Windows Dienst erst nach Anmeldung starten
-
Hallo,
ich habe einen Windows Dienst erfolgreich implementiert und dieser macht auch das für dass er entwickelt wurde. Meine Frage ist nun, wenn ich den Dienst mit sc create installiere, und start= auto mache, wird dann der Dienst nach dem erfolgreichen Anmelden beim Betriebssystem gestartet oder zuvor? Denn ich lese direkt am Anfang ein Xml-File aus. Wenn nun der Dienst vor der Anmeldung ausgeführt wird hätte ich somit ein Problem. Gibt es die Möglichkeit den Dienst so zu installieren, dass er erst nach der Anmeldung gestartet wird?
Vielen Dank für eure Mühen,
mr_einsa
-
Müsstest Du glaube ich hier entnehmen können.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms681957(v=vs.85).aspx
-
Es tut mir leid wenn ich mich jetzt dumm anstelle aber würde es reichen wenn ich meinen Service der Gruppe: lpLoadOrderGroup anfüge beim installieren?
-
http://msdn.microsoft.com/en-us/library/windows/desktop/ms681988(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms685155(v=vs.85).aspx
-
Vielen Dank für dien Mühe,
jedoch kann ich aus den Links lediglich herauslesen, dass der Service gestartet wird nachdem einige "wichtigere" Services am laufen sind und das nach einer kleinen Verzögerung. Also ist es nicht sicher wann der Service gestartet wird. Denn wenn vor der Anmeldung alle "wichtigen" Services online sind, wird mein Service aktiviert.
-
Also mal grundsätzlich:
Ein Service hat nichts mit einen "Logon" zu tun.Wenn Du möchtest das ein Dienst dann erst startet, dnan solltest Du ein Programm in die Run-Sektion einbauen, dass diesen Job übernmmt. (Aber pass auf die rechte auf, man ist nicht immer Admin).
Ansonsten, was stört Dich an einem Prozess der auf ewig auf einen Event wartet?
Der kostet weder Rechenzeit, und der wird sogar zu 100% aus dem Speicher geworfen...Ansonsen hast Du auch die Aufgabenplanung seit Vista/Windows 7, mit dem Du das Logon Event ohne blöde "Registry Run" Einträge sauber kontorllieren kannst.
-
Mr_Einsa schrieb:
Denn ich lese direkt am Anfang ein Xml-File aus. Wenn nun der Dienst vor der Anmeldung ausgeführt wird hätte ich somit ein Problem.
Seit wann kann man XML Files nur lesen wenn schon ein User angemeldet ist?
Wenn du Dependencies auf andere Services hast, dann trag die ein. Dann stellt der Service-Control Dingbums sicher dass dein Service erst gestartet wird nach dem die Dependencies bereits laufen, und gestoppt wird bevor die Dependencies gestoppt werden.
-
Vielen Dank für die ganzen Antworten.
Es ist so ich werde in dem Windows Service einen Prozess starten und dies muss natürlich geschehen, wenn jemand bei Windows angemeldet ist. Also gilt es herauszufinden ob jemand sich eingeloggt hat, wenn ja dann muss natürlich mit der arbeit begonnen werden.
-
und dies muss natürlich geschehen, wenn jemand bei Windows angemeldet ist.
Der Clou, bzw. das Wesen eines daemons, aka windows service ist es doch, das man eben ohne explizietes "login" operiert, also unabhaengig ob ueberhaupt und wer angemeldet ist.
Also konkret gibts eben nur 2 anwendungsfaelle fuer einen windows-service:
1. Das Ding muss unabhanegig von User und login laufen ...
2. Du kannst unter moderneren windows-Systemen nicht dauerhaft programme "hochleveln". D.H. alles was du als user startest, laeuft unter user rechten. Du kannst einen prozess hochleveln, das geht aber dann nur manuell, also mit dieser ominoesen DIalogbox. Um das zu verhindern, baut man fuer solche faelle (meist auto-updater die in priviligierte verzeichnisse schreiben wollen) services, die im hintergrund lauern (per IPC mechanismen) und befehle von einem Frontend (user Application) entgegennehmen, und somit den Rechtecontext ohne abfrage quasi aendern koennen.Ist was von einem login abhaengig, ist ein "windows service" die falsche wahl ! Im optimalsten Fall machst Dir einfach nur unnoetig Arbeit.
eine Standard Windows Application (also ohne windows service zeugs) kann man auch programmieren, dass sie auf Windows events hoert und sich sauber bei einem shutdown mit runterfaehrt (sollte eigentlich eh jede App machen). Dann muss man die nur noch automatisch nachm login starten lassen wenn nen user sich anmeldet (gibts mehrere möglichkeiten zu) und schon verhaelt sich das ding wie ein user spezifischer ... aehm daemon isses nun eigentlich nicht mehr ^^ ...
Können tut der windows service nicht mehr ... einzig relevante unterschied ist für dich, das die winapp definitiv im rechte context des Users laeuft, und nicht im context der service / des systems. Wenn damit ein problem hasst, musst dich mit der Rechte philosophie von windows auseinander setzen ... aber auch dafuer gibts loesungen (elevator etc).
Ciao ...
-
Gibt's einen Grund dafür, daß der Prozess vom Service gestartet werden soll? Warum tut's
Startup
bzw.HKLM\Software\Microsoft\CurrentVersion\Run
nicht?
-
Ich glaube auch dass ein Service nicht die richtige Lösung für was auch immer du genau tun willst ist. Wie schon gesagt wurde: Eine der wesentlichen Eigenschaften eines Service ist doch gerade, dass er läuft auch wenn niemand angemeldet ist...
-
Außerdem habe ich auch schon auf den Aufgabenplanungsdienst hingewiesen. Der kann wunderbar bei Logon einen Prozess starten und HKLM/Run!
-
Vielen Dank für die zahlreichen vorschläge. Ich habe es nun hinbekommen, jedoch gibt es noch ein Problem. Und zwar installiere ich den Windows Service mit der SC.exe. Am Anfang dachte ich juhu das klappt ja super aber da die SC.exe auf eine Rückantwort wartet und falls diese nicht kommt den Service abschießt ist dies schlecht für mich. Gibt es eine einfach möglichkeit den Service leicht zu installieren? Denn von .net findet man tausend sachen aber für mich ist da leider nix dabei.
Vielen Dank
-
Kann ich nicht verstehen dass Du nichts gefunden hast... Aber schau mal hier.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683500(v=vs.85).aspx
-
Das benutze ich sogar schon aber klappt auch nicht... kann es vlt. daran liegen dass in meinem service ein extra thread aufgemacht wird, der eine dauerschleife beinhaltet?
-
sc.exe wartet auf gar nix, sc.exe macht einfach nur Einträge in der Registry.
Warten tut der Service-Control-Manager, bei dem muss sich jedes Service melden, sonst ist es kein Service sondern höchstens ein Daemon. Damit wie das Service installiert wird hat das aber nichts zu tun.
Mr_Einsa schrieb:
Es ist so ich werde in dem Windows Service einen Prozess starten und dies muss natürlich geschehen, wenn jemand bei Windows angemeldet ist.
Wieso soll das Service einen Prozess starten wenn ein User angemeldet ist?
Also erstmal kannst du im Service Prozesse starten wann du willst, dazu muss auch kein User angemeldet sein. Die laufen dann halt in einer hübsch unsichtbaren Window-Station.Und wenn du einen Prozess starten willst der mit dem User interagiert ... wieso verwendest du dann überhaupt ein Service?
Bzw. wieso machst du es nicht so wie es alle machen, und machst "Run" Einträge bzw. Task-Scheduler Jobs um den Teil zu starten der mit dem User interagieren will/soll/muss?
Wie im übrigen schon vorgeschlagen wurde.Und was .NET angeht... Öhm. Es gibt sogar nen eigenen Projekttyp für .NET Services, wo der ganze nötige Boilerplate-Code bereits generiert wird. Viel einfacher geht's nicht. Schwer zu finden ist das Template auch nicht, heisst ja bloss "Windows Service".
EDIT: oder meinst du mit dem "für mich ist da nix dabei" dass du kein .NET verwenden kannst/willst? Dann würde ich das Template "ATL Project" mit Option "Service" empfehlen. Dadurch bekommt dein Service zwar automatisch ne COM Schnittstelle verpasst, aber das tut ja nicht wirklich weh. Musst du ja nicht verwenden wenn du nicht willst.
-
Da geb ich dir völlig recht hustbaer. Ich kann kein .net verwenden. Jedoch will ich das Programm als Windows Service starten. Wie kann ich denn dem Service-Control-Manager sagen, dass der Service noch aktiv ist? Es wäre wirklich hilfreich wenn ihr mir das erläutert. Oke also der Service wird gestartet und der Service-Control-Manager wartet meist alle 30sec auf ein "ping" von dem Service, aber wie kann ich ihm diesen "ping" zukommen lassen? Denn ich starte den service mit sc create servicename servicepfad start= auto type= interact type= own ... im service selber komm ich in die Main und stell dort meine ServiceMain ein ... in der ich dann einen Thread starte der in einer Dauerschleife etwas ausließt. ich kapier einfach nicht wie ich dem SCM die Antwort schicke ohne meinen Service zu unterbrechen. Die meisten Services schaffen das ja aber wieso meiner nicht
-
Du solltest dringen lernen Dir Informationen zu beschaffen!
Schau da mal rein. Eigentlich alles was Du wissen musst.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms685967(v=vs.85).aspxUnd Speziell diesen solltest Du mal unter die Lupe nehmen.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687414(v=vs.85).aspx
-
Vielen Dank für deinen Beitrag. Auf den Seiten war ich schon, ich denke ganz einfach dass mein Englisch zu schlecht ist und ich irgendetwas übersehe. Ich hab berreits mehrere Projekte erstellt mit den unterschiedlichsten Ansätzen. Auch deinen geposteten Ansatz habe ich schon vor Tagen genutzt und bin nicht auf das gewünschte Ergebnis gekommen.
Also was ich hier: http://msdn.microsoft.com/en-us/library/windows/desktop/ms687414%28v=vs.85%29.aspx
Entnehme ist, dass ich ich mich zuerst beim ServiceControlHandler Registrieren muss, dann muss ich ihm den derzeitigen ServiceStatus zukommen lassen. Der zuerst SERVICE_START_PENDIN ist, jetzt starte ich mit der Initialisierung... wenn alles gut geht gebe ich dem SCH den SERVICE_RUNNING status. Und jetzt kommt mein Hirngulasch zum einsatz. Und zwar laut dem Beispiel warte ich jetzt so lange, bis der Service den Status annimmt: SERVICE_STOPPED. Und hier denke ich muss innerhalb von 30sec der SCH den status SERVICE_STOPPED erhalten, sonst wird er terminiert.Anhand des zweiten links: http://msdn.microsoft.com/en-us/library/windows/desktop/ms685149%28v=vs.85%29.aspx
habe ich folgenden Text entnommen:The control handler must return within 30 seconds, or the SCM returns an error. If a service must do lengthy processing when the service is executing the control handler, it should create a secondary thread to perform the lengthy processing, and then return from the control handler. This prevents the service from tying up the control dispatcher. For example, when handling the stop request for a service that takes a long time, create another thread to handle the stop process. The control handler should simply call SetServiceStatus with the SERVICE_STOP_PENDING message and return.
Mein Ergebnis: Wenn ich den Service implementiere, und ganz am ende, in meine while-Schleife eintrete, würde es reichen wenn ich ständig alle 5sec einfach nur ReportSvcStatus( SERVICE_RUNNING, NO_ERROR, 0 ); aufrufe. Und so schaffe ich es dass der Service ständig läuft und nicht nach 30sec terminiet wird. Da ich natürlich meine Arbeiten in Threads abarbeite, macht dies meinem Arbeitsfluss nichts aus... lieg ich da richtig?
Zum Beispiel:while(1) { Sleep(5000); ReportSvcStatus( SERVICE_RUNNING, NO_ERROR, 0 ); } return;
-
Du brauchst gar nix periodisch aufrufen.
Die Callback-Funktion über die der SCM dir Steuerkommandos schickt darf bloss nicht zu lange brauchen, das ist das wo die 30 Sekunden herkommen.