在服務程式中用CreateProcessAsUser運行的外部EXE不能創建桌面快捷方式和開始選單欄快捷方式,其他目錄的檔案讀寫沒問題,與桌面互動也沒問題。
不是外部EXE的問題,直接手動運行外部EXE沒出現這些問題。
以下為代碼:
HANDLE hToken;
//創建行程快照
PROCESSENTRY32 pe32 = { 0 };
pe32.dwSize = sizeof(pe32);
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (hSnapShot!=0 && hSnapShot!=INVALID_HANDLE_VALUE)
{
BOOL bRet = Process32FirstW(hSnapShot,&pe32);
while(bRet)
{
if (_tcsicmp(pe32.szExeFile,L"Explorer.EXE") == 0)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,false,pe32.th32ProcessID);
if (hProcess!=NULL)
{
BOOL flag = OpenProcessToken(hProcess,TOKEN_ALL_ACCESS,&hToken);
CloseHandle(hProcess);
}
break;
}
bRet = Process32Next(hSnapShot,&pe32);
}
CloseHandle(hSnapShot);
}
STARTUPINFO si ={sizeof(si)};
PROCESS_INFORMATION pi;
//TCHAR FileName[256] 外部EXE的完整路徑
BOOL bSuccess = CreateProcessAsUser(hToken,FileName,NULL,NULL,NULL,FALSE,NULL,NULL,NULL,&si,&pi);
請大神們指教
uj5u.com熱心網友回復:
搜“Session0穿透”uj5u.com熱心網友回復:
是在XP上都沒成功,更別說win7了
uj5u.com熱心網友回復:
xp下也有Session隔離?
uj5u.com熱心網友回復:
請檢查每個函式呼叫的回傳值。
uj5u.com熱心網友回復:
關閉殺毒軟體、……uj5u.com熱心網友回復:
這個一般寫在當前用戶目錄下,你的程式啟動后,看看用戶權限等是否正確,然后就是看一下寫失敗的時候回傳的錯誤資訊uj5u.com熱心網友回復:
用除錯器(OD,WINDBG等)除錯服務程式To debug the initialization code of a service application, the debugger must be attached when the service is started. This is accomplished by creating a registry key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ProgramName
The ProgramName is the image file for the service application you are debugging. Do not specify a path. For example, the ProgramName might look like MyService.exe.
Under this key create a string data value called Debugger. The value of this string should be set to the full path of the debugger that will be used. For example,
c:\Debuggers\windbg.exe
In addition to setting this registry key, the service application must be marked as "interactive". This allows your service to interact with the desktop, and allows the debugger window to appear on your desktop.
This again requires modifying a registry key: you must bitwise-or the type entry for your service with 0x100 (this is the value for SERVICE_INTERACTIVE_PROCESS according to Winnt.h). The exact location and name of this registry entry varies. For example:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MyServiceKey
Finally, you need to adjust the service application timeout. Otherwise, the service application will kill the debugger within 20 seconds after starting. Adjusting the timeout involves setting an entry in the following registry key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
Under this key, create a DWORD data value called ServicesPipeTimeout. Set this entry to the amount of time in milliseconds that you want the service to wait before timing out. For example, 60,000 is one minute, while 86,400,000 is 24 hours.
設定ServicesPipeTimeout后需要重啟系統才生效
Now, when the service is started, the debugger will also start. When the debugger starts, it will stop at the initial process breakpoint, before the service has begun running. This allows you to set breakpoints or otherwise configure your debugging session to let you monitor the startup of your service. Another option is to place calls to the DebugBreak function in your service from the point at which you would like to break into the debugger. (For more information, see DebugBreak in the Platform SDK documentation.)
If your service is running with other services in a Service Host Process, you may need to isolate the service into its own Service Host Process.
uj5u.com熱心網友回復:
我改進了代碼,BOOL bSuccess = FALSE;
STARTUPINFO si = {0};
// 行程資訊
PROCESS_INFORMATION pi = {0};
si.cb = sizeof(si);
// 獲得當前Session ID
DWORD dwSessionID = WTSGetActiveConsoleSessionId();
HANDLE hToken = NULL;
// 獲得當前Session的用戶令牌
if (WTSQueryUserToken(dwSessionID, &hToken) == FALSE)
{
goto Cleanup;
}
// 復制令牌
HANDLE hDuplicatedToken = NULL;
if (DuplicateTokenEx(hToken,
MAXIMUM_ALLOWED, NULL,
SecurityIdentification, TokenPrimary,
&hDuplicatedToken) == FALSE)
{
goto Cleanup;
}
// 創建用戶Session環境
LPVOID lpEnvironment = NULL;
if (CreateEnvironmentBlock(&lpEnvironment,
hDuplicatedToken, FALSE) == FALSE)
{
goto Cleanup;
}
// 在復制的用戶Session下執行應用程式,創建行程。
// 通過這個行程,就可以顯示各種復雜的用戶界面了
if (CreateProcessAsUser(hDuplicatedToken,
exeFilePath, NULL, NULL, NULL, FALSE,
NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
lpEnvironment, NULL, &si, &pi) == FALSE)
{
/*DWORD errCode = GetLastError();
char msg[100] = {0};
sprintf(msg,"CreateProcessAsUser Error: %d",errCode);
OutputDebugStringA(msg);*/
goto Cleanup;
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
bSuccess = TRUE;
// 清理作業
Cleanup:
if (hToken != NULL)
CloseHandle(hToken);
if (hDuplicatedToken != NULL)
CloseHandle(hDuplicatedToken);
if (lpEnvironment != NULL)
DestroyEnvironmentBlock(lpEnvironment);
但這個代碼下,其他都是正常的,就是在開啟了UAC的電腦上不能運行行程,GetLastError是740,說需要提升權限。。
uj5u.com熱心網友回復:
試試使用 IShellLink 介面 創建快捷方式uj5u.com熱心網友回復:
最近我也在研究這個問題,服務更改sessionID可以啟動有界面程式,但是創建快捷方式失敗,和UAC權限無關轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/82901.html
標籤:進程/線程/DLL
