当前位置: 七九推 > 互联网>腾讯>微信 > 系统服务用CreateProcessAsUser实现创建界面进程

系统服务用CreateProcessAsUser实现创建界面进程

2022年06月23日 微信 我要评论
一、需求        有一个带界面的GUI程序需要一直保持运行状态,但是操作系统有时会自动更新重启,虽然已经通过注册表的方式设置为自启动,但是必须登录操纵系

一、需求

       有一个带界面的GUI程序需要一直保持运行状态,但是操作系统有时会自动更新重启,虽然已经通过注册表的方式设置为自启动,但是必须登录操纵系统才能启动,所以需要一种不登录也能让该程序运行的实现方法。

       又因为这个程序是GUI程序,无法直接注册为系统服务(系统服务可以开机后不登录也在后台运行),所以考虑通过把一个控制台程序注册成系统服务,然后通过这个控制台程序调用GUI程序。下面代码是控制台程序调用GUI程序的关键逻辑。

       经测试,在Win10 和 windows server 2016 都正常启用GUI程序。但是在云服务器有点特殊,使用下面代码调用GUI程序后,分配到的Session ID (会话ID,每个用户登录操作系统后都会被分配一个会话ID) 是1,但是我们用云平台给的用户名密码远程登录操作系统后的Session ID是2,这就导致我们看不到GUI程序的界面。在本地的虚拟机和实体机则正常。

 

2、代码



bool CStartUIProcess::Start(const string& strAppPath)
{
	HANDLE hToken = NULL;
	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))
	{
		return false;
	}

	HANDLE hTokenDup = NULL;
	bool bRet = DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityIdentification, TokenPrimary, &hTokenDup);
	if (!bRet || hTokenDup == NULL)
	{
		CloseHandle(hToken);
		return false;
	}

	DWORD dwSessionId = WTSGetActiveConsoleSessionId();
	//把服务hToken的SessionId替换成当前活动的Session(即替换到可与用户交互的winsta0下)
	if (!SetTokenInformation(hTokenDup, TokenSessionId, &dwSessionId, sizeof(DWORD)))
	{
		DWORD nErr = GetLastError();
		CloseHandle(hTokenDup);
		CloseHandle(hToken);
		return false;
	}

	STARTUPINFO si;
	ZeroMemory(&si, sizeof(STARTUPINFO));
	
	si.cb = sizeof(STARTUPINFO);
	si.lpDesktop = _T("WinSta0\\Default");
	si.wShowWindow = SW_SHOW;
	si.dwFlags = STARTF_USESHOWWINDOW /*|STARTF_USESTDHANDLES*/;

	//创建进程环境块
	LPVOID pEnv = NULL;
	bRet = CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE);
	if (!bRet)
	{
		CloseHandle(hTokenDup);
		CloseHandle(hToken);
		return false;
	}

	if (pEnv == NULL)
	{
		CloseHandle(hTokenDup);
		CloseHandle(hToken);
		return false;
	}

	//在活动的Session下创建进程
	PROCESS_INFORMATION processInfo;
	ZeroMemory(&processInfo, sizeof(PROCESS_INFORMATION));
	DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;

	if (!CreateProcessAsUser(hTokenDup, NULL, (char*)strAppPath.c_str(), NULL, NULL, FALSE, dwCreationFlag, pEnv, NULL, &si, &processInfo))
	{
		DWORD nRet = GetLastError();
		CloseHandle(hTokenDup);
		CloseHandle(hToken);
		return false;
	}

	DestroyEnvironmentBlock(pEnv);
	CloseHandle(hTokenDup);
	CloseHandle(hToken);

	return true;
}

 

(0)
打赏 微信扫一扫 微信扫一扫

相关文章:

  • 微信小程序开发工具基本介绍入门级(备忘)

    微信小程序开发工具基本介绍入门级(备忘)

    1、注册微信小程序开发者账号 登录微信公众平台或者复制链接https://mp.weixin.qq.com/ 第一步点击立即注册 第二步、选择小程序ÿ... [阅读全文]
  • Codeforces Round #658 (Div. 2) B. Sequential Nim

    Codeforces Round #658 (Div. 2) B. Sequential Nim

    B. Sequential Nim题目链接-B. Sequential Nim题目大意给 nnn 堆石子的数量,两人轮流从最左端的非空堆中取任意数量(>0... [阅读全文]
  • 扫描全能王如何取消自动扣费 关闭自动续费方法

    图片扫描全能王 for android v1.6.7 安卓手机版类型:商务办公大小:41.6mb语言:简体中文时间:2021-01-06扫描全能王会员服务该怎么关闭扣费服务呢?有很…

    2022年06月23日 腾讯
  • obsidian怎么设置链接?obsidian设置链接教程

    想要在obsidian中插入链接该怎么操作呢?插入链接作为obsidian最大的特色,喜欢用obsidian这款软件的小伙伴可不能错过,下面就和小编一起来看看吧。obsidian链…

    2022年06月23日 腾讯
  • 喜马拉雅如何把声音加到听单?

    我们有时候在使用喜马拉雅的时候,想要把声音加到听单,如何操作呢,感兴趣的朋友不要错过了。方法1、打开“喜马拉雅"app。2、进入主界面后点击中间的&ldquo…

    2022年06月23日 腾讯
  • 微信背景图应用到全部场景的操作方法

    微信背景图怎么应用到全部场景的呢?下面是小编介绍微信背景图应用到全部场景的操作方法过程,有需要的小伙伴一起来下文看看吧,希望可以帮助到大家!微信背景图应用到全部场景的操作方法1、首…

    2022年06月23日 腾讯

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2022  七九推 保留所有权利. 粤ICP备17035492号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com