在服务程序中用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);请大神们指教
不是外部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);请大神们指教
解决方案 »
- CListCtrl不触发OnBeginrdrag事件
- 打开多个文本文件,显示到客户区
- 关于数据库查询的问题?
- 急~~
- vc2005中如何将*tchar 转换为 *char?
- 如何在对话框中嵌入网页?
- 在知道用户名和密码的情况下如何用程序访问局域网上有密码保护的共享文件夹
- 在SDK环境下调用ATL组件中的CryptoAPI可以正常运行,为什么在ASP中调用组件就出现问题呢?
- 错误 Microsoft C++ 异常: 内存位置 0x0019f6c8 处的 std::bad_alloc。
- 我想把一个工程的CScrollView 给改成 CEditView 应该如何做啊!!!
- post登录带验证码网站,如何获取验证码呢?
- 为什么关闭对话框后主窗口也会自动关闭,求dalao帮助?
请检查每个函数调用的返回值。
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.exeIn addition to setting this registry key, the service application must be ed 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.
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,说需要提升权限。。