首页 > 代码库 > windows Service启动带有管理员权限的进程

windows Service启动带有管理员权限的进程

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

 

 1 /**
 2  *  创建进程
 3  *  @param process_name 进程名
 4  *  @param process 进程信息
 5  *  @param is_run_with_create 创建时是否启动
 6  *  @return 0 成功
 7  */
 8 int create_process(char* process_name, LPPROCESS_INFORMATION process,int is_run_with_create)
 9 {
10   
11     
12 
13     HANDLE hToken = NULL;  
14     HANDLE hTokenDup = NULL;
15     int errRet = -1;
16     
17     if (STRING_IS_EMPTY(process_name)) {
18         return -1;
19     }
20 
21         
22         do   
23         {  
24             if(OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hToken))  
25             {  
26                 if(DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS,NULL, SecurityIdentification, TokenPrimary, &hTokenDup))  
27                 {  
28                     STARTUPINFO si;  
29                    
30 
31                     LPVOID pEnv = NULL; 
32                     DWORD dwSessionId = WTSGetActiveConsoleSessionId();  
33                     
34                     ZeroMemory(&si,sizeof(STARTUPINFO));  
35                    
36                 
37                     
38                     if(!SetTokenInformation(hTokenDup,TokenSessionId,&dwSessionId,sizeof(DWORD)))  
39                     {  
40                        
41                         break;  
42                     }  
43       
44                    
45                     si.cb = sizeof(STARTUPINFO);  
46                     si.lpDesktop = "WinSta0\\Default";  
47                     si.wShowWindow = SW_SHOW;  
48                     si.dwFlags     =   STARTF_USESHOWWINDOW /*|STARTF_USESTDHANDLES*/;  
49       
50                    
51                     if(!CreateEnvironmentBlock(&pEnv,hTokenDup,FALSE))  
52                     {  
53                        
54                         break;  
55                     }  
56       
57                     if(!CreateProcessAsUser(hTokenDup,process_name,NULL,NULL,NULL,FALSE,
58                         NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
59                         pEnv,NULL,&si,process))  
60                     {  
61                 
62                         break;  
63                     }  
64       
65                     if(pEnv)  
66                     {  
67                         DestroyEnvironmentBlock(pEnv);  
68                     }  
69                 }  
70                 else  
71                 {  
72                     break;  
73                 }  
74       
75                       
76             }  
77             else  
78             {  
79                
80                 errRet = 0; 
81                 break;  
82             }  
83         }while(0);  
84       
85         if(hTokenDup != NULL && hTokenDup != INVALID_HANDLE_VALUE)  
86             CloseHandle(hTokenDup);  
87         if(hToken != NULL && hToken != INVALID_HANDLE_VALUE)  
88             CloseHandle(hToken);  
89 
90 
91     return errRet;
92 }

 

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

 

 

 

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

 

windows Service启动带有管理员权限的进程