Delphi-PRAXiS

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)

kuba 1. Mär 2011 10:22

Internet Explorer aus Systemdienst starten
 
Hallo,

ich starte den Internet Explorer mit CreateProcessAsUser aus einem Windows NT-Service (Windows 7). Wenn ich mir dann die Favoritenliste ansehe ist diese leer. Wenn ich versuche einen neuen Favoriten anzulegen bleibt die Favoritenliste leer. Offensichtlich funktionieren auch die Active-X Steuerelemente nicht. Sobald ich den Internet Explorer per Mausklick oder über "Autostart" ausführe, sind die Favoriten wieder vorhanden. Woran kann das liegen ??

KUBA

Satty67 1. Mär 2011 10:33

AW: Internet Explorer aus Systemdienst starten
 
Gib doch im gestartet Explorer mal die Url file:///%AppData% ein, dann siehst Du, ob der UserContext wie gewünscht ist.

kuba 1. Mär 2011 10:44

AW: Internet Explorer aus Systemdienst starten
 
Hy,

wenn ich den Internet Explorer per Mausklick gestartet habe erscheint der Explorer mit folgendem Pfad: C:\Users\Benutzer\AppData\Roaming
Aus dem NT-Service heraus gestartet erscheint eine Fehlermeldung: Die Datei file:///C:\Windows\System32\config\Systemprofile\AppData\R oaming wurde nicht gefunden. Überprüfen Sie die Schreibweise und wiederholen Sie den Vorgang.

Was läuft denn da falsch ??

KUBA

hathor 1. Mär 2011 10:51

AW: Internet Explorer aus Systemdienst starten
 
CreateProcessAsUserW ?

CreateEnvironmentBlock ?

X:\Windows\System32\config\systemprofile\AppData\R oaming\Microsoft\Windows ?

(Die Forumssoftware hat eine Macke: das SPACE in "Roaming" entfällt)

kuba 1. Mär 2011 11:03

AW: Internet Explorer aus Systemdienst starten
 
CreateProcessAsUserA habe ich gerade ausprobiert, funktioniert jedoch auch nicht ...

KUBA

Assarbad 1. Mär 2011 11:38

AW: Internet Explorer aus Systemdienst starten
 
Mal unbesehen des Unsinns eine Instanz des Internet Explorer aus einem Dienst zu starten, bitte stoppe doch mal folgenden Dienst: UI0Detect. Dann probiert dein Programm nochmal. Bin gespannt auf's Ergebnis ;)

Übrigens: %SystemRoot%\System32\config\Systemprofile enthält "Desktop" usw. für das Konto SYSTEM.

Dezipaitor 1. Mär 2011 11:38

AW: Internet Explorer aus Systemdienst starten
 
und wie bist du zu dem token für CreateProcessAsUserW gekommen?

Assarbad 1. Mär 2011 11:52

AW: Internet Explorer aus Systemdienst starten
 
Zitat:

Zitat von Dezipaitor (Beitrag 1085074)
und wie bist du zu dem token für CreateProcessAsUserW gekommen?

Kannste dir auch ohne PW basteln. Nebbett hat gezeigt wie's geht.

rollstuhlfahrer 1. Mär 2011 12:39

AW: Internet Explorer aus Systemdienst starten
 
Wenn du eine Anwendung als anderer User startest, so hat diese keine Umgebungsvariablen. Folglich ist auch %APPDATA% nicht besetzt und kann deswegen nicht aufgerufen werden. Ähnlich sieht es mit dem Favoritenordner aus, der nicht in APPDATA liegt, sondern im Benutzerprofil. Du müsstest deinem Prozess also die richtigen Umgebungsvariablen mitgeben. Das wurde schon in #4 angesprochen.

Bernhard

PS: Probiere es mal aus: Öffne aus deinem Dienst unter anderem Benutzernamen die CMD und gib mal "set" ein. Ein Wunder wie wenig da kommt.

Assarbad 1. Mär 2011 12:42

AW: Internet Explorer aus Systemdienst starten
 
Zitat:

Zitat von rollstuhlfahrer (Beitrag 1085114)
Wenn du eine Anwendung als anderer User startest, so hat diese keine Umgebungsvariablen. Folglich ist auch %APPDATA% nicht besetzt und kann deswegen nicht aufgerufen werden. Ähnlich sieht es mit dem Favoritenordner aus, der nicht in APPDATA liegt, sondern im Benutzerprofil. Du müsstest deinem Prozess also die richtigen Umgebungsvariablen mitgeben.

Bist du dir hundertprozentig sicher, daß die Shellfunktionen sich auf die Umgebungsvariablen verlassen?

kuba 1. Mär 2011 12:45

AW: Internet Explorer aus Systemdienst starten
 
Zitat:

Zitat von Assarbad (Beitrag 1085073)
Mal unbesehen des Unsinns eine Instanz des Internet Explorer aus einem Dienst zu starten, bitte stoppe doch mal folgenden Dienst: UI0Detect. Dann probiert dein Programm nochmal. Bin gespannt auf's Ergebnis ;)

Übrigens: %SystemRoot%\System32\config\Systemprofile enthält "Desktop" usw. für das Konto SYSTEM.

Hab ich ausprobiert, bzw. UI0Detect war nicht gestartet. Der Dienst hat keinen Einfluss auf meinen NT-Service, habs ausprobiert. Funktioniert denn RunAs aus einem NT-Service ?? Kennwort ist uninteressant ...

KUBA

Assarbad 1. Mär 2011 12:48

AW: Internet Explorer aus Systemdienst starten
 
Zitat:

Zitat von kuba (Beitrag 1085122)
Funktioniert denn RunAs aus einem NT-Service ??

Ehrlich gesagt noch nie probiert. Meiner Meinung nach spricht aber auch nichts wirklich dagegen. Versuch's doch. Du meinst ShellExecute(Ex) und das Verb "runas"?

kuba 1. Mär 2011 13:14

AW: Internet Explorer aus Systemdienst starten
 
Also mit RunAs funktionierts, allerdings ist das mit dem Passwort nicht ganz unproblematisch. Wenn ich das Kennwort ändere während der Benutzer angemeldet ist funktioniert RunAs nicht.

Wo hat Nebbett denn gezeigt wies ohne Passwort geht ?

Mit Windows 2000/XP gehts auch ohne Passwort ...

KUBA

Assarbad 1. Mär 2011 15:06

AW: Internet Explorer aus Systemdienst starten
 
Zitat:

Zitat von kuba (Beitrag 1085129)
Wo hat Nebbett denn gezeigt wies ohne Passwort geht ?

In der "Windows NT/2000 Native API Reference". Erfordert eben das TCB-Privileg. Aber das haste wenn du als Dienst unterwegs bist.

rollstuhlfahrer 1. Mär 2011 16:21

AW: Internet Explorer aus Systemdienst starten
 
Gibts auch ne Seitenzahl? - Nen Link wirds wohl kaum geben, da das ein Buch ist.

Bernhard

Assarbad 1. Mär 2011 16:43

AW: Internet Explorer aus Systemdienst starten
 
Zitat:

Zitat von rollstuhlfahrer (Beitrag 1085194)
Gibts auch ne Seitenzahl? - Nen Link wirds wohl kaum geben, da das ein Buch ist.

Leider im Moment nicht, da ich das Buch nicht hier habe. Kann aber am Abend nachschauen. Habe auch irgendwo eine elektronische Variante (neben den zwei gekauften physischen Exemplaren) :stupid:

Der Beispielcode war damals allerdings von Newriders noch herunterladbar. Der sollte also allemal auffindbar sein.

kuba 1. Mär 2011 18:43

AW: Internet Explorer aus Systemdienst starten
 
Den Nt-Service habe ich nicht selbst geschrieben sondern aus dem Internet.

Anscheinend funktioniert die Übergabe des Usertoken nicht unter Vista/7. Der Service funktioniert auch nicht unter 64Bit Betriebssystemen, da hab ich aber mittlerweile eine Lösung gefunden damit es doch funktioniert.

Würde mich sehr freuen wenn mir jemand einen Tip geben könnte was da falsch läuft, danke !

KUBA

PS: 64 Bit Anpassung...

Delphi-Quellcode:
function GetShellProcName: String;
var
    Reg : TRegistry;
begin
    if IsWin64 then Reg := TRegistry.Create(KEY_ALL_ACCESS OR KEY_WOW64_64KEY);
    if not IsWin64 then Reg := TRegistry.Create(KEY_READ);
    try
        Reg.RootKey := HKEY_LOCAL_MACHINE;
        Reg.OpenKeyReadOnly('Software\Microsoft\Windows NT\CurrentVersion\WinLogon');
        Result := Reg.ReadString('Shell');
    finally
        Reg.Free;
    end;
end;


function GetShellHandle: THandle;
var
    Pid : THandle;
    ShellProcName : String;
begin
    Result := 0;
    ShellProcName := GetShellProcName;
    if Length(ShellProcName) > 0 then
    begin
        Pid := ProcessIDFromAppname32(ShellProcName);
        if Pid <> 0 then
            Result := OpenProcess(PROCESS_ALL_ACCESS, False, Pid);
    end;
end;

Assarbad 2. Mär 2011 02:11

AW: Internet Explorer aus Systemdienst starten
 
Zitat:

Zitat von rollstuhlfahrer (Beitrag 1085194)
Gibts auch ne Seitenzahl? - Nen Link wirds wohl kaum geben, da das ein Buch ist.

Seite 205 ff.

hathor 2. Mär 2011 06:27

AW: Internet Explorer aus Systemdienst starten
 
Zitat:

Zitat von Assarbad (Beitrag 1085199)
...(neben den zwei gekauften physischen Exemplaren) :stupid: ...

M.Alzheimer ? :stupid:

Assarbad 2. Mär 2011 12:30

AW: Internet Explorer aus Systemdienst starten
 
Zitat:

Zitat von hathor (Beitrag 1085284)
Zitat:

Zitat von Assarbad (Beitrag 1085199)
...(neben den zwei gekauften physischen Exemplaren) :stupid: ...

M.Alzheimer ? :stupid:

HMM? Was meinst du? Es war nicht Vergeßlichkeit weshalb ich zwei habe, wenn das gemeint war. Mittlerweile ist das Buch ausverkauft und kurz nach dem Erscheinen hatte ich mein erstes Exemplar gekauft. Das sieht man diesem auch an - auch wie intensiv es genutzt wurde. Das zweite Exemplar sieht noch relativ unbeschädigt aus ;)

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 05:36 Uhr.

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