Получить переменные среды дочернего процесса в VC ++
Хорошо здесьПо сути, то, что я пытаюсь сделать. У меня есть процессP1
, Этот процесс должен вызвать компилятор командной строки Visual Studiocl.exe
в отдельном процессеP2
(Очевидно). Однако, как известно всем, кто когда-либо использовал компилятор командной строки Visual Studio, вы не можете просто вызватьcl.exe
и ожидать хорошего опыта. Вместо этого вы должны сначала запустить пакетный скрипт%VSXXXCOMNTOOLS%\vsvars32.bat
(гдеXXX
это номер версии Visual Studio). Этот скрипт устанавливает несколько ключевых переменных среды, используемых компилятором (например, что использовать в качестве пути включения). Используя пакетный скрипт, это безумно легко сделать:
call "%VS110COMNTOOLS%\vsvars32.bat"
...
cl Foo.cpp Bar.cpp ...
поскольку простой вызов пакетного файла из пакетного сценария выполняется в том же процессе (и, следовательно, добавленные переменные среды являются постоянными). Это то, что я делал до того, как понял, что мне нужно больше гибкости, и решил портировать свой скрипт на 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);
Это было бы предпочтительным решением. Я не совсем уверен, возможно ли такое, но исходя из моих исследований, кажется, что есть способ сделать это в.СЕТЬ, а такжеProcessExplorer похоже, что он способен читать окружение произвольных процессов, поэтому я бы предположил, что такое решение возможно. Я просто могуКажется, что не найдено каких-либо документированных функций, которые могут получить переменные окружения от дочерних процессов. Там'такжестарый обсуждение, которое похоже на это наMSDN, В одном из ответов упоминается настройкаMerge Environment
вyes
, Кто-нибудь знает, что это значит? Я могу'Кажется, я не нашел никакой документации по этому вопросу.
Если оказывается, что это невозможно, альтернативные решения, о которых я думал, - это (1) написать пакетный скрипт, который просто вызываетvsvars32.bat
а затем вызываетcl.exe
с входными аргументами, (2) вызываяcmd
вместоcl
с аргументами для запускаvsvars32.bat
а затем скомпилировать (аналогично1
, но более расширяемый ... но не уверен, если это возможно), или (3) распечатать переменные окружения в файл и затем прочитать их в. I 'Я бы предпочел не использовать ни одно из таких решений, если это возможно.
Я также открыт для альтернативных предложений. Просто знайте, что 99% того, что мне нужно сделать, уже сделано, поэтому предпочтительны чистые, не взломанные решения.