在服务中用CreateProcessAsUser运行的外部EXE不能创建快捷方式

wuyouba9345 2017-04-19 09:59:23
在服务程序中用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);

请大神们指教
...全文
943 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhuyongcun 2017-10-20
  • 打赏
  • 举报
回复
最近我也在研究这个问题,服务更改sessionID可以启动有界面程序,但是创建快捷方式失败,和UAC权限无关
zgl7903 2017-04-22
  • 打赏
  • 举报
回复
试试使用 IShellLink 接口 创建快捷方式
wuyouba9345 2017-04-21
  • 打赏
  • 举报
回复
我改进了代码,
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,说需要提升权限。。
赵4老师 2017-04-21
  • 打赏
  • 举报
回复
用调试器(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.
oyljerry 2017-04-21
  • 打赏
  • 举报
回复
这个一般写在当前用户目录下,你的程序启动后,看看用户权限等是否正确,然后就是看一下写失败的时候返回的错误信息
赵4老师 2017-04-20
  • 打赏
  • 举报
回复
搜“Session0穿透”
赵4老师 2017-04-20
  • 打赏
  • 举报
回复
关闭杀毒软件、……
赵4老师 2017-04-20
  • 打赏
  • 举报
回复
引用 2 楼 wuyouba9345 的回复:
[quote=引用 1 楼 zhao4zhong1 的回复:] 搜“Session0穿透”
是在XP上都没成功,更别说win7了[/quote] 请检查每个函数调用的返回值。
wuyouba9345 2017-04-20
  • 打赏
  • 举报
回复
引用 1 楼 zhao4zhong1 的回复:
搜“Session0穿透”
xp下也有Session隔离?
wuyouba9345 2017-04-20
  • 打赏
  • 举报
回复
引用 1 楼 zhao4zhong1 的回复:
搜“Session0穿透”
是在XP上都没成功,更别说win7了

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧