代码之家  ›  专栏  ›  技术社区  ›  Phisn

通过服务启动进程后,shGetKnownFolderPath中出现错误0x80070005

  •  1
  • Phisn  · 技术社区  · 7 年前

    我使用下面的代码来获取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;
        }
    

    我在网上没有发现任何与此相关的东西。有人能帮忙吗?

    1 回复  |  直到 7 年前
        1
  •  3
  •   RbMm    7 年前

    你不及格的错误 lpEnvironment 参数到 CreateProcess 呼叫。

    低压环境 [输入,可选]

    指向新进程的环境块的指针。如果这个 参数是 无效的 ,新进程使用 调用进程。

    因此,子进程使用调用进程的环境。这会有什么影响 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 呼叫中的标志 创建进程用户

    此外,您的错误很容易在本地(不提升)过程中由下一个代码复制:

    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)