Screenshot aus einem Service heraus unter WinXP, Vista + Win7
-
Hallo,
habe einen Dienst erstellt, der u.a. einen Screenshot vom Desktop macht. Leider funktioniert dies nur unter WinXP. Unter Vista oder Windows7 ergibt der Screenshot lediglich ein weißes Bild. Wohl deshalb, da der Screenshot nicht in der Session gemacht wird, in der der angemeldete User gerade arbeitet.
Was müsste ich hier ändern, damit dies auch bei Vista... klappt?HWND hWnd = GetDesktopWindow(); HDC dc = GetDC(hWnd); TJPEGImage *pJPG_Bild = new TJPEGImage(); Graphics::TCanvas *ScreenCanvas = new Graphics::TCanvas(); ScreenCanvas->Handle = dc; Form1->Screenshot->AutoSize = true; Form1->Screenshot->Center = true; Form1->Screenshot->Top = 0; Form1->Screenshot->Left = 0; Form1->Screenshot->Picture->Bitmap->Width = Screen->Width; Form1->Screenshot->Picture->Bitmap->Height= Screen->Height; TRect rect = Rect(0,0,Screen->Width, Screen->Height); //Screenshot ist hier ein Bitmap (noch kein jpg!) Form1->Screenshot->Picture->Bitmap->Canvas->CopyRect(rect, ScreenCanvas, rect); ReleaseDC(NULL,dc); delete ScreenCanvas; //Objekt löschen und Speicher wieder frei geben delete hWnd;Vielen Dank schon mal!
-
Hat denn jemand eine Idee?
-
Habe den Code nun so stehen, funzt aber immer noch nur unter WinXP. Unter Win7 passiert gar nichts, noch nicht einmal ein weißes Bild erscheint:
//zunächst die WindowStation öffnen, mit der der angemeldete User gerade interagiert... HWINSTA m_hWinsta = OpenWindowStation("winsta0", false, WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS | WINSTA_CREATEDESKTOP | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_EXITWINDOWS | WINSTA_READATTRIBUTES | WINSTA_READSCREEN | WINSTA_WRITEATTRIBUTES); //... und auf diese Window Station dann wechseln: if (m_hWinsta != NULL) SetProcessWindowStation(m_hWinsta); //aktueller User-Desktop öffnen HDESK m_hDesk = OpenInputDesktop(0, false, GENERIC_READ); HDC dc = GetDC(m_hDesk); TJPEGImage *pJPG_Bild = new TJPEGImage(); Graphics::TCanvas *ScreenCanvas = new Graphics::TCanvas(); ScreenCanvas->Handle = dc; Form1->Screenshot->AutoSize = true; Form1->Screenshot->Center = true; Form1->Screenshot->Top = 0; Form1->Screenshot->Left = 0; Form1->Screenshot->Picture->Bitmap->Width = Screen->Width; Form1->Screenshot->Picture->Bitmap->Height= Screen->Height; TRect rect = Rect(0,0,Screen->Width, Screen->Height); //Screenshot ist hier ein Bitmap (noch kein jpg!) Form1->Screenshot->Picture->Bitmap->Canvas->CopyRect(rect, ScreenCanvas, rect); ReleaseDC(NULL,dc); delete ScreenCanvas; //Objekte löschen und Speicher wieder frei geben CloseDesktop(m_hDesk); CloseWindowStation(m_hWinsta);Bitte um Hilfe, Danke!
-
Halloooooooooooo,
hat niemand eine Idee ????????????
-
Such mal nach: Service Session Isolation Vista / Windows 7
Und les DIch mal durch... dann wirst Du die Frage selber beantworten können...
-
Das war mir soweit schon bewusst. Das heißt also, dass ich auf jeden Fall eine eigenständige Anwendung zur Durchführung des Screenshots erstellen muss, welche vom Dienst aus aufgerufen wird?
Dann wäre die Aussage "Du musst also von Window Station "WinSta0" auf "default" wechseln, um auf die "normalen" Anwendungsfester und den Eingabedesktop zugreifen zu können. " von While(true){} unter http://www.c-plusplus.net/forum/viewtopic-var-t-is-264326-and-highlight-is-window+station.html aber wohl nicht korrekt.
-
Das war bis XP korrekt... oder funktioniert es unter XP bei Dir nicht?
-
Klar, unter XP einwandfrei.
Dann werde ich das jetzt einmal angehen.
Und den Screenshot kann ich dann via InterProcess-Kommunikation an den Dienst zurückgeben.
Oder gibt es einen einfacheren Weg, meinen Screenshot (Form1->Screenshot->Picture) dem Dienst (Dienst->Screenshot->Picture) zu übergeben?
-
Man könnte das Bild ja auch mit SetClipboardData über das Clipboard übergeben.
Mein Code hierzu funktioniert leider nicht:
Zunächst soll das Bitmap als jpg-Bild in die Zwischenablage:TJPEGImage *pJPG_Bild = new TJPEGImage(); unsigned int DataHandle; HPALETTE APalette; unsigned short MyFormat; ... pJPG_Bild->Assign(Form1->Screenshot->Picture->Bitmap); pJPG_Bild->CompressionQuality = 50; try { OpenClipboard(NULL); //Zwischenablage öffnen EmptyClipboard(); //Inhalt der Zwischenablage löschen // Zwischenablageformat mit Daten und Palette generieren: pJPG_Bild->SaveToClipboardFormat(MyFormat,DataHandle,APalette); // Daten in der Zwischenablage unter Verwendung des Formats und der // generierten Daten speichern: Clipboard()->SetAsHandle(MyFormat,DataHandle); CloseClipboard(); } catch(...) { }Das Herausholen aus der Zwischenablage soll so laufen:
TJPEGImage *pJPG_Bild2 = new TJPEGImage(); unsigned int DataHandle2; HPALETTE APalette; unsigned short MyFormat; try { OpenClipboard(NULL); DataHandle2 = Clipboard()->GetAsHandle(MyFormat); pJPG_Bild2->LoadFromClipboardFormat(MyFormat,DataHandle2,APalette); pJPG_Bild2->SaveToFile("c:\\screenshot.jpg"); //falls der screenshot gespeichert werden soll CloseClipboard(); } catch(...) { }An den Stellen "Clipboard()->SetAsHandle" und "Clipboard()->GetAsHandle" ergibt sich die Fehlermeldung "Zwischenablage kann nicht geöffnet werden".
Was ist falsch?
Das Programm soll übrigens unter WinXP,Vista und Win7 laufen!
DANKE!!
-
Das Clipboard ist abhängig von der Session...
-
Heißt also, ich muss beim Herausholen des Bildes aus dem Clipboard die Session, in der die externe Anwendung den Screenshot ins Clipboard kopiert hat, übergeben?
Oha, wie kann ich das denn machen?
-
Nein! Du nimmst am Besten die ganzen Daten aus dem Clipboard und transferierst diese an den Service. Ich wüsste keinen Weg mit irgendeinem Trick auf das Clipboard aus einem Service zuzugreifen.
Alles was Du hier machst ohne Modul im User-Bereich zu machen ist letzten Endes viel zu kompliziert und aufwendig.
Bau eine User und eine Service Komponente und gut ists.
-
Das habe ich ja bereits gemacht: den Service und eine eigenständige Anwendung, die durch den Service gestartet wird u. die den Screenshot macht.
Aber wie übertrage ich den Screenshot (pJPG_Bild->Assign(Form1->Screenshot->Picture->Bitmap);
pJPG_Bild->CompressionQuality = 50;) als dieses jpg-Bild nun an den Service, damit dieser mit dem Bild weiterarbeiten kann?
-
IPC?
Shared Memory, Memory Mapped File, TCP/IP, als pure Datei...