1. 程式人生 > >服務中拉起程式報錯

服務中拉起程式報錯

CFileDialog
c:\windows\system32\config\systemprofile\desktop 引用一個不可用的位置

原因:
The Desktop directory is part of the user profile. Starting an application from a service means that it does not have a user profile and therefore no desktop.

解決辦法:

BOOL CExecuteProcess::StartProcessWithToken(CString csProcessPath, CString csCommandLineParam,
    CString csAccessProcessName, bool
bWait) { PROCESS_INFORMATION pi = { 0 }; STARTUPINFO si = { 0 }; BOOL bResult = FALSE; DWORD dwSessionId = 0x00, winlogonPid = 0x00; HANDLE hUserToken = NULL; HANDLE hUserTokenDup = NULL; HANDLE hPToken = NULL; HANDLE hProcess = NULL; HANDLE hToken = NULL; DWORD dwCreationFlags = 0x00
; DWORD dwLastError = 0x00; // Log the client on to the local computer. dwSessionId = WTSGetActiveConsoleSessionId(); ////////////////////////////////////////// // Get the explorer process handle //////////////////////////////////////// PROCESSENTRY32 procEntry; HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnap == INVALID_HANDLE_VALUE) { //return bResult;
goto Cleanup; } procEntry.dwSize = sizeof(PROCESSENTRY32); if (!Process32First(hSnap, &procEntry)) { //return bResult; goto Cleanup; } do { if (_wcsicmp(procEntry.szExeFile, csAccessProcessName) == 0) { // We found a explorer process... // make sure it's running in the console session DWORD winlogonSessId = 0; if (ProcessIdToSessionId(procEntry.th32ProcessID, &winlogonSessId) && winlogonSessId == dwSessionId) { winlogonPid = procEntry.th32ProcessID; break; } } } while (Process32Next(hSnap, &procEntry)); //////////////////////////////////////////////////////////////////////// ::WTSQueryUserToken(dwSessionId, &hUserToken); dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.lpDesktop = L"winsta0\\default"; ZeroMemory(&pi, sizeof(pi)); TOKEN_PRIVILEGES tp; LUID luid; hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, winlogonPid); if (!::OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE, &hPToken)) { dwLastError = GetLastError(); goto Cleanup; //return bResult; } if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) { //printf("Lookup Privilege value Error: %u\n", GetLastError()); dwLastError = GetLastError(); //return bResult; goto Cleanup; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hUserTokenDup); dwLastError = GetLastError(); //Adjust Token privilege SetTokenInformation(hUserTokenDup, TokenSessionId, (void*)dwSessionId, sizeof(DWORD)); if (!AdjustTokenPrivileges(hUserTokenDup, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, NULL)) { dwLastError = GetLastError(); //return bResult; goto Cleanup; } //dwLastError = GetLastError(); //if (dwLastError == ERROR_NOT_ALL_ASSIGNED) //{ // //return bResult; // goto Cleanup; //} LPVOID pEnv = NULL; if (::CreateEnvironmentBlock(&pEnv, hUserTokenDup, TRUE)) { dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT; } else pEnv = NULL; // Launch the process in the client's logon session. bResult = CreateProcessAsUser( hUserTokenDup, // client's access token csProcessPath, // file to execute csCommandLineParam.GetBuffer(csCommandLineParam.GetLength()), // command line NULL, // pointer to process SECURITY_ATTRIBUTES NULL, // pointer to thread SECURITY_ATTRIBUTES FALSE, // handles are not inheritable dwCreationFlags, // creation flags pEnv, // pointer to new environment block NULL, // name of current directory &si, // pointer to STARTUPINFO structure &pi // receives information about new process ); csCommandLineParam.ReleaseBuffer(); dwLastError = GetLastError(); if (bResult) bResult = TRUE; //Perform All the Close Handles tasks Cleanup: if (hProcess) CloseHandle(hProcess); if (hUserToken) CloseHandle(hUserToken); if (hUserTokenDup) CloseHandle(hUserTokenDup); if (hPToken) CloseHandle(hPToken); if (hToken) CloseHandle(hToken); return bResult; }

ps:百度半天都不沾邊 google一下就出來了