Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Internet Explorer aus Systemdienst starten (https://www.delphipraxis.net/158747-internet-explorer-aus-systemdienst-starten.html)

rollstuhlfahrer 2. Mär 2011 14:43

AW: Internet Explorer aus Systemdienst starten
 
Glücklicherweise gibt es das Buch bei Google Books und es sind auch die "richtigen" Seiten veröffentlicht (Link).

Bernhard

Dezipaitor 2. Mär 2011 16:52

AW: Internet Explorer aus Systemdienst starten
 
Das CreateToken Privileg, welches für ZwCreateToken benötigt wird, ist ab Vista nicht mehr automatisch einem Dienst gegeben.
Außerdem, RunAsSys von JEDI funktioniert auch ohne.


ShellExecute sollte man nicht von einem Dienst aus nutzen, sondern stattdessen einen Prozess in die Session starten mit WTSGetActiveConsoleSession->WTSQueryUserToken->CreateProcessAsUser und dort dann nutzen.

kuba 3. Mär 2011 07:52

AW: Internet Explorer aus Systemdienst starten
 
Zitat:

Zitat von Dezipaitor (Beitrag 1085424)
Außerdem, RunAsSys von JEDI funktioniert auch ohne.

Ohne Passwort ?

Beim Einsatz von JEDI bekomme ich gelegentlich Konflikte, meistens mit der Unit Windows. Daher nutze ich JEDI nur selten. Inzwischen habe ich eine Lösung gefunden, allerdings keine besonders schöne. Ich starte ein Hilfsprogramm über den Registrierungsschlüssel HKEY_CURRENT_USER\Software\Microsoft\Windows\Curre ntVersion\Policies\Explorer\Run

Vorläufig kann ich das so machen, bis ich eine komfortablere Lösung gefunden habe.

KUBA

kuba 30. Mai 2011 22:53

AW: Internet Explorer aus Systemdienst starten
 
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


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:28 Uhr.
Seite 3 von 3     123   

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz