2010-12-22 16 views
0

啓動的進程,我登錄我的電腦與用戶podosta「新的環境變量添加到由ProcessStartInfo.LoadUserProfile

這是工作流程的精細

ProcessStartInfo p = new ProcessStartInfo("c:\myapp.exe"); 
p.UserName = "myuser"; 
p.Domain = "mydomain"; 
p.Password = SecureString; 
p.UseShellExecute = false; 
p.LoadUserProfile = true; 
Process.Start(p); 

環境變量是用戶爲myuser'
前的環境變量:%USERPROFILE%點「myuser的」

這是我的個人資料不是工作

ProcessStartInfo p = new ProcessStartInfo("c:\myapp.exe"); 
p.UserName = "myuser"; 
p.Domain = "mydomain"; 
p.Password = SecureString; 
p.UseShellExecute = false; 
p.LoadUserProfile = true; 
p.EnvironmentVariables.Add("MY_NEW_VARIABLE", "SOME_TEXT"); 
Process.Start(p); 

過程的環境變量是我的「podosta」
前設置環境變量:%USERPROFILE%點,我的資料「podosta」 順便說一句,%MY_NEW_VARIABLE%創建

爲什麼會這樣?
我需要用RunAs啓動一個應用程序,擁有runned用戶的環境並向該進程添加一些額外的環境變量。

感謝

+0

無法訪問,因爲它不存在或無法訪問,因爲它有錯誤的值?啓動cmd.exe來解決問題。 – 2010-12-22 17:29:45

+0

我編輯了我的問題。你是對的,應用程序可以訪問env變量但有錯誤的值。 – podosta 2010-12-23 09:16:40

回答

0

你看到上MSDN基本上記錄了CreateProcessWithLogon Win32函數在後臺啓動一個過程,不同的用戶工作時的行爲(使用System.Diagnostics.Process):

一指向新進程的環境塊的指針。如果此 參數爲NULL,則新進程使用從 創建的環境,該環境由lpUsername指定的用戶的配置文件創建。

因此,一旦您指定新工藝單一個環境變量,你需要指定他們。

現在的問題是ProcessStartInfo.EnvironmentVariables屬性。第一次(對於ProcessStartInfo的給定實例)訪問它時,它將自動填入當前用戶的完整環境(ref)。

走這條線,運行在用戶 「podosta」 的背景:

p.EnvironmentVariables.Add("MY_NEW_VARIABLE", "SOME_TEXT"); 

它會做兩件事情:

  1. 填補p.EnvironmentVariables與 「podosta」 的環境(包括「 USERPROFILE = ... podosta「)。
  2. 添加新變量「MY_NEW_VARIABLE = SOME_TEXT」。

然後將此組合集合傳遞給作爲「myuser」啓動的進程,因此它會得到「USERPROFILE」的「錯誤」(更好:意外)值。

如果你想確保你傳遞一個NULL環境塊底層Win32函數,來獲得在報價上面描述的行爲,你永遠不能「碰」的EnvironmentVariables財產 - 甚至沒有迭代和轉儲它記錄目的。

這也是不夠的做EnvironmentVariables.Clear()。這不會將內部字段設置爲null,而CreateProcessWithLogon函數只是傳遞給一個空的環境塊,而不是空的塊。

如果你不這樣做,你會得到各種有趣的行爲,例如當時的執行過程中會有一個價值USERPROFILE那就是啓動進程的用戶,等

你可以通過p/invoke調用CreateEnvironmentBlock來解決這個問題,根據需要添加你的環境變量,然後調用CreateProcessAsUser(也通過p/invoke),傳遞修改後的環境。這一切都不是一件容易的事情,特別是當你想要所有Process級別的輸出重定向等功能時。

ProcessStartInfo.EnvironmentVariables屬性的工作方式很不幸。