пример кода: служба вызывает CreateProcessAsUser () Я хочу, чтобы процесс выполнялся в сеансе пользователя, а не в сеансе 0 - PullRequest
5 голосов
/ 02 сентября 2011

Я ищу пример кода:

Для вызова службы CreateProcessAsUser () Я хочу, чтобы процесс выполнялся в сеансе пользователя, а не в сеансе 0

, пока созданный процесс только запущенкак услуга в сеансе 0

Ответы [ 2 ]

3 голосов
/ 03 сентября 2011

Это было удалено из некоторого старого кода, который запускал консольное приложение из службы. Он работал под NT4, но я не тестировал его с современной версией Windows, поэтому не могу гарантировать, что он будет работать так же, как и на NT4.

РЕДАКТИРОВАТЬ: Нет, это не будет работать как есть. Вам нужно добавить найденный код здесь , чтобы создать рабочий стол, установить SID и т. Д.

    if (!LogonUser(userId,
                   domain,
                   password,
                   LOGON32_LOGON_INTERACTIVE,
                   LOGON32_PROVIDER_DEFAULT,
                   &hUserToken))
    {
        return GetLastError();
    }

    if (!ImpersonateLoggedOnUser(hUserToken))
    {
        DWORD rc = GetLastError();
        CloseHandle(hUserToken);
        return rc;
    }

    STARTUPINFO             si;
    PROCESS_INFORMATION pi;

    memset(&si, 0, sizeof(si));
    memset(&pi, 0, sizeof(pi));

    si.cb = sizeof(si);

    rc = CreateProcessAsUser(hUserToken,                // user token
                           0,                           // app name
                           "foo.exe",                   // command line
                           0,                           // process attributes
                           0,                           // thread attributes
                           FALSE,                       // don't inherit handles
                           DETACHED_PROCESS,            // flags
                           0,                           // environment block
                           0,                           // current dir
                           &si,                         // startup info
                           &pi);                        // process info gets put here


    if (!rc)
    {
        DWORD rc = GetLastError();
        RevertToSelf();
        CloseHandle(hUserToken);
        return rc;
    }

    RevertToSelf();
    CloseHandle(hUserToken);

    return 0;
0 голосов
/ 07 июня 2018

Я знаю, что это древний пост, но я работаю над этим, поэтому вот код, который работает для меня.

Определение идентификатора сеанса текущего пользователя, вошедшего в систему

DWORD GetCurrentSessionId ()
{
    WTS_SESSION_INFO *pSessionInfo;
    DWORD n_sessions = 0;
    BOOL ok = WTSEnumerateSessions (WTS_CURRENT_SERVER, 0, 1, &pSessionInfo, &n_sessions);
    if (!ok)
        return 0;

    DWORD SessionId = 0;

    for (DWORD i = 0; i < n_sessions; ++i)
    {
        if (pSessionInfo [i].State == WTSActive)
        {
            SessionId = pSessionInfo [i].SessionId;
            break;
        }
    }

    WTSFreeMemory (pSessionInfo);
    return SessionId;
}

Запуск процесса от имени текущего пользователя

bool LaunchProcess (const char *process_path)
{
    DWORD SessionId = GetCurrentSessioId ();
    if (SessionId == 0)    // no-one logged in
        return false;

    HANDLE hToken;
    BOOL ok = WTSQueryUserToken (SessionId, &hToken);
    if (!ok)
        return false;

    void *environment = NULL;
    ok = CreateEnvironmentBlock (&environment, hToken, TRUE);

    if (!ok)
    {
        CloseHandle (hToken);
        return false;
    }

    STARTUPINFO si = { sizeof (si) } ;
    PROCESS_INFORMATION pi = { } ;
    si.lpDesktop = "winsta0\\default";

    // Do NOT want to inherit handles here
    DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT;
    ok = CreateProcessAsUser (hToken, process_path, NULL, NULL, NULL, FALSE,
        dwCreationFlags, environment, NULL, &si, &pi);

    DestroyEnvironmentBlock (environment);
    CloseHandle (hToken);

    if (!ok)
        return false;

    CloseHandle (pi.hThread);
    CloseHandle (pi.hProcess);
    return true;
}
...