一个用 c 语言写的 windows 服务程序,代码来自 codeproject,做了一些简化。 main.c #include "TestService.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) { strcpy( g_lpszCmdLine, lpCmdLine ); service_main_proc(); return 0; } TestService.h #ifndef __TestService_h__ #define __TestService_h__ #include <Windows.h> #include <tchar.h> #define SERVICE_NAME_W _T("TestService") #define SERVICE_NAME_A "TestService" #define LOG_FILE_NAME "TestService.log" void service_main_proc (); extern char g_lpszCmdLine[MAX_PATH]; #endif // __TestService_h__ TestService.c #include <stdio.h> #include <process.h> #include "TestService.h" void WINAPI service_main (); void WINAPI service_handler ( DWORD dwCtrl ); char g_lpszCmdLine[MAX_PATH] = { 0 }; SERVICE_STATUS_HANDLE g_hss = NULL; SERVICE_STATUS g_ss = { 0 }; SERVICE_TABLE_ENTRY g_ste[] = { { SERVICE_NAME_W, (LPSERVICE_MAIN_FUNCTION)service_main }, { NULL, NULL } }; void service_install ( const TCHAR *path, const TCHAR *name ); void service_uninstall ( const TCHAR *name ); int service_run ( const TCHAR *name ); int service_kill ( const TCHAR *name ); void execute_subprocess (); void write_log ( const char *filename, const char *text ); // void service_main_proc() { char szError[MAX_PATH] = { 0 }; TCHAR lpszModuleFile[MAX_PATH] = { 0 }; if( !GetModuleFileName(NULL, lpszModuleFile, MAX_PATH) ) return; if( 0 == strcmp("-i", g_lpszCmdLine) || 0 == strcmp("-I", g_lpszCmdLine) ) service_install( lpszModuleFile, SERVICE_NAME_W ); else if( 0 == strcmp("-r", g_lpszCmdLine) || 0 == strcmp("-R", g_lpszCmdLine) ) service_run( SERVICE_NAME_W ); else if( 0 == strcmp("-k", g_lpszCmdLine) || 0 == strcmp("-K", g_lpszCmdLine) ) service_kill( SERVICE_NAME_W ); else if( 0 == strcmp("-u", g_lpszCmdLine) || 0 == strcmp("-U", g_lpszCmdLine) ) service_uninstall( SERVICE_NAME_W ); else { if( !StartServiceCtrlDispatcher(g_ste) ) { sprintf( szError, "StartServiceCtrlDispatcher failed with error %d in execute_subprocess/r/n", GetLastError() ); write_log( LOG_FILE_NAME, szError ); } } } // void service_install( const TCHAR *path, const TCHAR *name ) { SC_HANDLE hSCManager = NULL; SC_HANDLE hService = NULL; char szError[MAX_PATH] = { 0 }; hSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE ); if( NULL == hSCManager ) { sprintf( szError, "OpenSCManager failed with error %d in install/r/n", GetLastError() ); write_log( LOG_FILE_NAME, szError ); return; } hService = CreateService( hSCManager, name, name, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS | / SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, path, NULL, NULL, NULL, NULL, NULL ); if( NULL == hService ) { sprintf( szError, "CreateService failed with error %d in install/r/n", GetLastError() ); write_log( LOG_FILE_NAME, szError ); CloseServiceHandle( hSCManager ); return; } write_log( LOG_FILE_NAME, "Install service successfully/r/n" ); CloseServiceHandle( hService ); CloseServiceHandle( hSCManager ); } void service_uninstall( const TCHAR *name ) { SC_HANDLE hSCManager = NULL; SC_HANDLE hService = NULL; char szError[MAX_PATH] = { 0 }; hSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if( NULL == hSCManager ) { sprintf( szError, "OpenSCManager failed with error %d in uninstall/r/n", GetLastError() ); write_log( LOG_FILE_NAME, szError ); return; } hService = OpenService( hSCManager, name, SERVICE_ALL_ACCESS ); if( NULL == hService ) { sprintf( szError, "OpenService failed with error %d in uninstall/r/n", GetLastError() ); write_log( LOG_FILE_NAME, szError ); CloseServiceHandle( hSCManager ); return; } if( !DeleteService(hService) ) { sprintf( szError, "DeleteService failed with error %d/r/n", GetLastError() ); write_log( LOG_FILE_NAME, szError ); } write_log( LOG_FILE_NAME, "Uninstall service successfully/r/n" ); CloseServiceHandle( hService ); CloseServiceHandle( hSCManager ); } int service_run( const TCHAR *name ) { SC_HANDLE hSCManager = NULL; SC_HANDLE hService = NULL; char szError[MAX_PATH] = { 0 }; hSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if( NULL == hSCManager ) { sprintf( szError, "OpenSCManager failed with error %d in run/r/n", GetLastError() ); write_log( LOG_FILE_NAME, szError ); return 0; } hService = OpenService( hSCManager, name, SERVICE_ALL_ACCESS ); if( NULL == hService ) { sprintf( szError, "OpenService failed with error %d in run/r/n", GetLastError() ); write_log( LOG_FILE_NAME, szError ); CloseServiceHandle( hSCManager ); return 0; } if( !StartService(hService, 0, NULL) ) { sprintf( szError, "StartService failed with error %d in run/r/n", GetLastError() ); write_log( LOG_FILE_NAME, szError ); CloseServiceHandle( hService ); CloseServiceHandle( hSCManager ); return 0; } write_log( LOG_FILE_NAME, "Run service successfully/r/n" ); CloseServiceHandle( hService ); CloseServiceHandle( hSCManager ); return 1; } int service_kill( const TCHAR *name ) { SC_HANDLE hSCManager = NULL; SC_HANDLE hService = NULL; SERVICE_STATUS status = { 0 }; char szError[MAX_PATH] = { 0 }; hSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if( NULL == hSCManager ) { sprintf( szError, "OpenSCManager failed with error %d in kill/r/n", GetLastError() ); write_log( LOG_FILE_NAME, szError ); return 0; } hService = OpenService( hSCManager, name, SERVICE_ALL_ACCESS ); if( NULL == hService ) { sprintf( szError, "OpenService failed with error %d in kill/r/n", GetLastError() ); write_log( LOG_FILE_NAME, szError ); CloseServiceHandle( hSCManager ); return 0; } if( !ControlService(hService, SERVICE_CONTROL_STOP, &status) ) { sprintf( szError, "ControlService failed with error %d in kill/r/n", GetLastError() ); write_log( LOG_FILE_NAME, szError ); CloseServiceHandle( hService ); CloseServiceHandle( hSCManager ); return 0; } write_log( LOG_FILE_NAME, "Kill service successfully/r/n" ); CloseServiceHandle( hService ); CloseServiceHandle( hSCManager ); return 1; } void write_log( const char *filename, const char *text ) { #if 0 CRITICAL_SECTION cs = { 0 }; SYSTEMTIME st = { 0 }; FILE *pf = NULL; GetLocalTime( &st ); InitializeCriticalSection( &cs ); EnterCriticalSection( &cs ); pf = fopen( filename, "a" ); if( NULL != pf ) { fprintf( pf, "%02d/%02d/%04d %02d:%02d:%02d %s", st.wMonth, st.wDay, st.wYear, st.wHour, st.wMinute, st.wSecond, text ); fclose( pf ); } LeaveCriticalSection( &cs ); DeleteCriticalSection( &cs ); #else MessageBoxA( NULL, text, "Log", MB_OK ); #endif } // void WINAPI service_main() { DWORD dwStatus = 0; char szError[MAX_PATH] = { 0 }; int i = 0; FILE *pf = NULL; SYSTEMTIME st = { 0 }; g_ss.dwServiceType = SERVICE_WIN32; g_ss.dwCurrentState = SERVICE_START_PENDING; g_ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE; g_ss.dwWin32ExitCode = 0; g_ss.dwServiceSpecificExitCode = 0; g_ss.dwCheckPoint = 0; g_ss.dwWaitHint = 0; g_hss = RegisterServiceCtrlHandler( SERVICE_NAME_W, service_handler ); if( NULL == g_hss ) { sprintf( szError, "RegisterServiceCtrlHandler failed with error %d/r/n", GetLastError() ); write_log( LOG_FILE_NAME, szError ); return; } g_ss.dwCurrentState = SERVICE_RUNNING; g_ss.dwCheckPoint = 0; g_ss.dwWaitHint = 0; if( !SetServiceStatus(g_hss, &g_ss) ) { sprintf( szError, "SetServiceStatus failed with error %d/r/n", GetLastError() ); write_log( LOG_FILE_NAME, szError ); return; } while( 1 ) { pf = fopen( "d://log.txt", "a" ); if( NULL != pf ) { GetLocalTime( &st ); fprintf( pf, "%02d/%02d/%04d %02d:%02d:%02d -- service is running !/r/n", st.wMonth, st.wDay, st.wYear, st.wHour, st.wMinute, st.wSecond ); fclose( pf ); pf = NULL; } Sleep( 10000 ); } } void WINAPI service_handler( DWORD dwCtrl ) { int i = 0; int index = 0; char szError[MAX_PATH] = { 0 }; switch( dwCtrl ) { case SERVICE_CONTROL_STOP: case SERVICE_CONTROL_SHUTDOWN: g_ss.dwWin32ExitCode = 0; g_ss.dwCurrentState = SERVICE_STOPPED; g_ss.dwCheckPoint = 0; g_ss.dwWaitHint = 0; break; case SERVICE_CONTROL_PAUSE: g_ss.dwCurrentState = SERVICE_PAUSED; break; case SERVICE_CONTROL_CONTINUE: g_ss.dwCurrentState = SERVICE_RUNNING; break; default: break; } if( !SetServiceStatus(g_hss, &g_ss) ) { sprintf( szError, "SetServiceStatus failed with error %d, in service_handler/r/n", dwCtrl ); write_log( LOG_FILE_NAME, szError ); } } 下图为服务启动后打印出的结果: