[C++]以不同用户身份运行程序

来源:互联网 发布:根域名 cname www 编辑:程序博客网 时间:2024/05/22 09:04

以不同用户身份运行程序

一直想方便的处理CCProxy代理的帐号管理,所以梦想做一个比较好的管理工具。但一个最麻烦的问题就是帐号的更新,CCProxy有一个网页管理功能,可以加帐号,但加的帐号就是不可以立即更新。中午上网的时候发现CCProxy有一功能就是支持命令行的操作,如:
  CCProxy -reboot  重启软件
  CCProxy -reset   更新配置
  CCProxy -update  更新帐号
  
  试着改了AccInfo.ini中帐号信息,在DOS中运行CCProxy -update的确更新了账号,所以开始用PHP做管理工具,做到调用CCProxy -update时,用了PHP中的exec(),system()等函数一直没有效果,后又通过调用批处理文件来调用命令行参数都不行。 处理得正没耐心的时候,一气之下狂刷新PHP网页,电脑卡死,用进程管理器查看时发现打开了多个CCProxy进程,认真一看,除了一个CCProxy是用户进程外其它CCProxy全是system进程。认真一想有可能是运行用户身份不同所产生的结果。
  Apache服务调用的外部程序以system身份运行,自己双击运行的程序以用户身份运行。 如果CCProxy -update以用户身份运行是不是就可以了呢?本人在网络上找到了runas这个命令,的确可以指定以哪个用户运行,但是每次都要输密码,没有密码的帐号就要加上密码才可以用,“/savecred”这个参数可以用,只要输入一次密码就可以了,但在PHP中发现要以system的身份输入一次才行,根本没有机会输入。打算用C程序来处理这个问题。可是发现用WinExec(),ShellExecute(),CreateProcess()都不好处理这个问题,好在发现了CreateProcessAsUser()这个函数。把网络上的程序改了几处,编译后一试问题终于解决。
   以下为相关代码:
// Update.cpp : 定义控制台应用程序的入口点。

 

#include "stdafx.h"  
#include <windows.h>  
#include <tlhelp32.h>  
  
BOOL GetTokenByName(HANDLE &hToken,LPSTR lpName)  
{  
    if(!lpName)  
        return FALSE;  
      
    HANDLE         hProcessSnap = NULL;   
    BOOL           bRet      = FALSE;   
    PROCESSENTRY32 pe32      = {0};   
      
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);   
    if (hProcessSnap == INVALID_HANDLE_VALUE)   
        return (FALSE);   
      
    pe32.dwSize = sizeof(PROCESSENTRY32);   
      
    if (Process32First(hProcessSnap, &pe32))   
    {    
        do   
        {  
            if(!strcmp(_strupr(pe32.szExeFile),_strupr(lpName)))  
            {  
                HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,  
                    FALSE,pe32.th32ProcessID);  
                bRet = OpenProcessToken(hProcess,TOKEN_ALL_ACCESS,&hToken);  
                CloseHandle (hProcessSnap);   
                return (bRet);  
            }  
        }   
        while (Process32Next(hProcessSnap, &pe32));   
        bRet = TRUE;   
    }    
    else   
        bRet = FALSE;  
      
    CloseHandle (hProcessSnap);   
    return (bRet);  
}  
  
BOOL RunProcess(LPCSTR lpImage,LPSTR lpCommandLine)  
{  
    if(!lpImage)  
        return FALSE;  
      
    HANDLE hToken;  
    if(!GetTokenByName(hToken,"EXPLORER.EXE"))  
        return FALSE;  
      
    STARTUPINFO si;  
    PROCESS_INFORMATION pi;  
      
    ZeroMemory(&si, sizeof(STARTUPINFO));  
    si.cb= sizeof(STARTUPINFO);  
    si.lpDesktop = TEXT("winsta0\default");  
      
    BOOL bResult = CreateProcessAsUser(hToken,lpImage, lpCommandLine,NULL,NULL,  
        FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi);  
    CloseHandle(hToken);  
    if(bResult)  
    {  
        OutputDebugString("CreateProcessAsUser ok!
");  
        printf("CreateProcessAsUser ok!
");  
    }  
    else  
    {  
        OutputDebugString("CreateProcessAsUse* **lse!
");  
        printf("CreateProcessAsUse* **lse!
");  
    }  
    return bResult;  
}  
  
int _tmain(int argc, _TCHAR* argv[])  
{  
    RunProcess("CCProxy.exe"," -update");  
    return 0;  
}