AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Screenshot aus TService

Ein Thema von Hobbycoder · begonnen am 15. Feb 2022 · letzter Beitrag vom 16. Feb 2022
Antwort Antwort
Seite 1 von 2  1 2      
Hobbycoder

Registriert seit: 22. Feb 2017
961 Beiträge
 
#1

Screenshot aus TService

  Alt 15. Feb 2022, 13:23
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
Angehängte Dateien
Dateityp: pas uScreenCapture.pas (4,4 KB, 4x aufgerufen)
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
peterbelow

Registriert seit: 12. Jan 2019
Ort: Hessen
704 Beiträge
 
Delphi 12 Athens
 
#2

AW: Screenshot aus TService

  Alt 15. Feb 2022, 16:24
           Canvas.Handle:=GetWindowDC(hdesk1); Das ist schonmal falsch, den hdesk1 ist kein window handle (HWND). Versuch mal
           Canvas.Handle:=GetWindowDC(HWND_DESKTOP);
Peter Below
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.116 Beiträge
 
Delphi 12 Athens
 
#3

AW: Screenshot aus TService

  Alt 15. Feb 2022, 16:26
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.

Geändert von Rollo62 (15. Feb 2022 um 16:29 Uhr)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Screenshot aus TService

  Alt 15. Feb 2022, 16:38
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.

Geändert von Der schöne Günther (15. Feb 2022 um 16:40 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Screenshot aus TService

  Alt 15. Feb 2022, 17:56
Irgendwo auf Github habe ich mal Delphi-Wrapper dafür gefunden und auch erfolgreich verwendet.
github.com/DesktopDuplicationAPI
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Screenshot aus TService

  Alt 15. Feb 2022, 18:23
Genau das war es, danke 😎
  Mit Zitat antworten Zitat
Benutzerbild von Sinspin
Sinspin

Registriert seit: 15. Sep 2008
Ort: Dubai
691 Beiträge
 
Delphi 10.3 Rio
 
#7

AW: Screenshot aus TService

  Alt 16. Feb 2022, 09:25
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.
Stefan
Nur die Besten sterben jung
A constant is a constant until it change.
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.116 Beiträge
 
Delphi 12 Athens
 
#8

AW: Screenshot aus TService

  Alt 16. Feb 2022, 09:34
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 ?
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#9

AW: Screenshot aus TService

  Alt 16. Feb 2022, 09:48
Hast Du es mal mit OpenWindowStation('winsta0', True, GENERIC_ALL) probiert? Und anstelle von default für den Desktopnamen GetUserObjectInformation(OpenInputDesktop(0, false, GENERIC_ALL), UOI_NAME, @pDesktopname, 256, dwLen) ?
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all

Geändert von Union (16. Feb 2022 um 10:03 Uhr)
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
961 Beiträge
 
#10

AW: Screenshot aus TService

  Alt 16. Feb 2022, 15:45
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 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).

Hast Du es mal mit OpenWindowStation('winsta0', True, GENERIC_ALL) probiert? Und anstelle von default für den Desktopnamen GetUserObjectInformation(OpenInputDesktop(0, false, GENERIC_ALL), UOI_NAME, @pDesktopname, 256, dwLen) ?
Hm....kurze Frage: Was würde das GetUserObjectInformation bringen?
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:53 Uhr.
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