2017-09-15 20 views
0

我有一個Windows控制檯可執行文件(稱爲SetEnvX.exe),它設置了一個環境變量。它在內部調用Windows API中的SetEnvironmentVariable。該呼叫成功。可執行文件如何在父CMD或批處理上下文中設置環境變量?

在執行SetEnvX.exe的父CMD實例中,如果在SetEnvX.exe之後立即運行SET,則它創建的環境變量不存在。

如果我創建與線

SetEnvX.exe 
set 

一個TEST.CMD內TEST.CMD的SET命令的輸出也沒有顯示由SetEnvX.exe創建的環境變量。

程序如SetEnvX.exe如何創建環境變量,該環境變量存在於交互式CMD shell或批處理文件的執行範圍中?換句話說,我不想把環境變量放到全局持久的環境中。

+0

是否SetEnvx.exe創建一個新的環境,然後退出該環境,ala SETLOCAL ENDLOCAL? – Squashman

回答

1

每個進程在出生時都會繼承其父母的變量。你不能從孩子繼承變量。雖然在註冊表中有一個「全局持久化環境」,也就是而不是這個環境在隨機的CMD.EXE過程中。

請注意批處理文件由CMD.EXE執行,通常沒有自己的進程。

3

這是不可能的。無論何時調用SetEnvX.exe cmd.exe都會生成一個子進程,它從cmd.exe繼承了環境變量。

SetEnvX.exe在其環境中設置環境變量,但當它結束時,環境塊會消失。因此,父項cmd.exe不會從子項SetEnvX.exe獲取任何變量。

TL; DR:

子進程可以繼承父的環境變量,但父退出時,不能承受孩子的環境變量。

解決方法:

如果您編譯自己SetEnvX.exe,而不是設置環境變量,可以打印值,然後捕獲它輸入cmd.exe。例如:

for /f "delims=" %%k in ('SetEnvX.exe') do set VARIABLE=%%k 
+1

從技術上講,可能(有時)打開父進程並重寫它的環境塊,但這不是可取的和糟糕的設計。您需要像您的解決方法一樣的協作設計,將新變量寫入stdout。 – eryksun

+1

請注意,環境變量是Unicode和'for/f'使用控制檯的當前輸出代碼頁從管道讀取的逐行解碼。通常,您可能需要通過將控制檯設置爲代碼頁65001(UTF-8)並使SetEnvX.exe將UTF-8寫入標準輸出來進行合作。 – eryksun

相關問題