项目中的实际问题:需要用一个服务程序来启动并监控另一个程序,而该程序中使用了JavaScript,并且访问百度的地图API,启动该程序后,发现地图总是无法加载, 这个问题纠结了我和外部程序的开发者三天时间了,一直没有头绪,今天写了一个最简单的百度地图的加载代码,结果弹出如下提示框但是当我自己按照普通的方式直接运行这个外部程序的时候,却能够正常加载,因此推断问题可能出现在启动权限上。userenv.h 检查代码,我的实现代码如下:DWORD INTER_GetExplorerToken(OUT PHANDLE phExplorerToken ){DWORD dwStatus = ERROR_FILE_NOT_FOUND ;BOOL bRet = FALSE ;HANDLE hProcess = NULL ;HANDLE hProcessSnap = NULL ;wchar_t szExplorerPath[MAX_PATH] = { 0 } ;wchar_t FileName[MAX_PATH] = { 0 } ;PROCESSENTRY32 pe32 = { 0 } ;GetWindowsDirectory( szExplorerPath , MAX_PATH ) ;StrCatW( szExplorerPath , L"\\Explorer.EXE" ) ;hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS , 0 ) ;if( hProcessSnap == INVALID_HANDLE_VALUE ){dwStatus = GetLastError() ;return 0;}pe32.dwSize = sizeof( PROCESSENTRY32 ) ;if( !Process32First( hProcessSnap, &pe32 )){dwStatus = GetLastError() ;return 0;}do {hProcess = OpenProcess(PROCESS_ALL_ACCESS ,FALSE ,pe32.th32ProcessID ) ;if( NULL != hProcess ){TCHAR szAppLocation[MAX_PATH] = _T("");DWORD dwRet = ::GetModuleFileNameEx( hProcess, NULL,szAppLocation, MAX_PATH );if ( 0 == dwRet ){::Process32Next( hProcessSnap, &pe32 );CloseHandle( hProcess );continue;}TCHAR szProcessName[MAX_PATH] = _T("");dwRet = ::GetLongPathName( szAppLocation, szProcessName,MAX_PATH );if ( 0 == dwRet ){::Process32Next( hProcessSnap, &pe32 );CloseHandle( hProcess );continue;}CString csProcessName = szProcessName;CString csExplorerPath = szExplorerPath;if ( 0 == csProcessName.CompareNoCase(csExplorerPath) ){HANDLE hToken ;if( OpenProcessToken( hProcess , TOKEN_DUPLICATE , &hToken )){HANDLE hNewToken = NULL;DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &hNewToken);* phExplorerToken = hNewToken ;dwStatus = 0 ;CloseHandle(hToken);}break ;}CloseHandle ( hProcess ) ;hProcess = NULL ;}} while( Process32Next( hProcessSnap, &pe32 )) ;return dwStatus ;}BOOL LaunchedSoftware(CString strFileName, CString csParam /* = EMPTY_STRING */){STARTUPINFO info;memset(&info,0,sizeof(info));info.cb=sizeof(info);//info.lpDesktop = _T("WinSta0\\Default");info.dwFlags |= STARTF_USESHOWWINDOW;info.wShowWindow = SW_SHOWNORMAL;CString strError;HANDLE hPtoken = NULL ;INTER_GetExplorerToken( &hPtoken ) ;if ( NULL == hPtoken ){return FALSE;}static HMODULE advapi32_dll = LoadLibraryW(L"advapi32.dll");if(!advapi32_dll)return FALSE;DWORD dwSessionId = 0;dwSessionId = WTSGetActiveConsoleSessionId();if ( !SetTokenInformation(hPtoken,TokenSessionId,(void*)(&dwSessionId),sizeof(DWORD)) ){DWORD dwError = GetLastError();FreeLibrary(advapi32_dll);return FALSE;}TOKEN_PRIVILEGES tp; //新特权结构体LUID Luid;BOOL retn = LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&Luid);if(retn != TRUE){//cout<<"获取Luid失败"<<endl;FreeLibrary(advapi32_dll);return FALSE;}//给TP和TP里的LUID结构体赋值tp.PrivilegeCount = 1;tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;tp.Privileges[0].Luid = Luid;//TOKEN_PRIVILEGES tp;if(!AdjustTokenPrivileges(hPtoken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL)) //这个函数启用或禁止指定访问令牌的特权{int abc =GetLastError();printf("Adjust Privilege value Error: %u\n",GetLastError());FreeLibrary(advapi32_dll);return FALSE;}if (GetLastError()== ERROR_NOT_ALL_ASSIGNED){printf("Token does not have the provilege\n");}DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;LPVOID pEnv = NULL;if(!CreateEnvironmentBlock(&pEnv,hPtoken,FALSE)){//PrintfDbgStr(TEXT("CreateEnvironmentBlock error !error code:%d\n"),GetLastError());//bSuccess = FALSE;//break;}BOOL bResult = FALSE;if ( 0 == csParam.CompareNoCase(EMPTY_STRING) ){bResult = CreateProcessAsUser(hPtoken, // 这个参数上面已经得到strFileName,NULL, // command lineNULL, // pointer to process SECURITY_ATTRIBUTESNULL, // pointer to thread SECURITY_ATTRIBUTESFALSE, // handles are not inheritabledwCreationFlag, // creation flagspEnv, // pointer to new environment blockNULL, // name of current directory&info, // pointer to STARTUPINFO structure&m_pinfo // receives information about new process);}else{bResult = CreateProcessAsUser(hPtoken, // 这个参数上面已经得到strFileName,csParam.GetBuffer(csParam.GetLength()), // command lineNULL, // pointer to process SECURITY_ATTRIBUTESNULL, // pointer to thread SECURITY_ATTRIBUTESFALSE, // handles are not inheritabledwCreationFlag, // creation flagsNULL, // pointer to new environment blockNULL, // name of current directory&info, // pointer to STARTUPINFO structure&m_pinfo // receives information about new process);csParam.ReleaseBuffer();}DWORD dwCode = GetLastError();FreeLibrary(advapi32_dll);return bResult;} 上网搜索,看到了在服务中用管理员权限创建一个可弹出UI的进程这篇文章,添加了如上红色代码,终于顺利解决了这个问题。userenv.h
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-52922-1.html
没有马云也会有张云李云
很看好