最近在使用C++做一个windows服务,服务作为监控狗来监督一些进程的运行情况。若有的进程崩溃了,监控会定时探索到,然后再将该进程启动起来。
这其中使用了CreateProcess启动进程,但是因为权限的问题不能调用成功。
后来又使用了CreateProcessAsUser接口启动进程,在使用该接口之前要进行一顿操作。
在网上找了一段代码,发现在win10 1803教育版能够正常启动进程;但是同样的代码在win10 1903专业版就不可以。
然后进行了调整,终于在1903版本可以正常启动进程了。
有遇到类似情况的小伙伴可以参考。

修改前的代码

// 启动进程
DWORD ProcessStartAsUser(char * pProcessPath, char * pCommandLine)
{DWORD dwProcessID = 0;  // 新进程的进程IDtry{BOOL bResult = FALSE;   // 返回值PROCESS_INFORMATION pi = { 0 }; // 新创建的进程相关信息STARTUPINFO si = { 0 }; // 新进程的主窗口特性DWORD dwSessionId = 0;  // 当前活动的会话IDDWORD dwWinlogon = 0;   // winlogon进程IDDWORD dwCreationFlags = -1; // 创建标识HANDLE hUserToken = NULL;HANDLE hUserTokenDup = NULL;HANDLE hPToken = NULL;HANDLE hProcess = NULL;// 获得当前活动的会话ID.dwSessionId = WTSGetActiveConsoleSessionId();// 创建进程快照PROCESSENTRY32 procEntry = { 0 };HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (hSnap == INVALID_HANDLE_VALUE){return 0;}// 遍历进程快照,轮流显示每个进程的信息procEntry.dwSize = sizeof(PROCESSENTRY32);bResult = Process32First(hSnap, &procEntry);if (FALSE == bResult){return 0;}do{if (strncmp(procEntry.szExeFile, "winlogon.exe", sizeof("winlogon.exe")) == 0){// 找到winlogon.exe进程对应的进程IDDWORD winlogonSessId = 0;if (ProcessIdToSessionId(procEntry.th32ProcessID, &winlogonSessId)&& winlogonSessId == dwSessionId){dwWinlogon = procEntry.th32ProcessID;break;}}} while (Process32Next(hSnap, &procEntry));// 通过会话ID得到令牌bResult = WTSQueryUserToken(dwSessionId, &hUserToken);if (FALSE == bResult){return 0;}dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;si.cb = sizeof(STARTUPINFO);si.lpDesktop = "winsta0\\default";TOKEN_PRIVILEGES tp = { 0 };LUID luid = { 0 };  // 系统权限hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, dwWinlogon);bResult = ::OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY| TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID| TOKEN_READ | TOKEN_WRITE, &hPToken);if (FALSE == bResult){return 0;}// 查看系统权限的特权值bResult = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);if (FALSE == bResult){return 0;}tp.PrivilegeCount = 1;tp.Privileges[0].Luid = luid;tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;// 创建一个新的访问令牌来复制一个已经存在的标记bResult = DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, NULL,SecurityIdentification, TokenPrimary, &hUserTokenDup);if (FALSE == bResult){return 0;}// 启用访问令牌的特权bResult = AdjustTokenPrivileges(hUserTokenDup, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL, NULL);if (FALSE == bResult || GetLastError() == ERROR_NOT_ALL_ASSIGNED){return 0;}// 创建环境信息LPVOID pEnv = NULL;if (CreateEnvironmentBlock(&pEnv, hUserTokenDup, TRUE)){dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;}else{pEnv = NULL;}// 通过winlogon创建一个进程bResult = CreateProcessAsUser(hUserTokenDup,   // 令牌pProcessPath,    // 程序全路径pCommandLine,    // 程序命令行(和前者二选一)NULL,            // 进程安全属性NULL,            // 线程安全属性FALSE,           // 句柄不可继承dwCreationFlags, // 创建标识pEnv,            // 环境信息NULL,            // 当前路径&si,             // 新进程的主窗口特性&pi              // 新创建的进程相关信息);if ((0 != GetLastError()) || (false == bResult)){}dwProcessID = pi.dwProcessId;// 释放句柄资源CloseHandle(hProcess);CloseHandle(hPToken);CloseHandle(hUserTokenDup);CloseHandle(hUserToken);}catch (...){}return dwProcessID;
}

修改后的:

// 启动进程
DWORD ProcessStartAsUser(char * pProcessPath, char * pCommandLine)
{DWORD dwProcessID = 0;  // 新进程的进程IDtry{BOOL bResult = FALSE;   // 返回值PROCESS_INFORMATION pi = { 0 }; // 新创建的进程相关信息STARTUPINFO si = { 0 }; // 新进程的主窗口特性DWORD dwWinlogon = 0;   // winlogon进程IDDWORD dwCreationFlags = -1; // 创建标识HANDLE hUserToken = NULL;HANDLE hUserTokenDup = NULL;HANDLE hPToken = NULL;HANDLE hProcess = NULL;// 创建进程快照PROCESSENTRY32 procEntry = { 0 };HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (hSnap == INVALID_HANDLE_VALUE){return 0;}// 遍历进程快照,轮流显示每个进程的信息procEntry.dwSize = sizeof(PROCESSENTRY32);bResult = Process32First(hSnap, &procEntry);if (FALSE == bResult){return 0;}do{if (strncmp(procEntry.szExeFile, "winlogon.exe", sizeof("winlogon.exe")) == 0){// 找到winlogon.exe进程对应的进程IDDWORD dwSessionId = 0;ProcessIdToSessionId(procEntry.th32ProcessID, &dwSessionId);dwWinlogon = procEntry.th32ProcessID;break;}} while (Process32Next(hSnap, &procEntry));dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;si.cb = sizeof(STARTUPINFO);si.lpDesktop = "winsta0\\default";TOKEN_PRIVILEGES tp = { 0 };LUID luid = { 0 };  // 系统权限hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwWinlogon);if (NULL == hProcess){return 0;}bResult = ::OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY| TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID| TOKEN_READ | TOKEN_WRITE, &hPToken);if (FALSE == bResult){return 0;}// 查看系统权限的特权值bResult = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);if (FALSE == bResult){return 0;}tp.PrivilegeCount = 1;tp.Privileges[0].Luid = luid;tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;// 创建一个新的访问令牌来复制一个已经存在的标记bResult = DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, NULL,SecurityIdentification, TokenPrimary, &hUserTokenDup);if (FALSE == bResult){return 0;}// 启用访问令牌的特权bResult = AdjustTokenPrivileges(hUserTokenDup, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL, NULL);if (FALSE == bResult || GetLastError() == ERROR_NOT_ALL_ASSIGNED){return 0;}// 创建环境信息LPVOID pEnv = NULL;if (CreateEnvironmentBlock(&pEnv, hUserTokenDup, TRUE)){dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;}else{pEnv = NULL;}// 通过winlogon创建一个进程bResult = CreateProcessAsUser(hUserTokenDup,   // 令牌pProcessPath,    // 程序全路径pCommandLine,    // 程序命令行(和前者二选一)NULL,            // 进程安全属性NULL,            // 线程安全属性FALSE,           // 句柄不可继承dwCreationFlags, // 创建标识pEnv,            // 环境信息NULL,            // 当前路径&si,             // 新进程的主窗口特性&pi              // 新创建的进程相关信息);if ((0 != GetLastError()) || (false == bResult)){}dwProcessID = pi.dwProcessId;// 释放句柄资源CloseHandle(hProcess);CloseHandle(hPToken);CloseHandle(hUserTokenDup);}catch (...){}return dwProcessID;
}

这其中的差别,小伙伴们自己对比

win10 1903 专业版 CreateProcessAsUser相关推荐

  1. p系统ndows10的功能更新1903,Win10 2019年四月版(Win10 1903)更新功能介绍和下载

    相信很多朋友已经很期待微软下一个Win10正式版2019年四月更新版,Win10 1903版也被称为Win10 19H1,临近四月,正式版发布月期临近,相信很多朋友已经跃跃欲试了,那么在即将发布的新版 ...

  2. 戴尔 服务器重装后蓝屏,dell inspiron 5490重新安装win10 1903专业工作站版系统后开机频繁蓝屏...

    [现象] 如题,新买的dell inspiron 5490电脑,i5-10210 CPU,办公需要重新安装win10 1903专业工作站系统,(全新的电脑,未修改磁盘分区)通过安装版安装完毕后(未安装 ...

  3. deepin win10字体_深度系统Win10 1903安装新字体的设置方法

    众所周知,在深度系统Win10专业版中都是自带字体的,使用Win10输入文字时才有文字出来,但Win10系统默认宋体.做设计的朋友需要用其他有文艺气息的字体,那么就要安装字体,下面跟随深度之家小编来看 ...

  4. linux重置win10开机密码,win10 1903怎么取消(设置)开机密码

    修改win10密码可以通过界面来操作,其实还有通过命令行来进行操作的方法. 如果您学会了命令行来操作,效率会更加高.windows系统是使用命令行比较少的系统,像linux系统,使用命令行是非常多的, ...

  5. win10 如何锁定计算机,Win10 1909 专业版怎么锁定计算机屏幕

    Win10 1909 专业版怎么锁定计算机屏幕?如果我们需要暂时离开计算机,但不想关机或者注销当前登录,那么为了防止未经授权的使用,我们可以将计算机锁定.在本文中,win10之家小编给大家分享如何自动 ...

  6. p系统ndows10的功能更新1903,Win10 1903到底有什么不同?Win10 1903更新内容汇总

    在2019年的四月,微软为Win10系统推送了19H1版本更新,也就是Win10 1903.作为一年两次的大版本更新,win10 1903有不少用户在关注,那么它有什么不同之处呢?到底更新了什么功能? ...

  7. 手把手教你自制U盘重装win10系统专业版(纯净版)+激活【图文教程】

    手把手教你自制U盘重装win10系统专业版(纯净版)+激活[图文教程] 一.前言 二.准备工作(重要文件备份+电脑驱动下载) 三.win10系统镜像文件下载+U盘系统制作 四.开始重装系统 五.系统装 ...

  8. Win10 1903过TP的双机调试

    了解内核知识已经有一段时间了,想双机调试一下XP,网上也找了不少资料.https://bbs.pediy.com/thread-248912.htm https://blog.csdn.net/kin ...

  9. 海康服务器系统装完重启转圈蓝屏,win10 1903系统重启后一直在转圈无法正常启动的解决方法...

    有不少用户升级到win10 1903系统之后,发现关机重启之后,一直在转圈无法正常启动,遇到这样的问题该怎么办呢,接下来给大家讲解一下win10 1903系统重启后一直在转圈无法正常启动的解决方法吧. ...

  10. win10系统dnf安装不上服务器失败,win10 1903系统dnf图表系统组建失败的修复方法

    今天小编分享的是win10 1903系统dnf图表系统组建失败的修复方法,很多DNF玩家发现自己电脑"图标系统组建失败"的弹窗而困扰,其实这一般出现这个问题就是驱动的问题,只要更新 ...

最新文章

  1. js中的new file_深受 Pandas 启发的 JavaScript 开源库 — Danfo.js 现已推出!
  2. vue 上传图片 input=file
  3. 安装wps导致 application/kset 上传文件类型报错解决办法
  4. UVA 557 Burger
  5. 如何造数据——分分钟变成造数据大师
  6. Anaconda3创建、删除虚拟环境(win10)
  7. 《Java语言程序设计》(基础篇原书第10版)第七章复习题答案
  8. Ani网页木马生成器
  9. True Launch Bar 4.2 注册码
  10. 机器之心的进化 / 理解 AI 驱动的软件 2.0 智能革命
  11. 企业级负载均衡LVS集群——DR模式下的(加权)轮询调度器、DR模式下的健康检测(ldirectord)
  12. Android添加自定义公共so库
  13. pythonweb项目微服务_python web微服务器端
  14. VMware(6):如何配置虚拟机与宿主机的端口映射
  15. 零基础入门学习python笔记-day1:程序开发谋定而后动
  16. 网易云音乐热评的规律,44万条数据告诉你
  17. 【Linux】Linux 开放端口
  18. 詹姆斯·高斯林-JAVA之父
  19. Autodesk Inventor Routed Systems: Harness Autodesk Inventor Routed Systems: Harness Lynda课程中文字幕
  20. RabbitMQ高级之如何保证消息可靠性?

热门文章

  1. Jsoup爬虫获取公司纳税识别号
  2. Excel单元格科学计数法转换和小数点取整
  3. matlab中证券组合的收益,【证券投资组合分析】基于MATLAB的证券投资组合分析_玛雅作文网...
  4. PS白底证件照换蓝底背景,头发边缘精细处理
  5. 左对齐杨辉三角python_什么是左的错误?
  6. 学位论文写作规范之论文选题、开题报告、毕业论文
  7. Rational Rose工具栏中没有参与者工具(小人图标)的解决方法
  8. js实现word生成书签_javascript下用ActiveXObject控件替换word书签,将内容导出到word后打印...
  9. 冯·诺依曼理论的要点
  10. pandas统计个数