如何让服务启动另一个程序

来源:互联网 发布:如何评价刘备 知乎 编辑:程序博客网 时间:2024/06/06 01:21

用Windows服务来启动带UI界面的程序 很多同学使用服务来单纯的启动另一个程序(WinExe,ShellExe,CreateProcess)结果发现我们的程序没界面但有进程,那是为什么呢?服务启动UI程序不能直接CreateProcess(),否则因为service session,程序UI不能看见,所以 我们需要拿到当前explorer.exe的token,然后CreateProcessAsUser模拟当前用户启动进程这样就可以显示界面了


第一步,得到explorer.exe环境的tokenDWORD INTER_GetExplorerToken( PHANDLE phExplorerToken ){    DWORD       dwStatus = ERROR_FILE_NOT_FOUND;    BOOL        bRet = FALSE;       HANDLE      hProcess = NULL;       HANDLE      hProcessSnap = NULL ;       char        szExplorerPath[MAX_PATH] = { 0 };       char        FileName[MAX_PATH] = { 0 };       PROCESSENTRY32 pe32 = { 0 };     try      {           hProcessSnap = ::CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS , 0 );        if( hProcessSnap == INVALID_HANDLE_VALUE )             {               dwStatus = GetLastError();        }        else        {            pe32.dwSize = sizeof( PROCESSENTRY32 );            int bMore = ::Process32First(hProcessSnap, &pe32);            while( bMore )            {                if ( ::wcscmp(pe32.szExeFile, _T("explorer.exe")) == 0 )                {                     hProcess = ::OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID );                    if( OpenProcessToken(hProcess , TOKEN_ALL_ACCESS  , phExplorerToken) )                    {                        dwStatus = 0;                    }                    else                    {                        dwStatus = GetLastError();                    }                    break;                }                   bMore = ::Process32Next( hProcessSnap, &pe32 );            }        }    }    catch(...)    {    }         if( hProcess )    {        CloseHandle( hProcess );    }    if( hProcessSnap )    {        CloseHandle ( hProcessSnap );    }      return dwStatus;} 第二步,启动程序void RunProcess(CString szExeFile, CString szDirectory){    HANDLE hToken = NULL;    if( INTER_GetExplorerToken( &hToken ) == 0 )    {        PROCESS_INFORMATION pi = { 0 };        SECURITY_ATTRIBUTES sa = { 0 };        sa.nLength = sizeof( SECURITY_ATTRIBUTES );         STARTUPINFO si = { 0 };        si.dwFlags = STARTF_USESHOWWINDOW;        si.cb = sizeof( STARTUPINFO );        si.wShowWindow = SW_SHOW;        CreateProcessAsUser( hToken, szExeFile, NULL, &sa, &sa, FALSE, NORMAL_PRIORITY_CLASS| CREATE_NEW_CONSOLE, NULL, szDirectory, &si, &pi );    }}  最后,大家注意了我使用了CreateProcessAsUser 的 lpCurrentDirectory 参数,这个对希望使用配置文件(ini)来说很重要,如果不设置该参数那么所读取的配置的路径将会和你服务路径一样


原创粉丝点击