Einzelnen Beitrag anzeigen

Benutzerbild von kuba
kuba

Registriert seit: 26. Mai 2006
Ort: Arnsberg
588 Beiträge
 
Delphi 11 Alexandria
 
#24

AW: Internet Explorer aus Systemdienst starten

  Alt 30. Mai 2011, 23:53
so habe ich es jetzt funktionsfähig bekommen:

Delphi-Quellcode:
procedure ProgramExecute(var PW1, PW2, PW3 :string);
var
    SI : TStartupInfo;
    PI : TProcessInformation;
    CmdLine : String;
    ProcCreated : Boolean;
    hUserToken : THandle;
    ActiveSessionID : Integer;
    hShell : THandle;
    hToken : THandle;
    pEnv : Pointer;
    ServiceToken, CopiedToken, UserToken : TJwSecurityToken;
begin
     if IsWtsAvailable then // usually XP and Vista.
     begin
        ActiveSessionID := GetActiveWtsSession;
        if ActiveSessionID < 0 then
        begin
            ShowMessage('GetActiveWtsSession returned -1, no user logged on');
            Exit;
        end;
// { Show MessageBox, this is blocking, prevents service from answering }
// { control messages from SCM, Timeout in seconds ! }
// f_WtsSendMessage(WTS_CURRENT_SERVER_HANDLE, ActiveSessionID,
// PChar(Title), Length(Title) + 1, PChar(Msg), Length(Msg) + 1,
// MB_YESNO or MB_ICONQUESTION, 30, MsgResult, TRUE);
// if MsgResult <> IDYES then
// Exit;
        { Get the user token from WtsApi }
        if not f_WTSQueryUserToken(ActiveSessionID, hUserToken) then
        begin
            AppendStringToFile(('WTSQueryUserToken error ' + SysErrorMessage(GetLastError)), Dateiname);
            Exit;
        end;
    end
    else begin // usually NT and W2K.
        if (Win32Platform = VER_PLATFORM_WIN32_NT) and
           (Win32MajorVersion >= 6) then
        begin
            { Will most likely never happen }
            //AppendStringToFile(('Can''t display a message box in Vista if Wts isn''t ' +
            // 'available'), Dateiname);
            //Exit;
        end;
        { Requires PSAPI.DLL which isn't available in all NT4-Versions, }
        { however it's a distributable!                                 }
        hShell := GetShellHandle;
        if hShell = 0 then
        begin
            AppendStringToFile(('No shell handle, no user logged on or PsApi not available'), Dateiname);
            Exit;
        end;
        try
// { Show MessageBox, this is blocking, prevents service from }
// { answering control messages from SCM. }
// if MessageBox(0, PChar(Msg), PChar(Title),
// MB_SERVICE_NOTIFICATION or MB_YESNO or
// MB_ICONQUESTION) <> IDYES then
// Exit;
            { Get the user token from the shell process                 }
            if not OpenProcessToken(hShell, TOKEN_ALL_ACCESS, hUserToken) then
            begin
                AppendStringToFile('OpenProcessToken error ' + SysErrorMessage(GetLastError), Dateiname);
                Exit;
            end;
        finally
            CloseHandle(hShell);
        end;
    end;
        //get the token from the service system session
        ServiceToken := TJwSecurityToken.CreateTokenEffective(MAXIMUM_ALLOWED);
        //copy the token to be able to change the TokenSessionId
        //Info: Win2000: Only 0
        // WinXP: Service=0, 1.User=0, 2.User=1, 3.User=2, ...
        // WinVista: Service=0, 1.User=1, 2.User=2, 3.User=3, ...
        CopiedToken := TJwSecurityToken.CreateDuplicateExistingToken(ServiceToken.TokenHandle, MAXIMUM_ALLOWED);
        //get the token of the logged in user
        if GetWinVersion = wvWin2000 then
        UserToken := TJwSecurityToken.CreateCompatibilityQueryUserToken(MAXIMUM_ALLOWED, 'explorer.exe')
        else //XP, 2003, Vista, 2008
        UserToken := TJwSecurityToken.CreateWTSQueryUserTokenEx(nil, WtsGetActiveConsoleSessionID);
        //give the copied token the same sessionid as the logged in user
        CopiedToken.TokenSessionId := UserToken.TokenSessionId;
        //create the environment block using the logged in user
        if not WTSQueryUserToken(WTSGetActiveConsoleSessionId, hToken) then
        RaiseLastOSError;
        JwaWindows.CreateEnvironmentBlock(@pEnv, UserToken.TokenHandle, true);
    try
        CmdLine := Format('"%s%s" %s',[IncludeTrailingPathDelimiter(PW1),PW2,PW3]);
        FillChar(SI, SizeOf(SI), #0);
        FillChar(PI, SizeOf(PI), #0);
        SI.cb := SizeOf(SI);
        SI.lpDesktop := PChar('Winsta0\Default');
        SI.dwFlags := STARTF_USESHOWWINDOW;
        SI.wShowWindow := SW_SHOWDEFAULT;
        ProcCreated := CreateProcessAsUser(
                            hUserToken,
                            nil,
                            PChar(CmdLine), // pointer to command line string
                            nil, // pointer to process security attributes
                            nil, // pointer to thread security attributes
                            True, // handle inheritance
                            CREATE_NEW_CONSOLE or CREATE_DEFAULT_ERROR_MODE or CREATE_UNICODE_ENVIRONMENT, // creation flags
                            pEnv, // pointer to new environment block
                            nil, // pointer to current directory name
                            SI, // STARTUPINFO
                            PI); // PROCESS_INFORMATION

        if ProcCreated then
        begin
            CloseHandle(PI.hProcess);
            CloseHandle(PI.hThread);
            DestroyEnvironmentBlock(pEnv);
        end
        else
            AppendStringToFile('Error ' + SysErrorMessage(GetLastError), Dateiname);
    finally
        CloseHandle(hUserToken);
    end;
end;
Basierend auf diesen NT-Service und den o.g. Anpassungen für 64-Bit Windows.

kuba
Stefan Kubatzki
E=mc2
  Mit Zitat antworten Zitat