019
23.06.2003, 23:10 Uhr
Uwe
C/C++ Master (Administrator)
|
Hallo, mal ein Bsp. welches funktioniert, aber nichts macht :) Install:
C++: |
// Includes #include <windows.h> #include <stdio.h> #include <tchar.h> // Defines #define GENSRV_ServiceName TEXT("TestService") #define GENSRV_DisplayName TEXT("Mein Test Service") // Hauptprogramm int main() { // lokale Variablen vorbereiten SC_HANDLE hSCManager = NULL; SC_HANDLE hService = NULL; TCHAR szWinDir[MAX_PATH]; TCHAR szImagePath[MAX_PATH]; // SCM öffnen if((hSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE)) == NULL) { // Fehler beim Öffnen _tprintf(TEXT("Fehler beim Oeffnen des SCM\n")); // Zurück return ; } // Windows Verzeichnis auslesen GetWindowsDirectory(szWinDir, MAX_PATH); // Namen der Service-Exe ermitteln _stprintf( szImagePath, TEXT("%s\\system32\\%s.exe"), szWinDir, GENSRV_ServiceName); // Service hinzufügen if ((hService = CreateService( hSCManager, GENSRV_ServiceName, GENSRV_DisplayName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, szImagePath, NULL, NULL, NULL, NULL, NULL)) == NULL) { // Hinzügen fehlgeschlagen, Fehler melden _tprintf(TEXT("Hinzufuegen fehlgeschlagen\n")); // Zurück return ; } // Handle zum Service schließen CloseServiceHandle(hService); // Handle zum SCM schließen CloseServiceHandle(hSCManager); // Alles ok _tprintf(TEXT("%s erfolgreich installiert\n"), szImagePath); return 0; }
|
Service:
C++: |
// Includes #include <windows.h> #include <stdio.h> // Defines #define GENSRV_ServiceName TEXT("TestService") #define GENSRV_DisplayName TEXT("Mein Test Service") // Prototypen bool NotifySCM( DWORD in_dwState, DWORD in_dwWin32ExitCode, DWORD in_dwProgress); void ServiceMain(DWORD in_dwArgc, LPTSTR *in_pszArgv); void ServiceHandler(DWORD in_dwControl); WORD MainServiceThread(LPDWORD in_ThreadParam); // globale Variablen HANDLE hDoneEvent = NULL; HANDLE hThread = NULL; DWORD dwCurrentState; SERVICE_STATUS_HANDLE hService; // Hauptprogramm main. Das Hauptprogramm des Dienstes könnte auch // als WinMain erzeugt werden. int main() { // service table entry Struktur definieren SERVICE_TABLE_ENTRY ServiceTable[] = { { GENSRV_ServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain }, { NULL, NULL } }; // Verbindung mit SCR aufbauen StartServiceCtrlDispatcher(ServiceTable); return 0; }
// Initialisierung des Services BOOL ServiceInitialization(DWORD in_dwArg, LPTSTR *in_pszArgv) { // Hier können Initialisierungen durchgeführt werden // ... // Alles OK return (true); }
// Hauptfunktion des Services VOID ServiceMain(DWORD in_dwArgc, LPTSTR *in_pszArgv) { // lokale Variable vorbereiten DWORD ThreadId; // Funktion zum Behandeln von Service Funktionalität registrieren if (!(hService = RegisterServiceCtrlHandler( GENSRV_ServiceName, (LPHANDLER_FUNCTION)ServiceHandler))) { // Fehler, Abbruch return; } // Statusinformationen aktualisieren NotifySCM(SERVICE_START_PENDING, 0, 1); // kann der Service Initialisiert werden? if (!ServiceInitialization(in_dwArgc, in_pszArgv)) { // Fehler, Abbruch return; } // Statusinformationen aktualisieren NotifySCM(SERVICE_START_PENDING, 0, 2); // Ereignis erzeugen if ((hDoneEvent=CreateEvent(NULL,FALSE,FALSE,NULL)) == 0) { // Fehler, Abbruch return; } // Statusinformationen aktualisieren NotifySCM(SERVICE_START_PENDING, 0, 3); // Neuen Thread erzeugen if ((hThread = CreateThread( 0, 0, (LPTHREAD_START_ROUTINE)MainServiceThread, 0, 0, &ThreadId)) == 0) { // Fehler! Ereignis Handle schließen CloseHandle(hDoneEvent); // zurück return; } // Statusinformationen aktualisieren NotifySCM(SERVICE_RUNNING, 0, 0); // Warten, bis der Service beendet wurde WaitForSingleObject(hDoneEvent, INFINITE); // Threadhandle schließen CloseHandle(hThread); // Thread beenden ExitThread(ThreadId); // Ereignis-Handle schließen CloseHandle(hDoneEvent); // Alles OK, zurück return 0; }
// Statusübertragung bool NotifySCM( DWORD in_dwState, DWORD in_dwWin32ExitCode, DWORD in_dwProgress) { // SERVICE_STATUS Struktur deklarieren SERVICE_STATUS ServiceStatus; // Werte in Struktur eintragen ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ServiceStatus.dwCurrentState = dwCurrentState = in_dwState; ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN; ServiceStatus.dwWin32ExitCode = in_dwWin32ExitCode; ServiceStatus.dwServiceSpecificExitCode = 0; ServiceStatus.dwCheckPoint = in_dwProgress; ServiceStatus.dwWaitHint = 3000; // Status übermitteln return (SetServiceStatus(hService, &ServiceStatus)); }
// Thread-Hauptfunktion WORD MainServiceThread(LPDWORD ThreadParam) { // Wiederholen, solange der Service läuft while (TRUE) { // Eine Minute warten Sleep(60000); // Datei öffnen FILE *pFile = fopen("c:\\testfile.zip","rb"); // Konnte die Datei geöffnet werden? if (pFile != NULL) { // Ausgabedatei vorbereiten FILE *pOutputFile = fopen("c:\\backup.zip","w+b"); // Buffer anlegen byte Buffer[1024]; // Anzahl der bislang eingelesenen Bytes speichern int nBytesRead=-1; // Gesamtes File auslesen while (!feof(pFile)) { // Jeweils 1024 Bytes einlesen int nBytesRead=fread(Buffer, 1, 1024, pFile); // Hat alles geklappt? if ((nBytesRead!=0) && (!ferror(pFile))) { // Daten in Ausgabedatei speichern fwrite(Buffer, 1, nBytesRead, pOutputFile); if (ferror(pOutputFile)) { // Signal ausgeben MessageBeep(MB_ICONASTERISK); // Kopiervorgang abbrechen break; } } else { // Signal ausgeben MessageBeep(MB_ICONASTERISK); // Kopiervorgang abbrechen break; } } } else { // Signal ausgeben MessageBeep(MB_ICONASTERISK); } } }
// Terminierung des Services void ServiceTermination() { // Hier können abschließende Aufräumarbeiten durchgeführt werden }
// Nachrichtenbehandlung des Services void ServiceHandler(DWORD in_dwControl) { switch(in_dwControl) { case SERVICE_CONTROL_STOP: { // Statusinformationen aktualisieren NotifySCM(SERVICE_STOP_PENDING, 0, 1); // Ereignis signalisieren SetEvent(hDoneEvent); // Statusinformationen aktualisieren NotifySCM(SERVICE_STOPPED, 0, 0); break; } case SERVICE_CONTROL_PAUSE: { // Statusinformationen aktualisieren NotifySCM(SERVICE_PAUSE_PENDING, 0, 1); // Thread pausieren SuspendThread(hThread); // Statusinformationen aktualisieren NotifySCM(SERVICE_PAUSED, 0, 0); break; } case SERVICE_CONTROL_CONTINUE: { // Statusinformationen aktualisieren NotifySCM(SERVICE_CONTINUE_PENDING, 0, 1); // Thread wieder starten ResumeThread(hThread); // Statusinformationen aktualisieren NotifySCM(SERVICE_RUNNING, 0, 0); break; } case SERVICE_CONTROL_INTERROGATE: { // Statusinformationen aktualisieren NotifySCM(dwCurrentState, 0, 0); break; } case SERVICE_CONTROL_SHUTDOWN: { // Service beenden ServiceTermination(); break; } } }
|
De-Install:
C++: |
// Includes #include <windows.h> #include <stdio.h> #include <tchar.h> // Defines #define GENSRV_ServiceName TEXT("TestService") #define GENSRV_DisplayName TEXT("Mein Test Service") // Hauptprogramm int main() { // lokale Variablen vorbereiten SC_HANDLE hSCManager = NULL; SC_HANDLE hService = NULL; // SCM öffnen if((hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE)) == NULL) { // Fehler beim Öffnen _tprintf(TEXT("Fehler beim Oeffnen des SCM\n")); // Zurück return; } if (!(hService = OpenService(hSCManager, GENSRV_ServiceName, STANDARD_RIGHTS_REQUIRED))) { // Fehler melden _tprintf(TEXT("Oeffnen des Services fehlgeschlagen!")); // zurück return; } if (!DeleteService(hService)) { // Fehler melden _tprintf(TEXT("Fehler beim Deinstallieren")); // return return; } // Handle zum Service schließen CloseServiceHandle(hService); // Handle zum SCM schließen CloseServiceHandle(hSCManager); // Alles ok _tprintf(TEXT("Service erfolgreich deinstalliert\n")); return 0; }
|
-- "Es ist schwierig, ein Programm wirklich idiotensicher zu machen, weil Idioten so genial sind."
Bis dann... Uwe Dieser Post wurde am 24.06.2003 um 07:33 Uhr von Uwe editiert. |