Ошибка 0x80070005 от SHGetKnownFolderPath после запуска процесса через службу - PullRequest
0 голосов
/ 03 июня 2018

Я использую код ниже, чтобы получить папку 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 Ответ

0 голосов
/ 03 июня 2018

ваша ошибка, что вы не передали lpEnvironment параметр в CreateProcess вызов.

lpEnvironment [in, необязательно]

Указатель наблок среды для нового процесса.Если этот параметр равен 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)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...