Dun*_*can 5 windows winapi visual-c++
好的,这基本上就是我想要做的.我有一个过程P1.此过程需要cl.exe在单独的进程中调用Visual Studio命令行编译器P2(显然).但是,正如使用Visual Studio命令行编译器的每个人都知道的那样,您不能简单地调用cl.exe并期望获得良好的体验.您必须首先运行批处理脚本%VSXXXCOMNTOOLS%\vsvars32.bat(XXXVisual Studio版本号在哪里).此脚本设置编译器使用的一些关键环境变量(例如用作包含路径的内容).使用批处理脚本,这非常容易:
call "%VS110COMNTOOLS%\vsvars32.bat"
...
cl Foo.cpp Bar.cpp ...
Run Code Online (Sandbox Code Playgroud)
因为只是从批处理脚本调用批处理文件在同一个进程中运行(因此添加的环境变量是持久的).在我意识到我需要更多的灵活性并决定将我的脚本移植到C++之前,这是我过去常常做的事情,到目前为止,C++运行得非常好.也就是说,直到我达到我需要实现实际编译的程度.
所以,这是我最终要解决的问题.我想出最好的办法是调用cmd.exe /c "%VS110COMNTOOLS%\vsvars32.bat"一个单独的进程P3使用CreateProcess,等待进程结束,然后提取该子进程修改后的环境变量.也就是说,P1创建P3并等待它完成.P1然后将P3环境变量设置为自己的环境变量.P1然后创建P2这些环境变量集.所以代码大致如下(减去所有错误检查):
...
CreateProcess(TEXT("cmd"), TEXT("/c \"%VS110COMNTOOLS%\vsvars32.bat\""), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
WaitForSingleObject(pi.hProcess, INFINITE);
/* Set current process environment using pi.hProcess */
CloseHandle(pi.hProcess);
...
CreateProcess(TEXT("cl"), TEXT("..."), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
Run Code Online (Sandbox Code Playgroud)
那将是首选的解决方案.我不完全确定这样的事情是否可行,但根据我的研究,似乎有一种方法可以在.NET中执行此操作,而ProcessExplorer似乎能够读取任意进程的环境,所以我会假设这样解决方案是可能的.我似乎无法找到任何能够从子进程获取环境变量的文档化函数.在MSDN上还有一个与此类似的旧讨论.其中一个答复提及设置到.任何人都知道那是什么意思?我似乎无法找到任何文件.Merge Environmentyes
如果事实证明这是不可能的,我想到的替代解决方案是(1)编写一个简单调用vsvars32.bat然后cl.exe使用输入参数调用的批处理脚本,(2)调用cmd而不是cl使用参数运行vsvars32.bat然后编译(类似于1,但更具可扩展性......但不确定是否可能),或者(3)将环境变量打印到文件中然后读取它们.如果可能的话,我宁愿不使用任何此类解决方案.
我也愿意接受其他建议.只要知道我需要做的99%已经完成,所以首选干净,非hacky解决方案.
执行此操作的简洁方法是运行vcvars32以设置所有环境变量,然后运行您的进程P1。
cmd /C vcvars32.bat && P1
Run Code Online (Sandbox Code Playgroud)
请注意,用户不必手动执行此操作。使用此目标创建快捷方式:
cmd /C ""C:\Some Path\vcvarsall.bat" && start /separate C:\SomeOtherPath\YourGui.exe"
Run Code Online (Sandbox Code Playgroud)
这将设置环境变量,然后启动您的 GUI 应用程序。start /separate一旦 GUI 应用程序启动,命令提示符就会停止。如果您还希望可以方便地从命令行运行,您可以将其全部放入批处理文件中。
如果由于某种原因您不想这样做,从批处理脚本获取环境变量的最简单方法是运行:
cmd /U /C vcvars32.bat && set
Run Code Online (Sandbox Code Playgroud)
这会将值以 Unicode 格式写入标准输出。您可以使用管道来检索值。这比尝试从另一个进程的内存中检索变量要简单得多。
注意:如果您想在命令提示符下测试它,您需要运行:
cmd /U /C "vcvars32.bat && set"
Run Code Online (Sandbox Code Playgroud)
引号确保set在子命令处理器中运行。