c++ - 通过服务启动进程后来自 SHGetKnownFolderPath 的错误 0x80070005
问题描述
我使用下面的代码来获取 appdata 文件夹。通常它可以工作,但如果我使用与此类似的方式通过服务启动相同的进程,我会收到错误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;
}
我在互联网上没有找到与此相关的任何内容。任何人都可以帮忙吗?
解决方案
您没有将lpEnvironment
参数传递给CreateProcess
调用的错误。
lpEnvironment [输入,可选]
指向新进程的环境块的指针。如果此参数为NULL,则新进程使用调用进程的环境。
结果子进程使用调用进程的环境。这有什么影响FOLDERID_RoamingAppData
?在解决期间FOLDERID_RoamingAppData
- 我们通常得到%USERPROFILE%\AppData\Roaming
- 最终结果将取决于%USERPROFILE%
. 在您的情况下-它将从 service( 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)
推荐阅读
- react-datepicker - 类型“null”不可分配给类型“SetStateAction”
' - c++ - 如何在 opencv c++ 中使用相应的掩码复制图像?
- python - 使用 ESRI arcgis python api 时出现 SSL 错误
- python - 删除 qtablewidget 中的选定行
- python - 将两个以上的点替换为 unicode 省略号
- laravel - 使用 Laravel 的 Orchestra 解析器解压包含列表的嵌套 XML
- linux - 戴尔电源的 snmpwalk 命令
- go - 压缩目录并且没有将结果保存在文件系统中
- java - 无法解析“PreviewView”中的方法“setPreferredImplementationMode”
- react-native - 按下 customButton 时 React-Native 没有任何反应,但是当我按下返回时它可以工作