CFileDialog
c:\windows\system32\config\systemprofile\desktop 引用一个不可用的位置
解决方法:
http://www.codeproject.com/Answers/896139/CFileDialog-gives-error-C-Windows-system-config-sy#answer3
原因:
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一下就出来了