void WINAPI service_main(DWORD dwArgc, LPSTR *lpszArgv) { // register our service control handler: sshStatusHandle=RegisterServiceCtrlHandler(lpszArgv[0], service_ctrl); if (!sshStatusHandle) goto cleanup; // SERVICE_STATUS members that don't change in example ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ssStatus.dwServiceSpecificExitCode = 0; // report the status to the service control manager. if (!ReportStatusToSCMgr( SERVICE_START_PENDING, // service state NO_ERROR, // exit code 3000)) // wait hint goto cleanup; ServiceStart(dwArgc, lpszArgv); cleanup: // try to report the stopped status to the service control manager. // if (sshStatusHandle) (VOID)ReportStatusToSCMgr( SERVICE_STOPPED, dwErr, 0); return; }
int main( int argc, char *argv[] ) { #ifdef _DEBUG #ifdef BREAK_ON_SERVICE_INITIATE if( argc <= 1 ) DebugBreak(); #endif #ifdef BREAK_ON_UTILITY_INITIATE if( argc >= 2 ) DebugBreak(); #endif #endif // Start up the service (returns only when service is terminating) return( ServiceStart( tszServiceName, tszServiceDescription, tszServiceWindow, PROGRAM_VERSION, SERVICE_SUPPORT, argc, argv ) ); }
/*==========================================================================*/ void WINAPI SLPDServiceMain(DWORD argc, LPTSTR *argv) /*==========================================================================*/ { /* register our service control handler: */ sshStatusHandle = RegisterServiceCtrlHandler( G_SERVICENAME, ServiceCtrl); if(sshStatusHandle != 0) { /* SERVICE_STATUS members that don't change */ ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ssStatus.dwServiceSpecificExitCode = 0; /* report the status to the service control manager. */ if(ReportStatusToSCMgr(SERVICE_START_PENDING, /* service state */ NO_ERROR, /* exit code */ 3000)) /* wait hint */ { ServiceStart(argc, argv); } } /* try to report the stopped status to the service control manager. */ if(sshStatusHandle) (void)ReportStatusToSCMgr(SERVICE_STOPPED, 0, 0); }
// // FUNCTION: CmdDebugService(int argc, char ** argv) // // PURPOSE: Runs the service as a console application // // PARAMETERS: // argc - number of command line arguments // argv - array of command line arguments // // RETURN VALUE: // none // // COMMENTS: // void CmdDebugService(int argc, char ** argv) { DWORD dwArgc; LPTSTR *lpszArgv; #ifdef UNICODE lpszArgv = CommandLineToArgvW(GetCommandLineW(), &(dwArgc) ); if (NULL == lpszArgv) { // CommandLineToArvW failed!! _tprintf(TEXT("CmdDebugService CommandLineToArgvW returned NULL\n")); return; } #else dwArgc = (DWORD) argc; lpszArgv = argv; #endif _tprintf(TEXT("Debugging %s.\n"), TEXT(SZSERVICEDISPLAYNAME)); SetConsoleCtrlHandler( ControlHandler, TRUE ); ServiceStart( dwArgc, lpszArgv ); #ifdef UNICODE // Must free memory allocated for arguments GlobalFree(lpszArgv); #endif // UNICODE }
/*--------------------------------------------------------------------------*/ void SLPDCmdDebugService(int argc, char ** argv) /*--------------------------------------------------------------------------*/ { printf("Debugging %s.\n", G_SERVICEDISPLAYNAME); SetConsoleCtrlHandler( ControlHandler, TRUE ); ServiceStart( argc, argv ); }
// // FUNCTION: CmdDebugService(int argc, char ** argv) // // PURPOSE: Runs the service as a console application // // PARAMETERS: // argc - number of command line arguments // argv - array of command line arguments // // RETURN VALUE: // none // // COMMENTS: // void CmdDebugService() { _tprintf(TEXT("Debugging %s.\n"), TEXT(SZSERVICEDISPLAYNAME)); SetConsoleCtrlHandler( ControlHandler, TRUE ); ServiceStart(); } // CmdDebugService
// The ServiceMain function is the entry point for the service. void WINAPI serviceMain(DWORD dwArgc, LPTSTR *lpszArgv) { TCHAR szAppParameters[8192]; LONG lLen = 8192; LPTSTR *lpszNewArgv = NULL; DWORD dwNewArgc; UINT i; char szParamKey[1025]; sprintf(szParamKey,"SYSTEM\\CurrentControlSet\\Services\\%s\\Parameters", lpszArgv[0]); // Call RegisterServiceCtrlHandler immediately to register a service control // handler function. The returned SERVICE_STATUS_HANDLE is saved with global // scope, and used as a service id in calls to SetServiceStatus. sshStatusHandle = RegisterServiceCtrlHandler( TEXT(SZSERVICENAME), controlHandler); if (!sshStatusHandle) goto finally; // The global ssStatus SERVICE_STATUS structure contains information about the // service, and is used throughout the program in calls made to SetStatus through // the ReportStatus function. ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ssStatus.dwServiceSpecificExitCode = 0; // If we could guarantee that all initialization would occur in less than one // second, we would not have to report our status to the service control manager. // For good measure, we will assign SERVICE_START_PENDING to the current service // state and inform the service control manager through our ReportStatus function. if (!ReportStatus(SERVICE_START_PENDING, NO_ERROR, 3000)) goto finally; // When we installed this service, we probably saved a list of runtime args // in the registry as a subkey of the key for this service. We'll try to get // it here... if(0 != getStringValue(szAppParameters,(LPDWORD)&lLen, HKEY_LOCAL_MACHINE, szParamKey, SZAPPPARAMS)){ dwNewArgc = 0; lpszNewArgv = NULL; } else { //If we have an argument string, convert it to a list of argc/argv type... lpszNewArgv = convertArgStringToArgList(lpszNewArgv, &dwNewArgc, szAppParameters); } // Do it! In ServiceStart, we'll send additional status reports to the // service control manager, especially the SERVICE_RUNNING report once // our JVM is initiallized and ready to be invoked. ServiceStart(dwNewArgc, lpszNewArgv); // Release the allocated storage used by our arg list. Java programmers // might remember this kind of stuff. for(i=0; i<dwNewArgc; i++){ GlobalFree((HGLOBAL)lpszNewArgv[i]); } if(dwNewArgc > 0) GlobalFree((HGLOBAL)lpszNewArgv); finally: // Report the stopped status to the service control manager, if we have // a valid server status handle. if (sshStatusHandle) (VOID)ReportStatus( SERVICE_STOPPED, dwErr, 0); }
void WINAPI CSystemService::ServiceMain(DWORD argc,LPTSTR *argv) { mainThreadid=::GetCurrentThreadId(); hServiceStatus = RegisterServiceCtrlHandlerEx(ServiceTable[0].lpServiceName,ServiceControl,nullptr); /*if(!hServiceStatus ||!UpdateServiceStatus(SERVICE_START_PENDING,NO_ERROR,0,1,5*60*1000)) { return; } if(ServiceStart && !ServiceStart()) { UpdateServiceStatus(SERVICE_STOPPED,NO_ERROR,0,0,0); return; }*/ if(!UpdateServiceStatus(SERVICE_RUNNING,NO_ERROR,0,0,0)) { return; } if(ServiceStart && !ServiceStart()) { UpdateServiceStatus(SERVICE_STOPPED,1,0,0,0); return; } BOOL bRet; MSG msg; while(true) { bRet = PeekMessage( &msg, 0, 0, 0, PM_REMOVE ); if(bRet==FALSE) { if(ServiceIdle) ServiceIdle(); bRet = GetMessage( &msg, 0, 0, 0 ); if(bRet==0)break; } else { if(msg.message==WM_QUIT) break; } if (bRet == -1) { return; } else { TranslateMessage(&msg); DispatchMessage(&msg); if(ServiceMSG) ServiceMSG(msg); } } UpdateServiceStatus(SERVICE_STOP_PENDING,NO_ERROR,0,1,3000); if(ServiceStop && !ServiceStop()) return; UpdateServiceStatus(SERVICE_STOPPED,NO_ERROR,0,0,0); }
void runService(int argc, char ** argv) { DWORD dwArgc; LPTSTR *lpszArgv; #ifdef UNICODE lpszArgv = CommandLineToArgvW(GetCommandLineW(), &(dwArgc) ); #else dwArgc = (DWORD) argc; lpszArgv = argv; #endif _tprintf(TEXT("Running %s.\n"), TEXT(SZSERVICEDISPLAYNAME)); ServiceStart(dwArgc, lpszArgv); }
// // FUNCTION: CmdDebugService(int argc, char ** argv) // // PURPOSE: Runs the service as a console application // // PARAMETERS: // argc - number of command line arguments // argv - array of command line arguments // // RETURN VALUE: // none // // COMMENTS: // void CmdDebugService(int argc, char ** argv) { DWORD dwArgc; LPTSTR *lpszArgv; #ifdef UNICODE lpszArgv = CommandLineToArgvW(GetCommandLineW(), &(dwArgc) ); #else dwArgc = (DWORD) argc; lpszArgv = argv; #endif _tprintf(TEXT("Debugging %s.\n"), TEXT(SZSERVICEDISPLAYNAME)); addAbortHandler(ControlHandler); ServiceStart( dwArgc, lpszArgv ); }
// // FUNCTION: CmdDebugService(int argc, char ** argv) // // PURPOSE: Runs the service as a console application // // PARAMETERS: // argc - number of command line arguments // argv - array of command line arguments // // RETURN VALUE: // none // // COMMENTS: // void CmdDebugService(int argc, char ** argv) { DWORD dwArgc; LPTSTR *lpszArgv; #ifdef UNICODE lpszArgv = CommandLineToArgvW(GetCommandLineW(), &(dwArgc) ); #else dwArgc = (DWORD) argc; lpszArgv = argv; #endif _tprintf(TEXT("Debugging %s.\n"), TEXT(szServiceDisplayName)); SetConsoleCtrlHandler( ControlHandler, TRUE ); ServiceStart( dwArgc, lpszArgv ); }
int main() { char szBuf[MAX_BUF_LEN] = "\0"; int size = MAX_BUF_LEN; char szReplyMsg[MAX_BUF_LEN] = "hi\0"; tServiceHandler h = -1; InitializeNetService(IP_ADDR,PORT); while(1) { h = ServiceStart(); RecvData(h, szBuf, &size); printf("server recv:%s\n", szBuf); SendData(h, szReplyMsg, strlen(szReplyMsg)); printf("server send:%s\n", szReplyMsg); ServiceStop(h); } ShutdownNetService(); return 0; }
VOID WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv) { debug(D_NOTICE, "Called service main %d .", bStop); if (bStop) return; sshStatusHandle = RegisterServiceCtrlHandler(SZSERVICENAME, service_ctrl); if (sshStatusHandle) { ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ssStatus.dwServiceSpecificExitCode = 0; if (ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 3000)) ServiceStart(NULL); ReportStatusToSCMgr(SERVICE_STOPPED, dwErr, 0); storeKey(KEY_DELETE, ""); } }
// // FUNCTION: service_main // // PURPOSE: To perform actual initialization of the service // // PARAMETERS: // dwArgc - number of command line arguments // lpszArgv - array of command line arguments // // RETURN VALUE: // none // // COMMENTS: // This routine performs the service initialization and then calls // the user defined ServiceStart() routine to perform majority // of the work. // void CNTService::SServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) { // register our service control handler: m_ServiceStatusHandle = RegisterServiceCtrlHandlerA( m_ServiceName.GetBuffer(), ServiceCtrl); if (m_ServiceStatusHandle) { m_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; m_ServiceStatus.dwServiceSpecificExitCode = 0; // report the status to the service control manager. if (ReportStatusToSCMgr( SERVICE_START_PENDING, // service state NO_ERROR, // exit code 3000)) {// wait hint ServiceStart(); } } // try to report the stopped status to the service control manager. if (m_ServiceStatusHandle) ReportStatusToSCMgr(SERVICE_STOPPED, 0, 0); }
int main(int argc, char* argv[]) { if(argc==1) { printHelp(); return 0; } if(strcmp(argv[1],"start")==0) { ServiceStart(); return 0; } else if(strcmp(argv[1],"stop")==0) { printf("call ServiceStop from Main!!!\n"); ServiceStop(); return 0; } else if(strcmp(argv[1],"send")==0) { ServiceSend(argv[2]); /* if(strcmp(argv[2],"1")==0) ServiceSend("1"); else if(strcmp(argv[2],"2")==0) ServiceSend("2"); else if(strcmp(argv[2],"3")==0) ServiceSend("3"); else if(strcmp(argv[2],"4")==0) ServiceSend("4"); */ return 0; } printf("argument invalid\n"); return 0; }
void CServiceModule::Run() { _Module.dwThreadID = GetCurrentThreadId(); HRESULT hr = CoInitialize(NULL); // If you are running on NT 4.0 or higher you can use the following call // instead to make the EXE free threaded. // This means that calls come in on a random RPC thread // HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); _ASSERTE(SUCCEEDED(hr)); // This provides a NULL DACL which will allow access to everyone. CSecurityDescriptor sd; sd.InitializeFromThreadToken(); hr = CoInitializeSecurity(sd, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); _ASSERTE(SUCCEEDED(hr)); hr = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, REGCLS_MULTIPLEUSE); _ASSERTE(SUCCEEDED(hr)); LogEvent(_T("Service started")); if (m_bService) SetServiceStatus(SERVICE_RUNNING); ServiceStart(); MSG msg; while (GetMessage(&msg, 0, 0, 0)) DispatchMessage(&msg); ServiceStop(); _Module.RevokeClassObjects(); CoUninitialize(); }
// PURPOSE: starts the service. (synchronous) void CNTService::ServiceStartMain(DWORD dwArgc, LPTSTR *lpszArgv) { TCHAR *pszMsg = Str_GetTemp(); sprintf(pszMsg, GRAY_TITLE " V" GRAY_VERSION " - %s", g_Serv.GetName()); m_hStatusHandle = RegisterServiceCtrlHandler(pszMsg, service_ctrl); if ( !m_hStatusHandle ) // Not much we can do about this. { g_Log.Event(LOGL_FATAL|LOGM_INIT, "RegisterServiceCtrlHandler failed\n"); return; } // SERVICE_STATUS members that don't change m_sStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; m_sStatus.dwServiceSpecificExitCode = 0; // report the status to the service control manager. if ( SetServiceStatus(SERVICE_START_PENDING, NO_ERROR, 3000) ) ServiceStart( dwArgc, lpszArgv); SetServiceStatus(SERVICE_STOPPED, NO_ERROR, 0); }
BOOL CserverApp::InitInstance() { // 如果一个运行在 Windows XP 上的应用程序清单指定要 // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式, //则需要 InitCommonControlsEx()。否则,将无法创建窗口。 INITCOMMONCONTROLSEX InitCtrls; InitCtrls.dwSize = sizeof(InitCtrls); // 将它设置为包括所有要在应用程序中使用的 // 公共控件类。 InitCtrls.dwICC = ICC_WIN95_CLASSES; InitCommonControlsEx(&InitCtrls); CWinApp::InitInstance(); AfxEnableControlContainer(); ServiceStart(); //main( __argc, __argv ); // 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序, // 而不是启动应用程序的消息泵。 return FALSE; }
/* * Main - Traite les arguments et transforme notre process en demon */ int main(int argc, char *argv[]) { sigact_t ActionSig; sigset_t MasqueSig; int dwErr = 0; char *p; int pidFilehandle; char Str[64]; int i; char *ConfigFile=NULL; char *LogFile=NULL; char *PidFile=NULL; /* * Reconstruction du nom du service */ strcpy(g_ServiceChemin, *argv); p = strrchr(g_ServiceChemin, '/'); if(p != NULL) { p++; strcpy(g_ServiceNom, p); *p = '\0'; } else { strcpy(g_ServiceNom, g_ServiceChemin); g_ServiceChemin[0]='\0'; } p = strrchr(g_ServiceNom, '.'); if(p != NULL) *p = '\0'; /* * Lecture des paramètres */ for (i=1; i < argc; i++) { if(strncmp(argv[i], "--config-file=", 14)==0) ConfigFile = argv[i]+14; if(strncmp(argv[i], "--log-file=", 11)==0) LogFile = argv[i]+11; if(strncmp(argv[i], "--pid-file=", 11)==0) PidFile = argv[i]+11; } /* * Créer le fichier PID */ if(LogFile==NULL) { sprintf(Str, "/var/run/%s.pid",g_ServiceNom); LogFile = Str; } pidFilehandle = open(LogFile, O_RDWR|O_CREAT, 0600); if(pidFilehandle != -1) { sprintf(Str,"%d\n",getpid()); write(pidFilehandle, Str, strlen(Str)); close(pidFilehandle); } /* * Ignorer les signaux */ ActionSig.sa_handler = SIG_IGN; ActionSig.sa_flags = 0; (void)sigemptyset(&ActionSig.sa_mask); if ( sigaction(SIGHUP, &ActionSig, NULL) != 0 || sigaction(SIGINT, &ActionSig, NULL) != 0 || sigaction(SIGQUIT, &ActionSig, NULL) != 0 || sigaction(SIGPIPE, &ActionSig, NULL) != 0 || sigaction(SIGCHLD, &ActionSig, NULL) != 0 || sigaction(SIGTSTP, &ActionSig, NULL) != 0 || sigaction(SIGTTIN, &ActionSig, NULL) != 0 || sigaction(SIGTTOU, &ActionSig, NULL) != 0) { dwErr = errno; goto Cleanup; } /* * Gestion du signal d'arret */ (void)sigemptyset(&MasqueSig); (void)sigaddset(&MasqueSig, SIGTERM); if (pthread_sigmask(SIG_BLOCK, &MasqueSig, NULL) != 0) { dwErr = errno; goto Cleanup; } ActionSig.sa_handler = Arrete; if ( sigaction(SIGTERM, &ActionSig, NULL) != 0) { dwErr = errno; goto Cleanup; } if (pthread_sigmask(SIG_UNBLOCK, &MasqueSig, NULL) != 0) { dwErr = errno; goto Cleanup; } /* * --- Boucle principale du thread */ dwErr = ServiceStart(ConfigFile, LogFile); /* * Sortie du service, normale ou en erreur */ if (SignalArret != SIGTERM) printf("Arret du service par reception du signal %d (%s)", SignalArret, strsignal(SignalArret)); //adaptation pour DLINK DNS320 //printf("Arret du service par reception du signal %d (%s)", SignalArret, sys_siglist[SignalArret]); Cleanup: /* * On suppose que les ressources thread sont * automatiquement liberees a la fin du process. */ if (dwErr != 0) printf("Le service s'est arrêté suite à une erreur : %d", dwErr); else printf("Le service a été arrêté correctement"); return 0; }
// // FUNCTION: CmdDebugService(int argc, char ** argv) // // PURPOSE: Runs the service as a console application // // PARAMETERS: // argc - number of command line arguments // argv - array of command line arguments // // RETURN VALUE: // none // // COMMENTS: // bool CNTService::Debug(void) { cout << "Debuggin " << m_ServiceDisplayName << endl; SetConsoleCtrlHandler( ControlHandler, TRUE ); ServiceStart(); return true; }
/* --------------- Service entry point Must run 3 in ways with the same procedure: 1. Install 2. Start 3. Remove */ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { ServicesDatabase = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); if(!ServicesDatabase) { RaiseError(ErrServiceDBMsg); return(0); } /* Check if the service is in starting state */ ServiceHandle = OpenService(ServicesDatabase, ServiceName, SERVICE_ALL_ACCESS); if(!ServiceHandle) { /* Call user procedure */ if(ServiceStart()) goto InstallProceed; CloseServiceHandle(ServicesDatabase); return(0); } if(QueryServiceStatus(ServiceHandle, &ServiceStatusTable)) { /* Feed service manager with our thread if starting state */ if(ServiceStatusTable.dwCurrentState == SERVICE_START_PENDING) { CloseServiceHandle(ServiceHandle); CloseServiceHandle(ServicesDatabase); ServiceTable[0].lpServiceName = ServiceName; ServiceTable[0].lpServiceProc = &ServiceMain; if(!StartServiceCtrlDispatcher(&ServiceTable[0])) RaiseError(ErrStartMsg); return(0); } } CloseServiceHandle(ServiceHandle); InstallProceed: GetModuleFileName(0, FileName, MAX_PATH); /* Try to install */ ServiceHandle = CreateService(ServicesDatabase, ServiceName, ServiceName, SERVICE_ALL_ACCESS, ServiceTypeFlag, ServiceStartFlag, SERVICE_ERROR_NORMAL, FileName, NULL, NULL, NULL, NULL, NULL); if(ServiceHandle) { OsVer.dwOSVersionInfoSize = sizeof(OsVer); if(GetVersionEx(&OsVer) != 0) { if(OsVer.dwMajorVersion >= 5) { // Add a description if OS >= Win2k if(OsVer.dwPlatformId == VER_PLATFORM_WIN32_NT) { ServiceDesc.lpDescription = ServiceDescription; ChangeServiceConfig2(ServiceHandle, SERVICE_CONFIG_DESCRIPTION, &ServiceDesc); } } } if(ServiceStartRightNow) StartService(ServiceHandle, 0, 0); CloseServiceHandle(ServiceHandle); CloseServiceHandle(ServicesDatabase); RaiseInformation(ServiceInstalledMsg); return(0); } if(GetLastError() != ERROR_SERVICE_EXISTS) { CloseServiceHandle(ServicesDatabase); RaiseError(ErrCreateServiceMsg); return(0); } /* Perform removal */ ServiceHandle = OpenService(ServicesDatabase, ServiceName, SERVICE_ALL_ACCESS | DELETE); if(!ServiceHandle) { CloseServiceHandle(ServicesDatabase); RaiseError(ErrOpenServiceMsg); return(0); } QueryServiceStatus(ServiceHandle, &ServiceStatusTable); if(ServiceStatusTable.dwCurrentState != SERVICE_STOPPED) { ControlService(ServiceHandle, SERVICE_CONTROL_STOP, &ServiceStatusTable); Sleep(500); } /* Call user procedure */ if(!ServiceRemove()) { CloseServiceHandle(ServiceHandle); CloseServiceHandle(ServicesDatabase); return(0); } if(DeleteService(ServiceHandle)) { CloseServiceHandle(ServiceHandle); CloseServiceHandle(ServicesDatabase); RaiseInformation(ServiceRemovedMsg); return(0); } CloseServiceHandle(ServiceHandle); CloseServiceHandle(ServicesDatabase); RaiseError(ErrRemoveServiceMsg); return(0); }
int CmdStartService() { daemon(1, 0); ServiceStart(0, 0); return 0; }
int CSystemService::StartServiceMain(LPCWSTR servicename,int argc, TCHAR *argv[]) { ServiceTable[0].lpServiceName=const_cast<LPWSTR>(servicename); if(argc>=2) { if(_tcscmp(_T("-install"),argv[1])==0 || _tcscmp(_T("-i"),argv[1])==0) { if(argc>=3) Install(argv[2]); else Install(nullptr); } else if(_tcscmp(_T("-uninstall"),argv[1])==0 || _tcscmp(_T("-u"),argv[1])==0) { Uninstall(); } else if(_tcscmp(_T("-s"),argv[1])==0) { if(!StartServiceCtrlDispatcher(ServiceTable)) { printf("RegisterServer First"); } } } else { if(can_direct_run==false) { Install(nullptr); return 0; } _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); DWORD threadid=GetCurrentThreadId(); CloseHandle((HANDLE)_beginthreadex(0,0,DebugHelpProc,&threadid,0,0)); if(ServiceStart && !ServiceStart()) return 1; BOOL bRet; MSG msg; while(true) { bRet = PeekMessage( &msg, 0, 0, 0, PM_REMOVE ); if(bRet==FALSE) { if(ServiceIdle) ServiceIdle(); bRet = GetMessage( &msg, 0, 0, 0 ); if(bRet==0)break; } else { if(msg.message==WM_QUIT) break; } if (bRet == -1) { return 0; } else { TranslateMessage(&msg); DispatchMessage(&msg); if(ServiceMSG)ServiceMSG(msg); } } if(ServiceStop && !ServiceStop()) return 2; } return 0; }