2010-01-18 66 views
22

我想從.NET服務的不同用戶下啓動.NET應用程序。這個想法是在Windows中創建一個沙盒主機應用程序。在該服務中,我以編程方式在Windows中創建用戶,爲該用戶創建一個文件夾,並將主機.exe從服務器下載到該文件夾​​中。然後我使用System.Diagnostics.Process運行主機.exe。這裏是StartInfo的爲過程:權限問題從.NET服務作爲一個不同的用戶啓動.NET應用程序?

_process = new Process 
{ 
    StartInfo = 
    { 
     Arguments = " -debug", 
     FileName = instanceDirectory + "host.exe", 
     WorkingDirectory = instanceDirectory, 
     UseShellExecute = false, 
     RedirectStandardError = true, 
     RedirectStandardOutput = true, 
     RedirectStandardInput = true, 
     UserName = Helpers.GetUserNameForInstance(_hostid), 
     Password = _hostpass, 
     Domain = "" 
    }, 
    EnableRaisingEvents = true 
}; 

當我運行服務作爲一種服務,過程與-1073741502錯誤代碼瞬間崩潰。但是當我以Windows服務中指定的相同用戶的身份運行服務,但在控制檯中交互式地運行時,一切正常。只有在服務作爲服務運行時纔會發生這種情況,而不是直接在控制檯中運行。

任何幫助將不勝感激。這一直是現在很長一段時間頭疼,這也是不得已而爲之:(

+0

您是否測試過在控制檯應用程序中運行的相同代碼? – 2010-01-18 00:50:06

+2

是的,一切正常運行在獨立模式..它只有作爲服務運行的問題。 – 2010-01-18 01:07:16

+1

嗨,正如你所說,這聽起來像是一個權限問題,因爲它不是服務時運行。此鏈接可能有所幫助: http://asprosys.blogspot.com/2009/03/perils-and-pitfalls-of-launching.html – keyboardP 2010-01-18 02:20:30

回答

1

0xc0000142(-1073741502)的STATUS_DLL_INIT_FAILED:

動態鏈接庫[名稱]的初始化失敗的進程異常終止

由於TenaciousImpy給出的網站指出,您需要將帳戶權限授予窗口站和桌面。但是,如果程序是交互式的,你還需要設置進程令牌的會話ID。

14

好像使用new Process()用戶名和密碼,並在服務模式從MSDN「不計算」 :)

報價:

您可以更改指定的參數 StartInfo屬性增加 到您調用該過程的開始 方法的時間。在啓動 過程後,更改StartInfo 值不會影響或重新啓動 關聯過程。如果調用 開始(的ProcessStartInfo)方法 的的ProcessStartInfo .. ::。用戶名和 的ProcessStartInfo .. ::。密碼 屬性設置,非託管 CreateProcessWithLogonW功能 調用,啓動過程中 新即使CreateNoWindow屬性值爲true或 WindowStyle屬性值爲Hidden。

此外,在看CreateProcessWithLogonW文檔:

lpStartupInfo [IN]

指向一個STARTUPINFO結構。應用程序必須將指定用戶 帳戶的 權限添加到指定窗口 工作站和桌面,即使對於 WinSta0 \ Default。

如果lpDesktop成員爲NULL或空字符串,則新進程 將繼承其父進程的桌面和窗口 工作站。 應用程序必須將 指定用戶帳戶的權限添加到 繼承的窗口站和桌面。

.NET StartupInfo中沒有lpDesktop,另一方面,SERVICE用戶沒有桌面,這可能會導致您的問題。

長話短說,儘量設置LoadUserProfiletrue從註冊表中讀取用戶的信息,或者你需要設置工作目錄等

爲了進一步調查,你應該檢查你的環境,並可能記錄使用FileMon訪問哪些文件。

5

我會嘗試在新創建的用戶的模擬上下文下創建流程,如下所示。

[DllImport("advapi32.DLL", SetLastError = true)] 
public static extern int LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken); 

[DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
public extern static bool CloseHandle(IntPtr handle); 

[DllImport("advapi32.DLL")] 
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken); 

static void Main() 
{    
    IntPtr admin_token = new IntPtr(); 
    WindowsIdentity wid_admin = null; 
    WindowsImpersonationContext wic = null; 

    LogonUser("username", "domain", "password", 9, 3, out admin_token); 
    wid_admin = new WindowsIdentity(admin_token); 
    wic = wid_admin.Impersonate(); 

    _process = new Process 
    { 
     StartInfo = 
     { 
      Arguments = " -debug", 
      FileName = instanceDirectory + "host.exe", 
      WorkingDirectory = instanceDirectory, 
      UseShellExecute = false, 
      RedirectStandardError = true, 
      RedirectStandardOutput = true, 
      RedirectStandardInput = true, 
      UserName = Helpers.GetUserNameForInstance(_hostid), 
      Password = _hostpass, 
      Domain = "" 
     }, 
     EnableRaisingEvents = true 
    }; 

    if (wic != null) wic.Undo(); 
    CloseHandle(admin_token); 
} 
+0

我試過了,它似乎沒有幫助。回顧一下Gyury引用的內容,似乎用戶需要被授予使用該服務所屬的窗口站點和桌面的權限。 – jamessan 2012-12-20 13:11:50

相關問題