Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Screenshot aus TService (https://www.delphipraxis.net/209992-screenshot-aus-tservice.html)

Hobbycoder 15. Feb 2022 12:23

Screenshot aus TService
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Leute,

ich stehe vor dem Problem einen Screenshot des aktuell angemeldeten Benutzer (nur Workstation an Console, kein RDP oder Terminalserver) aus einem TService heraus zu machen. Komme aber mit meinem Wissen nicht so recht weiter und brauch eure Unterstützung.

Folgendes habe ich bereits zusammengesucht um auf dem lokalen Desktop zu kommen (und hoffe, dass das soweit korrekt ist).
Delphi-Quellcode:
function TScreenCapture.GetScreenBitmap(bmp: Vcl.Graphics.TBitmap; lpszWinSta: PWideChar): Boolean;
var
  hDeskCurrent: HDESK;
  hdesk1: HDESK;
  hwinstaCurrent: HWINSTA;
  hwinsta1: HWINSTA;
  Canvas: TCanvas;
  r: TRect;
begin
  hwinstaCurrent:=GetProcessWindowStation;
  if hwinstaCurrent<>0 then
  begin
    hwinsta1:=OpenWindowStation(lpszWinSta, False,
      WINSTA_ACCESSCLIPBOARD or
      WINSTA_ACCESSGLOBALATOMS or
      WINSTA_CREATEDESKTOP or
      WINSTA_ENUMDESKTOPS or
      WINSTA_ENUMERATE or
      WINSTA_EXITWINDOWS or
      WINSTA_READATTRIBUTES or
      WINSTA_READSCREEN or
      WINSTA_WRITEATTRIBUTES);
    if hwinsta1<>0 then
    begin
      if SetProcessWindowStation(hwinsta1) then
      begin
        hdesk1:=OpenDesktop('default', 0, False,
          DESKTOP_CREATEMENU or
          DESKTOP_CREATEWINDOW or
          DESKTOP_ENUMERATE or
          DESKTOP_HOOKCONTROL or
          DESKTOP_JOURNALPLAYBACK or
          DESKTOP_JOURNALRECORD or
          DESKTOP_READOBJECTS or
          DESKTOP_SWITCHDESKTOP or
          DESKTOP_WRITEOBJECTS);
        // Hier Screenshot machen
        if SetThreadDesktop(hdesk1) then
        begin
          Canvas := TCanvas.Create;
          try
            Canvas.Handle:=GetWindowDC(hdesk1);
            try
              //GetWindowRect(Canvas.Handle, r);
              bmp.Width:=Screen.Width;
              bmp.Height:=Screen.Height;
              bmp.PixelFormat:=pfDevice;
              BitBlt(bmp.Canvas.Handle, 0, 0, Pred(bmp.Width),
                  Pred(bmp.Height), Canvas.Handle, 0,
                  0, SRCCOPY);
            finally
              ReleaseDC(0, Canvas.Handle);
            end;
          finally
            Canvas.Free;
          end;
        end;
        CloseDesktop(hdesk1);
      end;
    end;
  end;
end;
Aufruf:
Delphi-Quellcode:
        bmp:=Vcl.Graphics.TBitmap.Create;
        try
          try
            GetScreenBitmap(bmp, 'WinSta0');
          except
            DoLastError(GetLastError);
          end;
          bmp.SaveToFile(FPath+'bmp.bmp');
        finally
          bmp.Free;
        end;
Soweit so gut. Diese Funktion lasse ich in einem Thread laufen (Source hängt an).
Wenn ich das über eine TApplication, also über den Benutzercontext, laufen lassen, bekomme ich auch eine Bitmap. Allerdings ist diese weiß.
Lass ich das über ein TService laufen, bekomme ich ebenfalls eine weiße Bitmap. Zusätzlich tritt bei Screen.Width, bei Screen.Height oder beim BitBlt (und wenn ich es drin lasse auch beim GetWindowRect) ein Windows-Fehler 1400 auf.

Irgendwas mache ich wohl grundsätzlich falsch. Ich bin mir auch nicht sicher, ob ich aus einem TService auf Screen zugreifen kann. Wär nett, wenn sich das mal jemand anschauen könnte.

Vielen Dank

peterbelow 15. Feb 2022 15:24

AW: Screenshot aus TService
 
Delphi-Quellcode:
           Canvas.Handle:=GetWindowDC(hdesk1);
Das ist schonmal falsch, den hdesk1 ist kein window handle (HWND). Versuch mal
Delphi-Quellcode:
           Canvas.Handle:=GetWindowDC(HWND_DESKTOP);

Rollo62 15. Feb 2022 15:26

AW: Screenshot aus TService
 
Vielleicht ist es so, dass es nicht so einfach möglich ist das UI aus dem Service anzusprechen.
https://stackoverflow.com/questions/...s-black-screen
https://stackoverflow.com/questions/...in-system-tray
https://social.msdn.microsoft.com/Fo...=csharpgeneral
https://www.codeproject.com/Question...esktop-service
Ich denke aber es sollte irgendwelche Hacks und Tricks geben, um einen Screenshot zu machen.

Der schöne Günther 15. Feb 2022 15:38

AW: Screenshot aus TService
 
Wenn das nicht gehen würde, was machen denn dann Dienste wie VNC und so. Gehen wird es schon.

PS: Vielleicht ist die Desktop Duplication API etwas. Irgendwo auf Github habe ich mal Delphi-Wrapper dafür gefunden und auch erfolgreich verwendet. Als Dienst habe ich das aber nie probiert, das lief immer im Kontext des angemeldeten Benutzers.

KodeZwerg 15. Feb 2022 16:56

AW: Screenshot aus TService
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1502241)
Irgendwo auf Github habe ich mal Delphi-Wrapper dafür gefunden und auch erfolgreich verwendet.

github.com/DesktopDuplicationAPI

Der schöne Günther 15. Feb 2022 17:23

AW: Screenshot aus TService
 
Genau das war es, danke 😎

Sinspin 16. Feb 2022 08:25

AW: Screenshot aus TService
 
Dienste laufen in einem anderen Desktop und kommen da auch nicht raus.
Du brauchst also zu deinem Dienst ein Programm das in der aktuell User session sitzt und dir die Bilder liefert.

Rollo62 16. Feb 2022 08:34

AW: Screenshot aus TService
 
Zitat:

Zitat von Sinspin (Beitrag 1502273)
Du brauchst also zu deinem Dienst ein Programm das in der aktuell User session sitzt und dir die Bilder liefert.

Das war auch mein erster Gedanke, dass der Service eventuell regelmäßig ein kleines, unsichtbares Snapshot-Programm triggern könnte, dass ihm die Daten liefert.

Die Idee mit DesktopDuplicationApi ist auch nett, ich sehe da aber nirgends dass man sich vom Service aus was holen könnte.
Wahrscheinlich ist das Ergebnis im Service dann auch wieder nur schwarz oder weiss, aber eben nicht aus dem User Process.
Hat es damit denn funktioniert ?

Union 16. Feb 2022 08:48

AW: Screenshot aus TService
 
Hast Du es mal mit
Delphi-Quellcode:
OpenWindowStation('winsta0', True, GENERIC_ALL)
probiert? Und anstelle von default für den Desktopnamen
Delphi-Quellcode:
GetUserObjectInformation(OpenInputDesktop(0, false, GENERIC_ALL), UOI_NAME, @pDesktopname, 256, dwLen)
?

Hobbycoder 16. Feb 2022 14:45

AW: Screenshot aus TService
 
Zitat:

Zitat von Rollo62 (Beitrag 1502277)
Zitat:

Zitat von Sinspin (Beitrag 1502273)
Du brauchst also zu deinem Dienst ein Programm das in der aktuell User session sitzt und dir die Bilder liefert.

Das war auch mein erster Gedanke, dass der Service eventuell regelmäßig ein kleines, unsichtbares Snapshot-Programm triggern könnte, dass ihm die Daten liefert.

Die Idee mit DesktopDuplicationApi ist auch nett, ich sehe da aber nirgends dass man sich vom Service aus was holen könnte.
Wahrscheinlich ist das Ergebnis im Service dann auch wieder nur schwarz oder weiss, aber eben nicht aus dem User Process.
Hat es damit denn funktioniert ?

Also im Dienst läuft es damit auch nicht. Schon beim
Delphi-Quellcode:
FDuplication.GetFrame
kommt SystemError 170.

Möglicherweise muss ich mich von dem Anspruch verabschieden, dass gänzlich unter Verzicht einer Application im Usercontext zu realisieren. Ziel war eigentlich die Manipulation der Function über den Taskmanager zu unterbinden.
Allerdings hat die DesktopDuplicationApi noch eine anderen Nachteil. Sie greif nämlich immer nur den primären Bildschirm ab. Bei 2 oder mehr Monitoren fehlt also immer einiges. Und ich habe (zumindes im Wrapper) keine Möglichkeit gefunden, den Bildschirm zu wechseln (allerdings würde ich beide gleichzeitig benötigen).

Zitat:

Zitat von Union (Beitrag 1502278)
Hast Du es mal mit
Delphi-Quellcode:
OpenWindowStation('winsta0', True, GENERIC_ALL)
probiert? Und anstelle von default für den Desktopnamen
Delphi-Quellcode:
GetUserObjectInformation(OpenInputDesktop(0, false, GENERIC_ALL), UOI_NAME, @pDesktopname, 256, dwLen)
?

Hm....kurze Frage: Was würde das GetUserObjectInformation bringen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:16 Uhr.
Seite 1 von 2  1 2      

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