事情是这样的,公司的产品有个守护进程(windows Service)需要启动产品的主程序exe,让主程序它运行为管理员权限(因为主程序会加载一个插件,插件中有列出端口监听的功能,需要由端口查找到进程PID,由进程PID查找进程名或进程镜像路径,这些对于一些特殊进程例如svchost需要有管理员权限才能查到进程名和路径)。windows下的程序是不能在运行时获得管理员权限的,只能在创建进程的时候提升为管理员权限。如果是普通进程运行一个管理员权限程序,可以调用ShellExcute API。双击鼠标运行exe,可以在manifest文件中加入invoker admin,UAC 会提示用户以管理员权限运行。但是,特殊就在这里了!!守护进程是windows service,service不能调用ShellExcute来创建进程,如果这样,就会会失败。需要调用CreateProcessAsUser API来创建进程,这个API的普通用法,不能创建带有管理员权限的程序,需要一丁点特殊用法,如下:

 bool createProcessWithAdmin(const std::string & process_name, LPPROCESS_INFORMATION process)
{
HANDLE hToken = NULL;
HANDLE hTokenDup = NULL; if (process_name.empty()) {
return false;
} if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))
{
return false;
} if (!DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityAnonymous, TokenPrimary, &hTokenDup))
{
CloseHandle(hToken);
return false;
} STARTUPINFO si;
LPVOID pEnv = NULL;
DWORD dwSessionId = WTSGetActiveConsoleSessionId(); ZeroMemory(&si, sizeof(STARTUPINFO)); if (!SetTokenInformation(hTokenDup, TokenSessionId, &dwSessionId, sizeof(DWORD)))
{
CloseHandle(hToken);
CloseHandle(hTokenDup);
return false;
} si.cb = sizeof(STARTUPINFO);
si.lpDesktop = "WinSta0\\Default";
si.wShowWindow = SW_SHOW;
si.dwFlags = STARTF_USESHOWWINDOW; if (!CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE))
{
CloseHandle(hToken);
CloseHandle(hTokenDup);
return false;
} if (!CreateProcessAsUser(hTokenDup, process_name.c_str(), NULL, NULL, NULL, FALSE,
NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
pEnv, NULL, &si, process))
{
CloseHandle(hToken);
CloseHandle(hTokenDup);
return false;
} if (pEnv)
{
DestroyEnvironmentBlock(pEnv);
} CloseHandle(hToken);
CloseHandle(hTokenDup);
return true;
}

用法:

 PROCESS_INFORMATION pi;
createProcessWithAdmin("D:/absolute-path-exe", &pi);

用以上的代码就能用windows服务进程创建带有管理员权限的主GUI程序了。

另外windows service推荐用Qt的解决方案,编写windows service更简单了: https://github.com/qtproject/qt-solutions

references:

http://stackoverflow.com/questions/6418791/requesting-administrator-privileges-at-run-time

http://blog.csdn.net/woshinia/article/details/7850295

http://stackoverflow.com/questions/6261427/how-to-run-a-process-as-an-administrator-from-win32-c

http://blog.csdn.net/breeze_vickie/article/details/4334257

https://stackoverflow.com/questions/267838/how-can-a-windows-service-execute-a-gui-application

windows Service启动带有管理员权限的GUI进程的更多相关文章

  1. Windows 无法启动MongoDB服务 错误1067:进程意外终止

    1:Windows 无法启动MongoDB服务 错误1067:进程意外终止 2:解决方法: 进入MongoDB安装目录\data\将此文件夹下的mongod.lock删除(网友提供解决方案,实验之后貌 ...

  2. [Windows]VS2010如何以管理员权限启动?(转)

    在某些项目进行开发的时候,需要提升应用程序本身的权限,这个是很容易的.但是如何让VS2010启动的时候就已管理员权限运行程序呢?为这个问题苦恼了好久,终于找到了办法. 找到VS2010的快捷方式:右击 ...

  3. WIN8,开机启动 需要管理员权限的程序

    1. 用WPF开发,需要管理员权限并开机启动,以写注册表的方式实现.仅写注册表只能启动一般权限的程序. 2. 考虑这样实现: 程序以一般权限启动,启动以后申请管理员权限. 实现: App类中重写OnS ...

  4. window 10 删除带有管理员权限的Oracle文件夹

    因为文件已经被删除就不附图解释了 因为文件安装的方式错误,所以本是按照正常步骤卸载Oracle,前面的禁用Orace服务与删除Oracle注册表都没有出错,但到最后一步---------Oracle文 ...

  5. Windows Service 访问远程共享权限设置

    最近为实现共享目录之间的文件同步,开发了一个Windows Service. 考虑到在拷贝过程中,如果网络忽然抽风访问不了,导致文件拷贝不完整的情况,果断抛弃.Net 自带的 COPY 方法,而使用D ...

  6. Windows 8提升普通管理员权限为超级管理员权限以及激活超级管理员Administrator

    在Windows 8下运行某些操作时(比如删除一些文件或者更改某些系统设置时)系统会提示我们权限不够.须要Administrator账户的权限. 相信很多其它的使用者都会觉得自己当前使用的账户已经是系 ...

  7. windows Service 之调试过程(附加到进程里调试,而且启动时间不能超过30秒)

    最近第一次用C#写了一个windows service ,其实实现的内容比较简单.就是启动remoting 连接,但是调试相对初次写windws service 的我来说,比较烦.没有经验,而且没办法 ...

  8. MySQL的安装(比较详细的安装步骤,包括客户端和服务端的安装,还有环境变量的配置以及使用Windows service启动MySQL)

    1.MySQL官网下载操作系统对应的MySQL安装包,解压之后就可以直接使用(免安装). MySQL安装包,一种是MySQL Enterprise Edition (commercial)企业版,还有 ...

  9. 使用程序控制windows service启动/停止

    1.首先加入引用: using System.ServiceProcess; 2.控制启动服务: public void Start() { var timeout = TimeSpan.FromSe ...

随机推荐

  1. Swift:宏定义

    一.简述 swift中并没有加入宏系统,C语言使用#define定义的基本常量在导入Swift时被Swift编译自动转为Swfit语言的全局变量.但复杂的宏定义不能被Swift转换.Swift中类似宏 ...

  2. 【转】QT 串口QSerialPort + 解决接收数据不完整问题

    类:QSerialPort 例程:Examples\Qt-5.9.1\serialport\terminal,该例子完美展示了qt串口收发过程,直接在这上面修改就可以得到自己的串口软件.核心方法 // ...

  3. iOS开发-Block回调

    关于Block之前有一篇文章已经写过一篇文章Object-C-代码块Block回顾,不过写的比较浅显,不能体现出Block在实际开发中的重要性,关于Block的基础知识,可以参考之前的博客.在实际开发 ...

  4. Linux扩展文件分区

    **************操作之前请看章节6,看系统是否支持LVM分区管理方式*************** 1:新增磁盘 插入新的磁盘,比如物理机可以直接在卡槽插入,虚拟机可以在控制台添加磁盘或者 ...

  5. BigDecimal 的幂次方运算

    public static void main(String[] args){ BigDecimal bg1, bg2; bg1 = new BigDecimal("200000.45&qu ...

  6. iis 防火墙防止恶意ip攻击

    今天发现服务器里,一个IP不停的占用我的网络资源,然后在防火墙里配置,将其禁止访问,网络很快降了下来. 这个恶意的IP是 115.171.60.62

  7. mysql游标的使用 No data - zero rows fetched, selected

    转自:http://blog.sina.com.cn/s/blog_544c72960101bvl3.html 这是一个游标的使用例子. 但是其中有几点需要注意,就是为什么要加入 declare CO ...

  8. Windows 之 可以Ping通服务器但无法使用服务器连接的共享打印机

    故障现象:一个公司内部局域网中,一台电脑可以Ping通服务器,但无法使用服务器连接的共享打印机. 故障分析与排除:根据故障现象分析,由于客户端可以Ping通服务器,说明网络连接正常,故障可能是由客户端 ...

  9. [置顶] 在Visual Studio 2008上调试C语言程序

    C语言的地位和重要性就不用说了,但,很多人学习C语言,还在使用Visual C++ 6.0,甚至还有人使用Turbo C,很无语,只说一句吧:“OUT了". 让我们体验一下华丽的Visual ...

  10. 微软BI 之SSAS 系列 - 在SQL Server 2012 中开发 Analysis Services Multidimensional Project

    SQL Server 2012 中提供了开发 SSAS 项目的两种模型,一种是新增加的 Tabular Model 表格模型,另一种就是原始的 Multidimensional Model 多维模型. ...