我使用下面的代码获取appdata文件夹。通常它可以工作,但如果我使用与this类似的方式开始使用相同的服务,我会收到错误0x80070005
,这意味着Access Denied
。
HRESULT result;
if ((result = SHGetKnownFolderPath(
FOLDERID_RoamingAppData,
NULL,
NULL,
&appdate)) != S_OK)
{
std::cout << result << std::endl
return false;
}
创建过程的函数是
if (!CreateProcessAsUser(
token,
executablePath,
executableName,
NULL,
NULL,
FALSE,
NORMAL_PRIORITY_CLASS,
NULL,
0,
&startupInfo,
&processInformation))
{
SHOW_SERVICE_ERROR;
}
我在互联网上找不到与此相关的任何内容。有人可以帮忙吗?
答案 0 :(得分:3)
您的错误,即您未将lpEnvironment
参数传递给CreateProcess
来电。
lpEnvironment [in,optional]
指向新进程的环境块的指针。如果这 参数是 NULL ,新进程使用的环境 呼叫过程。
结果子进程使用调用进程的环境。这会给FOLDERID_RoamingAppData
带来什么影响?在解决FOLDERID_RoamingAppData
期间 - 我们通常会获得%USERPROFILE%\AppData\Roaming
- 最终结果将取决于%USERPROFILE%
的值。在您的情况下 - 它将从服务(LocalSystem
)继承而且看起来像C:\WINDOWS\system32\config\systemprofile
- 所以最终路径必须看起来像C:\WINDOWS\system32\config\systemprofile\AppData\Roaming
。在将此路径返回给调用者之前 - 系统检查是路径存在 - 调用GetFileAttributes
。在这里它失败了(由于安全许可) - 最后一次错误 - 5 - ERROR_ACCESS_DENIED
。和api最终返回HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)
,即80070005
。
结论 - 在调用CreateProcessAsUser
中使用指向CreateEnvironmentBlock
返回的环境块的指针。然后由DestroyEnvironmentBlock
释放此块。也不要忘记调用CREATE_UNICODE_ENVIRONMENT
CreateProcessAsUser
标记
也可以通过下一个代码在本地(非提升)过程中轻松复制您的错误:
SetEnvironmentVariableW(L"USERPROFILE", L"C:\\WINDOWS\\system32\\config\\systemprofile");
PWSTR appdate;
HRESULT result;
if ((result = SHGetKnownFolderPath(
FOLDERID_RoamingAppData,
NULL,
NULL,
&appdate)) == S_OK)
{
CoTaskMemFree(appdate);
}
如果我们在USERPROFILE
设置无效路径,则会出现80070003
错误 - HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)