Ich habe ein Programm, das SHGetKnownFolderPath mit FOLDERID_RoamingAppData aufruft.SHGetKnownFolderPath schlägt mit E_ACCESSDENIED fehl
Wenn ich das Programm durch Doppelklick starte, funktioniert es einwandfrei.
Wenn das Programm von einem Windows-Dienst (im aktuellen Benutzerkontext) gestartet wird, schlägt die Funktion mit Fehlern E_ACCESSDENIED (-2147024891). Diese
ist, was mein Code wie folgt aussieht:
Tstring EasyGetFolderPath(REFKNOWNFOLDERID folderid)
{
Tstring sPath = _T("");
PWSTR pszPath = NULL;
HRESULT hr = SHGetKnownFolderPath(folderid, 0, NULL, &pszPath);
if (hr == S_OK && pszPath)
{
sPath = WStringToTCHAR(pszPath);
CoTaskMemFree(pszPath);
return sPath;
}
else
{
throw HResultException(hr, _T("SHGetKnownFolderPath failed"));
}
}
Tstring EasyGetUsrAppDataPath()
{
return EasyGetFolderPath(FOLDERID_RoamingAppData);
}
static TCHAR* WStringToTCHAR(const std::wstring &s)
{
#ifdef UNICODE
TCHAR *sT = new TCHAR[s.length() + 1];
_tcscpy_s(sT, s.length() + 1, s.c_str());
return sT;
#else
std::string str = WStringToString(s);
TCHAR *sT = new TCHAR[str.length()+1];
_tcscpy_s(sT, str.length() + 1, str.c_str());
return sT;
#endif // UNICODE
}
static std::string WStringToString(const std::wstring& s, bool method = true)
{
std::string temp;
temp.assign(s.begin(), s.end());
return temp;
}
Dies ist der Code, der den Prozess in der aktuellen Benutzerkontext beginnt: (ich habe den Fehler behoben haben, um Ausführlichkeit zu reduzieren Handling)
void StartProcessInCurrentUserContext(const Tstring &sExeName, const Tstringarr &lstParams, const Tstring &sWorkingDir)
{
...
EnableDebugPrivilege();
errCode = GetProcessByName(_T("explorer.exe"), hProcess);
if (!OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken))
{
...
}
if (hProcess)
CloseHandle(hProcess);
Tstring sCmdLine = ...;
...
// Create the child process.
bSuccess = CreateProcessAsUser(hToken, NULL,
(LPTSTR)sCmdLine.c_str(), // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
sWorkingDir.length() > 0 ? (LPCTSTR)sWorkingDir.c_str() : NULL,
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
CloseHandle(hToken);
...
}
Weiß jemand, was das Problem sein könnte?
Vielleicht Benutzerzugriffskontrolle, u.a. UAC? Wie auch immer, warum benutzt du das dumme '_T' Zeug? Das ist 16 Jahre überholt. –
Nun, wenn ich es durch einen Doppelklick starte, wird die UAC nicht angezeigt. Also, ich glaube nicht, dass es damit zu tun hat. – conectionist
Möglicherweise liegt das Problem in 'WStringToTCHAR'. Zeige seine Definition. –