C# Windowsdienst erstellt keine Screenshots

Fou-Lu

Lt. Junior Grade
Registriert
Aug. 2006
Beiträge
290
Hallo,
bin gerade an einem Service (probeweise) dran und hab nen kleinen Test gemacht ob ich dann Screenshots erstellen kann.

Jetzt ist mir jedoch aufgefallen, dass meine Funktion in einer Forms anwendung ohne Probleme die Screenshots erstellt und speichert, aber als Service nicht.

Hier erstmal die Funktion:
PHP:
private void Screenshots() {
	try {
		string path = "C:\\test\\service\\";

		for (int i = 0; i < 100; i++) {
			Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
					Screen.PrimaryScreen.Bounds.Height);

			Graphics g = Graphics.FromImage(bmp);
			g.CopyFromScreen(0, 0, 0, 0, bmp.Size);
			g.Flush();
			g.Dispose();

			bmp.Save(path + "image" + i + ".jpg");
		}
	} catch (Exception ex) {
		EventLog.WriteEntry(ex.Message);
	}
}

Die Funktion hab ich selbstverständlich in einem eigenen Thread gestartet und wie gesagt... als Forms-Anwendung läuft alles reibungslos, aber als Service spuckt es mir an der Stelle "g.CopyFromScreen(0, 0, 0, 0, bmp.Size);" eine Exception rauß.

Die Exception die da in den Eventlog eingetragen wird ist folgende:
Das Handle ist ungültig.

Habe auch viel probiert und lange gebraucht um heraus zu finden dass es exakt diese Zeile ist.

Hat vielleicht jemand ne Idee wieso das so ist und was man dagegen tun könnte?
 
Ein Service läuft auch auf seinem eigenen Desktop ;)

Du kannst nur mit Windows Funktionen probieren das ganze in einem Service zum laufen zu bekommen - viel Hoffnung sehe ich da nicht gerade!

Vielleicht solltest du eher eine Tray-Application machen
 
Oh mist... klingt nicht so toll... -_-"

Ne sollte schon ein Service sein, es soll nämlich auch funktionieren, wenn der User gerade nicht angemeldet ist. Ist jetzt auch nicht nur auf Screenshots beschränkt, wird noch paar weitere funktionen haben.

Aber wie gesagt, muss als Service laufen :-/
 
Du kannst ja einen extra Prozess erstellen der beim Logon in der Session des aktuellen Users startet, bei Bedarf Screenshots macht und dann mit dem Service kommuniziert.
 
Hmm... naja gut aber das würde ja dann auch nur funktionieren, wenn sich ein Benutzer anmeldet. Aber was wenn der PC einfach nur eingeschaltet wird, oder es ein Server ist man einfach den Screen entweder sperrt oder der User sich abmeldet??!

Mir fällt grad ein, dass man den TeamViewer und VNC ja auch als Service installieren kann, aber die schaffen es ja dann dennoch die Screenshots zu schießen. RDP ebenfalls.

Hat jemand ne Idee wie es bei diesen Programmen dann funktioniert oder so?
 
Viele VNC-Varianten sind opensource. Einfach mal im Code reinschauen, wie sie das machen. ;)
 
Klick mal im MMC-SnapIn deinen Dienst doppelt an und aktiviere die Checkbox "Datenaustausch zwischen Dienst und Desktop zulassen" auf der "Anmelden" Registerkarte.

Das sollte ermöglichen von der Windows-API entsprechende Handles zu erhalten.
 
@MacGyver: Tatsächlich... jetzt funktioniert es. Vielen Dank, hatte das selbe Problem wie Fou-Lu :D

Hmm... aber hätte noch eine Frage bezüglich dessen. Gibt es auch eine Möglichkeit diese Checkbox auch automatisch irgendwie bei der Installation zu aktivieren oder so? Oder Irgendwo im Code vom Dienst?

Wäre echt super, wenns möglich wäre ;)


EDIT:
Es funktioniert wenn der User angemeldet ist und der Dienst dann erst startet. Wenn ich jedoch den PC neustarte und der Dienst startet mit obwohl der User nicht angemeldet ist, dann läuft da nichts.... habs eigentlich gleich vermutet, dass es so nicht funktionieren wird.

Hoffentlich find ich da noch ne Möglichkeit ohne irgendwie auf DirectX oder sowas zurückgreifen zu müssen :D

Wenn jemand Tipps oder Vorschläge hat, dann gern her damit ;) :D
Bin über jede Hilfe erfreut :)
 
Zuletzt bearbeitet:
@MacGyver: Danke für den Tipp. ;-)

@Zhen: Falls du ne Lösung findest für das Problem mit dem Anmeldebildschirm, dann wäre ich dankbar wenn du sie mit mir teilen würdest :P

An sonsten hab ich mir den Code von RealVNC angeguckt und (noch blick ich zwar nicht ganz durch, ist ja auch C++ - hab damit eher wenig zu tun), aber was ich mitbekommen habe benutzen die wohl irgendwie die Funktionen "GetThreadDesktop, SetThreadDesktop und OpenInputDesktop".

Werde mich mal über diese Funktionen erkundigen und hoffe, dass die mich weiterbringen ^^
 
Zhen schrieb:
Hmm... aber hätte noch eine Frage bezüglich dessen. Gibt es auch eine Möglichkeit diese Checkbox auch automatisch irgendwie bei der Installation zu aktivieren oder so? Oder Irgendwo im Code vom Dienst?

Ja, das geht.

Man geht in der Registry in HKLM\CurrentControlSet\Services\[Name des eigenen Services]

Dort ändert man den DWORD-Wert "Type" auf 0x120 (Dezimal: 288). Das kann man im Installer machen, den man ja für die Installation und Registrierung von Diensten braucht.
 
MacGyver schrieb:
Klick mal im MMC-SnapIn deinen Dienst doppelt an und aktiviere die Checkbox "Datenaustausch zwischen Dienst und Desktop zulassen" auf der "Anmelden" Registerkarte.

Das sollte ermöglichen von der Windows-API entsprechende Handles zu erhalten.

Aua ;) Mehr muss man dazu nicht sagen.

http://asprosys.blogspot.de/2009/03/allow-service-to-interact-with-desktop.html
http://blogs.technet.com/b/voy/arch...n-0-of-windows-vista-and-longhorn-server.aspx

Abgesehen von dem riesigen Sicherheitsloch, dass du in das System reißt, wirst du so nur Zugriff auf Session 0 kriegen.
Was du eigentlich benutzen möchtest ist die Remote Desktop Services API (früher Terminal Services), kurz WTSAPI.
 
holy schrieb:
Aua ;) Mehr muss man dazu nicht sagen.

http://asprosys.blogspot.de/2009/03/allow-service-to-interact-with-desktop.html
http://blogs.technet.com/b/voy/arch...n-0-of-windows-vista-and-longhorn-server.aspx

Abgesehen von dem riesigen Sicherheitsloch, dass du in das System reißt, wirst du so nur Zugriff auf Session 0 kriegen.
Was du eigentlich benutzen möchtest ist die Remote Desktop Services API (früher Terminal Services), kurz WTSAPI.

Oh nein. Wir werden alls sterben, weil ein Dienst ohne Interaktionen nach außen mit dem Desktop kommunizieren kann. [/sarkasmus]

PS: Ich möchte gar nichts benutzen. Ich antworte lediglcih auf Problemanfragen. Würde nie auf die Idee kommen nen Dienst zu programmieren der Screenshots macht, weil das für mich total unnütz ist. Aber wenns jemand machen möchte, kann er das so lösen, oder eben auch anders.
 
MacGyver schrieb:
Oh nein. Wir werden alls sterben, weil ein Dienst ohne Interaktionen nach außen mit dem Desktop kommunizieren kann. [/sarkasmus]

Das ist eine ziemlich naive Aussage. Jedes billige Toolkit kommt mit einem Service-HiJacker daher, um genau von solchen, schlampig geschriebenen Diensten die System-Rechte abzufarmen. Die Session 0 Isolation hilft da auch nichts mehr, macht es höchtens ein wenig komplizierter (1 Exploit mehr).

Besorg dir, falls du überhaupt Interesse daran hast, Metasploit oder eine andere Testsuite deiner Wahl und überzeug dich selbst ^^

MacGyver schrieb:
PS: Ich möchte gar nichts benutzen. Ich antworte lediglcih auf Problemanfragen.

Oh, I'm sorry. Sollte wohl heißen, was der TE benutzen möchte, nicht du.
 
MacGyver schrieb:
Würde nie auf die Idee kommen nen Dienst zu programmieren der Screenshots macht, weil das für mich total unnütz ist.

Also ich kann zwar natürlich nur für mich sprechen, aber wieso sollte es sinnlos sein?

Ich persönlich brauche es z.B. für meine Fernwartung. Die funktioniert mittlerweile auch soweit, aber es wäre super wenn ich die auch noch als Dienst installieren könnte.


Und an sonsten gebe es da bestimmt noch andere Einsatzbereiche, was mir da noch einfallen würde wären Malware und solche Sachen (wobei ich in diesem Punkt wohl eher auf C++ und nicht .NET setzen würde) :D :D :D
 
@holy: Danke für die Info, dass es ne gigantische Sicherheitslücke ist :)

Habe mich nun da bisschen reingelesen bei deinen Links.
Diese Option soll es seit Vista ja gar nicht mehr geben :rolleyes:
 
Fou-Lu schrieb:
Diese Option soll es seit Vista ja gar nicht mehr geben :rolleyes:

Ja, das ist so eine Sache. Microsoft nimmt es nicht so genau mit Ankündigungen und geplanten Umsetzungen. Heute so, morgen so. Die Option gibt es in Windows 8 übrigens auch noch ;) Ob sie allerdings funktioniert, keine Ahnung.
 
holy schrieb:
um genau von solchen, schlampig geschriebenen Diensten die System-Rechte abzufarmen.

Wer sagt dir denn dass der Dienst schlampig geschrieben ist? Es gibt auch Möglichkeiten Dienste "gut" zu schreiben. Gerade mit Hilfe von .NET :cool_alt:
Ergänzung ()

Zhen schrieb:
Ich persönlich brauche es z.B. für meine Fernwartung. Die funktioniert mittlerweile auch soweit, aber es wäre super wenn ich die auch noch als Dienst installieren könnte.

Fernwartung macht man aber nicht über Screenshotfunktionen. Dafür gibts andere APIs.
 
@MacGyver: und die APIs wären? DirectX? OpenGL?

Die Screenshots erschienen mir als nur logisch und einfach. Ich mach nen Screen und prüfe diesen auf Änderungen mit dem vorherigen Screenshot. Übermittelt werden nur die Änderungen. Mit welcher anderen API willst du den sowas machen? Ich denke TeamViewer hat bestimmt den selben Ansatz in diesem Bereich.


@Erdmännchen: na vom Anmeldebildschirm? Das ist es ja, ich will wissen ob es überhaupt möglich ist unter anderem. Ich will auf TeamViewer und RemoteDesktop sowie VNC GÄNZLICH verzichten. Wenn ich schon eine eigene Software nutze, dann komplett in in diesem Bereich.

Ich habe keine Lust für normale Fernwartung z.B. mein Tool zu benutzen, aber NUR wegen dem Anmeldebildschirm, z.B. weil ich den PC gerade per WoL gestartet habe, auf alternative Lösungen wie Remote Desktop ausweichen zu MÜSSEN.
 
omg wofür gibts denn RDP?

Nen Dienst, der Screenshots von nem Idle-Server erstellt... oder um zu prüfen, ob er schon bereit ist zur Anmeldung... aha... hm, ich denk da gibts bessere möglichkeiten, als ein Screenshot zu machen lass dir doch einfach ne Mail schicken, wenn er hochgefahren ist z.B.
 
Zurück
Oben