FinalFantasy Geschrieben 19. Januar 2004 Geschrieben 19. Januar 2004 Hallo, wie kann ich einen Service schreiben? Also eigentlich ein kleines Programm, dass komplett im Hintergrund läuft. Es soll von dem Programm nichts sichtbar sein, also keine Oberfläche. Wenn man den Prozess im Taskmanager sieht, macht das allerdings nichts. Ein kleines Beispiel würde mir schon sehr helfen. Das wichtigeste ist halt, dass man keine Oberfläche sieht, also auch keine Dosbox oder so. Achja, es soll wirklich so laufen, also bitte nicht mit irgendwelchen Hilfsprogrammen wie AppToService oder so. Die helfen mir nichts. Zitieren
Klotzkopp Geschrieben 19. Januar 2004 Geschrieben 19. Januar 2004 Dazu brauchst du im Prinzip keinen Dienst. Eine einfache Windowsanwendung, die kein Fenster erstellt, ist nur im Taskmanager zu sehen. Das Problem daran ist nur: Solange du keine andere Möglichkeit einbaust, kann so eine Anwendung auch nur über den Taskmanager beendet werden, und beim Herunterfahren kommt die bekannte Meldung "Anwendung reagiert nicht". Mit einem Dienst geht das besser. Darüber hinaus kann ein Dienst auch laufen, wenn kein Benutzer angemeldet ist. Allerdings sind Dienste ein wenig komplizierter. Siehe dazu MSDN Library: http://msdn.microsoft.com/library/en-us/dllproc/base/services.asp Zitieren
FinalFantasy Geschrieben 19. Januar 2004 Autor Geschrieben 19. Januar 2004 Achso, hm. Ja, das mit keinem Fenster ist in MFC nicht so einfach. Mit direkter WinAPI ginge das vielleicht, hab ich noch nicht probiert. Das Programm soll eigentlich eh nur laufen, wenn jemand angemeldet ist, aber die "Programm reagiert nicht"-Meldung ist dann doch störend. Ich schau mal deinem Link nach. Danke für die schnelle Antwort. Zitieren
HELLmut Geschrieben 19. Januar 2004 Geschrieben 19. Januar 2004 Original geschrieben von FinalFantasy Achso, hm. Ja, das mit keinem Fenster ist in MFC nicht so einfach. Mit direkter WinAPI ginge das vielleicht, hab ich noch nicht probiert. Das Programm soll eigentlich eh nur laufen, wenn jemand angemeldet ist, aber die "Programm reagiert nicht"-Meldung ist dann doch störend. Ich schau mal deinem Link nach. Danke für die schnelle Antwort. Am Rande: Ist kein Problem ne MFC Anwendung ohne Fenster zu schreiben. Zitieren
FinalFantasy Geschrieben 19. Januar 2004 Autor Geschrieben 19. Januar 2004 Habs mir schon ein bischen angeschaut. Service is vielleicht doch etwas kompliziert. An welcher Stelle muss ich denn in MFC das Fenster verstecken? Zitieren
Klotzkopp Geschrieben 19. Januar 2004 Geschrieben 19. Januar 2004 Du brauchst nichts zu verstecken. Du musst nur in der InitInstance-Methode deiner von CWinApp abgeleiteten Klasse einfach kein Fenster erstellen. Zitieren
FinalFantasy Geschrieben 20. Januar 2004 Autor Geschrieben 20. Januar 2004 Ok, stimmt. Aber da krieg ich wirklich ne "Anwendung reagiert nicht" Fehlermeldung beim Runterfahren, und das stört schon. Ausserdem kann ich so nicht in den EventLog schreiben, oder? Hat nicht zufällig jemand ein Gerüsst für nen Service? Da braucht ja nichts ausprogrammiert sein drin. Hab den Beitrag ind der MSDN auch gelesen, das Beispiel kompiliert bei mir sogar, allerdings wird der Service nicht gestartet, wenn ich das Ausführe. Zitieren
Klotzkopp Geschrieben 20. Januar 2004 Geschrieben 20. Januar 2004 Original geschrieben von FinalFantasy Ausserdem kann ich so nicht in den EventLog schreiben, oder? Warum solltest du das nicht können? Hab den Beitrag ind der MSDN auch gelesen, das Beispiel kompiliert bei mir sogar, allerdings wird der Service nicht gestartet, wenn ich das Ausführe. Einen Service startet man auch nicht so. Dienste werden vom Dienstmanager gestartetet und beendet. Wenn ich mich richtig an das MSDN-Beispiel erinnere, musste man es mit einem bestimmten Parameter starten, damit der Dienst beim Dienstmanager eingetragen wird. Der übernimmt den Rest. Zitieren
FinalFantasy Geschrieben 20. Januar 2004 Autor Geschrieben 20. Januar 2004 Hier ist das Beispiel: #include <windows.h> #include <stdio.h> SERVICE_STATUS MyServiceStatus; SERVICE_STATUS_HANDLE MyServiceStatusHandle; VOID SvcDebugOut(LPSTR String, DWORD Status); VOID WINAPI MyServiceStart (DWORD argc, LPTSTR *argv); VOID WINAPI MyServiceCtrlHandler (DWORD opcode); DWORD MyServiceInitialization (DWORD argc, LPTSTR *argv, DWORD *specificError); void main( ) { SERVICE_TABLE_ENTRY DispatchTable[] = { { "MyService", MyServiceStart }, { NULL, NULL } }; if (!StartServiceCtrlDispatcher( DispatchTable)) { SvcDebugOut(" [MY_SERVICE] StartServiceCtrlDispatcher error = %d\n", GetLastError()); } } VOID SvcDebugOut(LPSTR String, DWORD Status) { CHAR Buffer[1024]; if (strlen(String) < 1000) { sprintf(Buffer, String, Status); OutputDebugStringA(Buffer); } } void WINAPI MyServiceStart (DWORD argc, LPTSTR *argv) { DWORD status; DWORD specificError; MyServiceStatus.dwServiceType = SERVICE_WIN32; MyServiceStatus.dwCurrentState = SERVICE_START_PENDING; MyServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE; MyServiceStatus.dwWin32ExitCode = 0; MyServiceStatus.dwServiceSpecificExitCode = 0; MyServiceStatus.dwCheckPoint = 0; MyServiceStatus.dwWaitHint = 0; MyServiceStatusHandle = RegisterServiceCtrlHandler( "MyService", MyServiceCtrlHandler); if (MyServiceStatusHandle == (SERVICE_STATUS_HANDLE)0) { SvcDebugOut(" [MY_SERVICE] RegisterServiceCtrlHandler failed %d\n", GetLastError()); return; } // Initialization code goes here. status = MyServiceInitialization(argc,argv, &specificError); // Handle error condition if (status != NO_ERROR) { MyServiceStatus.dwCurrentState = SERVICE_STOPPED; MyServiceStatus.dwCheckPoint = 0; MyServiceStatus.dwWaitHint = 0; MyServiceStatus.dwWin32ExitCode = status; MyServiceStatus.dwServiceSpecificExitCode = specificError; SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus); return; } // Initialization complete - report running status. MyServiceStatus.dwCurrentState = SERVICE_RUNNING; MyServiceStatus.dwCheckPoint = 0; MyServiceStatus.dwWaitHint = 0; if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus)) { status = GetLastError(); SvcDebugOut(" [MY_SERVICE] SetServiceStatus error%ld\n",status); } // This is where the service does its work. SvcDebugOut(" [MY_SERVICE] Returning the Main Thread \n",0); return; } VOID WINAPI MyServiceCtrlHandler (DWORD Opcode) { DWORD status; switch(Opcode) { case SERVICE_CONTROL_PAUSE: // Do whatever it takes to pause here. MyServiceStatus.dwCurrentState = SERVICE_PAUSED; break; case SERVICE_CONTROL_CONTINUE: // Do whatever it takes to continue here. MyServiceStatus.dwCurrentState = SERVICE_RUNNING; break; case SERVICE_CONTROL_STOP: // Do whatever it takes to stop here. MyServiceStatus.dwWin32ExitCode = 0; MyServiceStatus.dwCurrentState = SERVICE_STOPPED; MyServiceStatus.dwCheckPoint = 0; MyServiceStatus.dwWaitHint = 0; if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus)) { status = GetLastError(); SvcDebugOut(" [MY_SERVICE] SetServiceStatus error %ld\n",status); } SvcDebugOut(" [MY_SERVICE] Leaving MyService \n",0); return; case SERVICE_CONTROL_INTERROGATE: // Fall through to send current status. break; default: SvcDebugOut(" [MY_SERVICE] Unrecognized opcode %ld\n", Opcode); } // Send current status. if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus)) { status = GetLastError(); SvcDebugOut(" [MY_SERVICE] SetServiceStatus error %ld\n",status); } return; } DWORD MyServiceInitialization(DWORD argc, LPTSTR *argv, DWORD *specificError) { argv; argc; specificError; return(0); } [/PHP] wie man sieht, übernimmt die Main-Funktion nichtmal Argumente. Was für ein Argument solltes dass dann sein? Muss ich das vielleicht als ein bestimmtes Projekt anlegen? Oder irgendwo das Programm eintragen?? (Services unter Wind2k-Administrative Tools....) Zitieren
Guybrush Threepwood Geschrieben 21. Januar 2004 Geschrieben 21. Januar 2004 Alos ich hab nur mal kurz drüber geguckt, aber soweit ich das sehe legt das Programm keinen neuen Service an. Zitieren
FinalFantasy Geschrieben 21. Januar 2004 Autor Geschrieben 21. Januar 2004 Steht aber als Beispiel so in der MSDN. Ich kanns ja nicht, und wills mir lernen, also wie muss ich es machen?? Zitieren
Pointerman Geschrieben 21. Januar 2004 Geschrieben 21. Januar 2004 @Final Fantasy Ich habe noch nicht mit C++/MFC gearbeitet, aber schon mit Delphi einen kleinen Dienst geschrieben. Damit der Dienst in der Systemsteuerung/Dienste erscheint, musste man da in der Eingabeaufforderung das programm mit /install aufrufen (z.B. "Dienst.exe/install") . Danach konnte man den Dienst entweder in der Eingabeaufforderung mit "net start Dienst" oder in der Systemsteuerung/dienste starten. Müsste ja mit C++/MFC genauso sein. Zitieren
FinalFantasy Geschrieben 21. Januar 2004 Autor Geschrieben 21. Januar 2004 Ja, das ist mir schon bekannt. Die Frage ist nur: Wie programmier ich das? Dass der Dienst mit /install auch angemeldet wird, dass der Dienst auf net start service auch startet..... Zitieren
Klotzkopp Geschrieben 21. Januar 2004 Geschrieben 21. Januar 2004 @FinalFantasy: Was du da hast, ist der reine Dienst, ohne Installationsfunktionalität. Ich hatte da wohl ein anderes Beispiel in Erinnerung. Du musst diesen Dienst noch registrieren, damit du ihn starten kannst. Wie das geht, findest du hier. Zitieren
FinalFantasy Geschrieben 21. Januar 2004 Autor Geschrieben 21. Januar 2004 Ah, das war genau der Punkt, der mir gefehlt hat. Danke schonmal, soweit läufts jetzt. Jetzt muss ich noch rausfinden, wie ich EventLog-Einträge schreibe, aber ich schau erstmal, ob ich das selber rausbringe. Danke schonmal. Zitieren
FinalFantasy Geschrieben 21. Januar 2004 Autor Geschrieben 21. Januar 2004 Ok, für alles was ich bis jetzt als EventLog gefunden hab, muss man eine Ressource anlegen, diese seperat compilieren, und dann erst immer laden.... Gibts nicht ne Möglichkeit, da einfach nur einen String reinzuschreiben?? Eine Messagebox kann man auch nicht anzeigen, aus einem Service raus, oder? Weil der Bezug zu nem Fenster/Desktop fehlt. Naja, irgendwie muss es ja gehen... hm..... Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.