2008-08-28 109 views
3

我需要ShellExecute東西作爲另一個用戶,目前我開始一個幫助進程CreateProcessAsUser,調用ShellExecute,但這似乎太多的黑客(錯誤的父進程等)是否有更好的方法來做這個?CreateProcessAsUser vs ShellExecute

@PabloG:ImpersonateLoggedOnUser不起作用:

 
HANDLE hTok; 
VERIFY(LogonUser("otheruser",0,"password",LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT,&hTok)); 
VERIFY(ImpersonateLoggedOnUser(hTok)); 
ShellExecute(0,0,"calc.exe",0,0,SW_SHOW); 
RevertToSelf(); 
CloseHandle(hTok); 

將剛開始計算作爲登錄的用戶,而不是 「otheruser」

@ 1800信息:CreateProcess/CreateProcessAsUser是不一樣的ShellExecute ,如果在Vista上使用UAC,CreateProcess在您無法控制用戶正在執行的程序時是無用的(如果您給它帶有標記爲requireAdmin的清單的exe文件,則CreateProcess將返回錯誤)

@Brian R. Bondy:我已經知道這個信息(並且不要誤解我的意思,它是好東西),但它是脫離主題(恕我直言)我要求的是ShellExecuteAsUser,而不是作爲另一個用戶啓動進程,我已經知道如何做到這一點。

回答

0

你可以用給ShellExecute ImpersonateLoggedOnUser/RevertToSelf時

鏈接之間: ImpersonateLoggedOnUser:http://msdn.microsoft.com/en-us/library/aa378612(VS.85).aspx 了RevertToSelf:http://msdn.microsoft.com/en-us/library/aa379317.aspx

抱歉,無法與超級鏈接的URL 「()」

+0

我敢肯定,我試過這個,它沒有工作,因爲新進程產生的當前進程的令牌,而不是它的線程 – Anders 2009-02-16 02:05:44

+0

這可能工作,如果在一個進程的主線程完成,但它會如果在單獨的線程中完成,則不起作用,因爲ShellExecute使用主線程的標記/安全上下文。去搞清楚。現在...如果你的應用程序有多個線程,在主線程中進行模擬/還原可能會導致應用程序的其他部分中斷。 – 2012-12-31 04:17:43

0

你爲什麼不只是做CreateProcessAsUser指定你想運行的進程?

您可能也可以使用SHCreateProcessAsUserW。

+0

因爲我需要ShellExecute處理非可執行文件 – Anders 2009-02-16 02:06:32

9

該解決方案真的取決於您的需求,並且可能非常複雜(完全感謝Windows Vista)。這可能會超出您的需求,但這將有助於其他人通過搜索找到此頁面。

  1. 如果您不需要使用GUI運行過程中,如果你想爲已經登錄到會話
  2. 運行的用戶如果需要運行,你不需要海拔
  3. 具有圖形用戶界面,並且用戶進程可能或可能不會在
  4. 記錄如果你需要與海拔

運行過程關於1: 在Win dows Vista中存在一些稱爲會話0隔離的內容。所有服務都以會話0運行,並且在會話0中不應該有GUI。第一個登錄用戶登錄到會話1中。在先前版本的Windows(Vista之前)中,第一個登錄用戶也完全運行會話0.

您可以在同一會話中使用不同用戶名運行多個不同的進程。您可以找到有關會話0隔離here的優秀文檔。

由於我們正在處理選項1),因此不需要GUI。因此,您可以在會話0中啓動您的流程。

你需要一個類似下面的調用序列: LogonUser,ExpandEnvironmentStringsForUser,GetLogonSID,LoadUserProfile,CreateEnvironmentBlock,CreateProcessAsUser。此

示例代碼可以通過任何搜索引擎中找到,或通過Google code search

關於2:如果用戶要運行過程已經登錄,您可以簡單地使用: WTSEnumerateSessions和WTSQuerySessionInformation獲取會話ID,然後使用WTSQueryUserToken獲取用戶令牌。從那裏你可以在CreateProcessAsUser Win32 API中使用用戶令牌。

這是一個很好的方法,因爲您甚至不需要以用戶身份登錄,也不需要知道用戶的用戶名/密碼。我相信這隻能通過一個服務,儘管作爲本地系統帳戶運行。

您可以通過WTSGetActiveConsoleSessionId獲取當前會話。

關於3: 您將遵循與#1相同的步驟,但此外您還可以使用STARTUPINFO的lpDesktop字段。將其設置爲winsta0 \ Default。您還需要嘗試使用OpenDesktop Win32 API,如果失敗,您可以使用CreateDesktop。在使用工作站和桌面句柄之前,您應該在SE_WINDOW_OBJECT和GROUP_SECURITY_INFORMATION |上使用SetSecurityInfo。 DACL_SECURITY_INFORMATION。

如果有問題的用戶以後嘗試登錄,他將實際看到正在運行的進程。

對於4: 這可以爲好,但它需要你已經運行了一個提升的過程。作爲本地系統帳戶運行的服務確實以提升的方式運行。我也可以通過擁有我想要開始的authenticode簽名過程來實現它。你也要把這個過程必須有它的requestedExecutionLevel水平=「requireAdministrator」

其他說明相關的清單文件:

  • 您可以通過SetTokenInformation設置令牌的會話和TokenSessionId
  • 你不能更改已經運行的進程的會話ID。
  • 如果Vista不在等式中,這整個過程將會非常簡單。
1

如果你需要的ShellExecute語義可以喂以下:

C:\windwos\system32\cmd.exe /k" start <your_target_to_be_ShellExecuted>"CreateProcessAsUser和你做。