windows - eksempelkode: En serviceopkald CreateProcessAsUser () Jeg vil have, at processen skal køre i brugerens session, ikke session 0

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg søger eksempelkode:


For en serviceopkald CreateProcessAsUser () Jeg vil have, at processen skal køre i brugerens session, ikke session 0


hidtil er den oprettede proces kun kører som en tjeneste i session 0

Bedste reference


Dette blev fjernet fra en gammel kode, der lancerede en konsol-app fra en tjeneste. Det fungerede under NT4, men jeg har ikke testet det med en moderne version af Windows, så det kan ikke garantere, at det vil fungere som det gjorde på NT4.


EDIT: Nej, det kommer ikke til at fungere som. Du skal tilføje koden, der findes her for at oprette et skrivebord, indstille SID osv. [4]


    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;

Andre referencer 1


Jeg ved, at dette er et gammelt indlæg, men jeg tilfældigvis arbejder på dette, så her er en kode, der virker for mig.


Bestem sessionens id for den bruger, der er logget på


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;
}


Start processen som den bruger, der er logget på


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;
}