// WatchService.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "psapi.h" #include #include "Global.h" #include "..\ChineseRes\ChineseRes\resource.h" #pragma comment ( lib, "psapi.lib" ) const VER_WIN2000_PRO = 1; const VER_WIN2000_SRV = 2; const VER_WIN2000_ADVANCE_SRV = 3; const VER_WIN_XP = 4; const VER_WIN2003 = 5; const VER_WINNT = 6; const VER_VISA_UP = 7; const VER_OTHER = 8; const BUFSIZE = 1024; //定义全局函数变量 int g_nWindowsVer = VER_OTHER; void Init(); BOOL IsInstalled(); BOOL Install(); BOOL Uninstall(); void WINAPI ServiceMain(); void WINAPI ServiceStrl(DWORD dwOpcode); void LogEvent(LPCTSTR pFormat, ...); int FindProcessCount(char *strProcessName); DWORD FindAndKillProcess(char *strProcessName); void KillProcess(DWORD dwProcess); int GetSysData(); INT GetWindowVersion(); SERVICE_STATUS_HANDLE g_hServiceStatus; SERVICE_STATUS g_status; DWORD dwThreadID; BOOL InitWatchService(); void UnInitWatchService(); HANDLE g_hRunObject = NULL; HANDLE g_hWatchThread = NULL; DWORD WINAPI ReConnectTwoShipperServerThread( void *pData ); DWORD WINAPI ReConnectWatchSrvThread( void *pData ); HANDLE g_hReConnectWatchSrvThread = NULL; HANDLE g_hReConnectTwoShipperServerThread = NULL; DWORD WINAPI BackupDBThread( void *pData ); HANDLE g_hBackupDBThread = NULL; char g_strWatchDirectory[MAX_PATH]={0}; CHAR g_strAppName[MAX_PATH] = {0}; // 软件名称 char g_strVirComDir[MAX_PATH] = {0}; HINSTANCE g_hLangDLL; int _tmain(int argc, _TCHAR* argv[]) { GetSysData(); CHAR szPath[MAX_PATH] = {0}; int nProcessCount = 0; memset(szPath, 0, sizeof(szPath)); strcpy(szPath, g_strWatchDirectory); strcat(szPath, "\\WatchService.exe"); // 进程存在,直接退出 nProcessCount = FindProcessCount(szPath); if( nProcessCount > 1 ) { return 0; } Init(); dwThreadID = ::GetCurrentThreadId(); SERVICE_TABLE_ENTRY st[] = { { g_szServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain }, { NULL, NULL } }; if(argc > 1) { if (stricmp((char *)argv[1], "/install") == 0) { Install(); } else if (stricmp((char *)argv[1], "/uninstall") == 0) { Uninstall(); } else { if (!::StartServiceCtrlDispatcher(st)) { LogEvent(_T("Register Service Main Function Error!")); } } } else { if (!::StartServiceCtrlDispatcher(st)) { LogEvent(_T("Register Service Main Function Error!")); } } return 0; } INT GetWindowVersion() { int nResult = VER_OTHER; OSVERSIONINFOEX osvi; BOOL bOsVersionInfoEx; // Try calling GetVersionEx using the OSVERSIONINFOEX structure. // If that fails, try using the OSVERSIONINFO structure. ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) ) { osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) return -1; } switch (osvi.dwPlatformId) { // Test for the Windows NT product family. case VER_PLATFORM_WIN32_NT: // Test for the specific product family. if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 ) { nResult = VER_WIN2003; printf ("Microsoft Windows Server 2003 family, "); } if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 ) { nResult = VER_WIN_XP; printf ("Microsoft Windows XP "); } if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 ) { nResult = VER_WIN2000_PRO; printf ("Microsoft Windows 2000 "); } if ( osvi.dwMajorVersion <= 4 ) { nResult = VER_WINNT; printf("Microsoft Windows NT "); } // Test for specific product on Windows NT 4.0 SP6 and later. if( bOsVersionInfoEx ) { // Test for the workstation type. if ( osvi.wProductType == VER_NT_WORKSTATION ) { if( osvi.dwMajorVersion == 4 ) printf ( "Workstation 4.0 " ); else if( osvi.wSuiteMask & VER_SUITE_PERSONAL ) printf ( "Home Edition " ); else printf ( "Professional " ); } // Test for the server type. else if ( osvi.wProductType == VER_NT_SERVER ) { if( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 ) { if( osvi.wSuiteMask & VER_SUITE_DATACENTER ) printf ( "Datacenter Edition " ); else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) printf ( "Enterprise Edition " ); else if ( osvi.wSuiteMask == VER_SUITE_BLADE ) printf ( "Web Edition " ); else printf ( "Standard Edition " ); } else if( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 ) { if( osvi.wSuiteMask & VER_SUITE_DATACENTER ) { printf ( "Datacenter Server " ); } else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) { nResult = VER_WIN2000_ADVANCE_SRV; printf ( "Advanced Server " ); } else { nResult = VER_WIN2000_SRV; printf ( "Server " ); } } else // Windows NT 4.0 { if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) printf ("Server 4.0, Enterprise Edition " ); else printf ( "Server 4.0 " ); } } } else // Test for specific product on Windows NT 4.0 SP5 and earlier { HKEY hKey; char szProductType[BUFSIZE]; DWORD dwBufLen=BUFSIZE; LONG lRet; lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\ProductOptions", 0, KEY_QUERY_VALUE, &hKey ); if( lRet != ERROR_SUCCESS ) return FALSE; lRet = RegQueryValueEx( hKey, "ProductType", NULL, NULL, (LPBYTE) szProductType, &dwBufLen); if( (lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE) ) return FALSE; RegCloseKey( hKey ); if ( lstrcmpi( "WINNT", szProductType) == 0 ) printf( "Workstation " ); if ( lstrcmpi( "LANMANNT", szProductType) == 0 ) printf( "Server " ); if ( lstrcmpi( "SERVERNT", szProductType) == 0 ) printf( "Advanced Server " ); printf( "%d.%d ", osvi.dwMajorVersion, osvi.dwMinorVersion ); } // Display service pack (if any) and build number. if( osvi.dwMajorVersion == 4 && lstrcmpi( osvi.szCSDVersion, "Service Pack 6" ) == 0 ) { HKEY hKey; LONG lRet; // Test for SP6 versus SP6a. lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009", 0, KEY_QUERY_VALUE, &hKey ); if( lRet == ERROR_SUCCESS ) printf( "Service Pack 6a (Build %d)\n", osvi.dwBuildNumber & 0xFFFF ); else // Windows NT 4.0 prior to SP6a { printf( "%s (Build %d)\n", osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF); } RegCloseKey( hKey ); } else // Windows NT 3.51 and earlier or Windows 2000 and later { printf( "%s (Build %d)\n", osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF); } break; // Test for the Windows 95 product family. case VER_PLATFORM_WIN32_WINDOWS: if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) { printf ("Microsoft Windows 95 "); if ( osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B' ) printf("OSR2 " ); } if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10) { printf ("Microsoft Windows 98 "); if ( osvi.szCSDVersion[1] == 'A' ) printf("SE " ); } if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) { printf ("Microsoft Windows Millennium Edition\n"); } break; case VER_PLATFORM_WIN32s: printf ("Microsoft Win32s\n"); break; } return nResult; } void ReStartProcess(char *pPath) { PROCESS_INFORMATION pi; STARTUPINFO sti; ZeroMemory(&sti,sizeof(sti)); sti.cb=sizeof(sti); sti.lpDesktop="winsta0\\default"; CreateProcess(pPath,NULL,NULL,NULL,FALSE,0,NULL,NULL,&sti,&pi); } void StartIOService() { // 打开服务管理对象 SC_HANDLE hSC = ::OpenSCManager( NULL, NULL, GENERIC_EXECUTE); if( hSC == NULL) { return; } // 打开www服务。 SC_HANDLE hSvc = ::OpenService( hSC, "eBus-CMS IO Service", SERVICE_START | SERVICE_QUERY_STATUS | SERVICE_STOP); if( hSvc == NULL) { ::CloseServiceHandle( hSC); return; } // 获得服务的状态 SERVICE_STATUS status; if( ::QueryServiceStatus( hSvc, &status) == FALSE) { ::CloseServiceHandle( hSvc); ::CloseServiceHandle( hSC); return; } //如果处于停止状态则启动服务,否则停止服务。 if( status.dwCurrentState == SERVICE_RUNNING) { return; } else if( status.dwCurrentState == SERVICE_STOPPED) { // 启动服务 if( ::StartService( hSvc, NULL, NULL) == FALSE) { ::CloseServiceHandle( hSvc); ::CloseServiceHandle( hSC); return; } // 等待服务启动 while( ::QueryServiceStatus( hSvc, &status) == TRUE) { ::Sleep( status.dwWaitHint); if( status.dwCurrentState == SERVICE_RUNNING) { ::CloseServiceHandle( hSvc); ::CloseServiceHandle( hSC); return; } } } ::CloseServiceHandle( hSvc); ::CloseServiceHandle( hSC); return; } void StopIOService() { } //将进程名转换为PID的函数 DWORD ProcessToPID(char* InputProcessName) { DWORD aProcesses[1024], cbNeeded, cProcesses; unsigned int i; HANDLE hProcess; HMODULE hMod; char szProcessName[MAX_PATH] = "UnknownProcess"; // 计算目前有多少进程, aProcesses[]用来存放有效的进程PIDs if( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) return 0; cProcesses = cbNeeded / sizeof(DWORD); // 按有效的PID遍历所有的进程 for( i = 0; i < cProcesses; i++ ) { // 打开特定PID的进程 hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i]); // 取得特定PID的进程名 if( hProcess ) { if( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) ) { GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName) ); //LogEvent("得到的进程名%s", szProcessName); //将取得的进程名与输入的进程名比较,如相同则返回进程PID if(!_stricmp(szProcessName, InputProcessName)) { CloseHandle( hProcess ); DWORD dwSessionID = 0; ProcessIdToSessionId( aProcesses[i], &dwSessionID ); if( dwSessionID != 0 ) { KillProcess( aProcesses[i] ); LogEvent("删除远程桌面用户串口服务器进程!"); } //return aProcesses[i]; } } }//end of if ( hProcess ) }//end of for //没有找到相应的进程名,返回0 CloseHandle( hProcess ); return 0; }//end of ProcessToPID DWORD WINAPI WatchThreadProc(void *pPara) { CHAR szPath[MAX_PATH] = {0}; int nProcessCount = 0; do { if( g_nWindowsVer == VER_WIN2000_ADVANCE_SRV || g_nWindowsVer == VER_WIN2000_SRV || g_nWindowsVer == VER_WIN2003 ) { #if 0 //LogEvent("Win2003系统"); memset(szPath, 0, sizeof(szPath)); strcpy(szPath, g_strVirComDir); //关闭远程桌面进程 ProcessToPID("VComManage.exe"); nProcessCount = FindProcessCount(szPath); if( nProcessCount > 1 ) { // 指定桌面,要不看不到界面 // 等待桌面进程成功以后再指定桌面 nProcessCount = FindProcessCount("C:\\WINDOWS\\system32\\explorer.exe"); while( nProcessCount <= 0 ) { nProcessCount = FindProcessCount("C:\\WINDOWS\\system32\\explorer.exe"); } ReStartProcess(szPath); Sleep(10000); // 等待串口服务器转发成功 } #endif } if( g_nRunModeForIOServer==0 ) { Sleep( 3000 ); continue; } memset(szPath, 0, sizeof(szPath)); strcpy(szPath, g_strWatchDirectory); strcat(szPath, "\\IOServer.exe"); // 进程存在,直接退出 #if 1 nProcessCount = FindProcessCount(szPath); if( nProcessCount == 0 ) { Sleep(5000); //等待5秒,再启动 StartIOService(); //ShellExecute(NULL, "open", szPath, NULL, NULL, SW_SHOWNORMAL); // 指定桌面,要不看不到界面 //ReStartProcess(szPath); } else if( nProcessCount > 1 ) { FindAndKillProcess(szPath); LogEvent("删除IO服务器进程!"); Sleep(5000); //等待5秒,再启动 StartIOService(); //ShellExecute(NULL, "open", szPath, NULL, NULL, SW_SHOWNORMAL); // 指定桌面,要不看不到界面 //ReStartProcess(szPath); } #endif }while( WaitForSingleObject( g_hRunObject, 1250L ) == WAIT_TIMEOUT ); return 0; } DWORD __stdcall INTER_GetExplorerToken(OUT PHANDLE phExplorerToken ) { DWORD dwStatus = ERROR_FILE_NOT_FOUND ; BOOL bRet = FALSE ; HANDLE hProcess = NULL ; HANDLE hProcessSnap = NULL ; char szExplorerPath[MAX_PATH] = { 0 } ; char FileName[MAX_PATH] = { 0 } ; PROCESSENTRY32 pe32 = { 0 } ; __try { GetWindowsDirectory( szExplorerPath , MAX_PATH ) ; strcat( szExplorerPath , "\\Explorer.EXE" ) ; hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS , 0 ) ; if( hProcessSnap == INVALID_HANDLE_VALUE ) { dwStatus = GetLastError() ; __leave ; } pe32.dwSize = sizeof( PROCESSENTRY32 ) ; if( !Process32First( hProcessSnap, &pe32 )) { dwStatus = GetLastError() ; __leave ; } do { hProcess = OpenProcess( PROCESS_ALL_ACCESS , FALSE , pe32.th32ProcessID ) ; if( NULL != hProcess ) { DWORD (__stdcall *GMFNE)(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize); HMODULE hPsapi=LoadLibrary("PSAPI"); if ( ! hPsapi ) { dwStatus = GetLastError() ; break ; } GMFNE=(DWORD (__stdcall *) (HANDLE, HMODULE,LPTSTR,DWORD))GetProcAddress(hPsapi,"GetModuleFileNameExA"); if ( GMFNE(hProcess , NULL , FileName , MAX_PATH) ) { if( !strcmpi( FileName , szExplorerPath )) { HANDLE hToken ; if( OpenProcessToken( hProcess , TOKEN_ALL_ACCESS , &hToken )) { * phExplorerToken = hToken ; dwStatus = 0 ; } break ; } } CloseHandle ( hProcess ) ; hProcess = NULL ; } } while( Process32Next( hProcessSnap, &pe32 )) ; } __finally { if( NULL != hProcess ) { CloseHandle( hProcess ) ; } if( NULL != hProcessSnap ) { CloseHandle ( hProcessSnap ) ; } } return dwStatus ; } BOOL FolderExist(CString strPath) { WIN32_FIND_DATA wfd; BOOL rValue = FALSE; HANDLE hFind = FindFirstFile(strPath, &wfd); if( (hFind != INVALID_HANDLE_VALUE) && (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) { rValue = TRUE; } FindClose(hFind); return rValue; } int CreateBat( CString sDBBackName ) { CHAR strFile[MAX_PATH + 1] = ""; CHAR strFileSave[MAX_PATH + 1] = ""; CHAR strTemp[MAX_PATH + 1] = ""; int iPosFile = 0; int iLenghtFile = 0; //////////////////////////////////////////////////////////////////////////// //获取应用名 GetModuleFileName(NULL, g_strWatchDirectory, MAX_PATH); iLenghtFile = (int)strlen(g_strWatchDirectory); for (iPosFile = iLenghtFile - 1; iPosFile >= 0; iPosFile--) { if (g_strWatchDirectory[iPosFile] == '\\') { memset(g_strAppName, 0, sizeof(g_strAppName)); memcpy(g_strAppName, g_strWatchDirectory + iPosFile + 1, iLenghtFile - iPosFile - 1); break; } } iLenghtFile = (int)strlen(g_strWatchDirectory); for (iPosFile = iLenghtFile - 1; iPosFile >= 0; iPosFile--) { if (g_strWatchDirectory[iPosFile] == '\\') { g_strWatchDirectory[iPosFile] = '\0'; break; } } wsprintf(strFile, "%s\\set.ini", g_strWatchDirectory); wsprintf(strFileSave, "%s\\backupDB.bat", g_strWatchDirectory); DeleteFile( strFileSave ); CString sDBName,sDBPwd,sTemp; //数据库名称 GetPrivateProfileString("Database", "DataBaseName", "", strTemp, sizeof(strTemp), strFile); sDBName = strTemp; //数据库密码 GetPrivateProfileString("Database", "Password", "", strTemp, sizeof(strTemp), strFile); sDBPwd = strTemp; CStdioFile MyFile; if(!MyFile.Open(strFileSave,CFile::modeWrite)) MyFile.Open(strFileSave,CFile::modeCreate|CFile::modeWrite); MyFile.WriteString("set PGHOME=C:\\Program Files\\PostgreSQL\\8.3\n"); MyFile.WriteString("set PGDATA=%PGHOME%\\data\n"); MyFile.WriteString("set PGLIB=%PGHOME%\\lib\n"); MyFile.WriteString("set PGHOST=localhost\n"); MyFile.WriteString("set PATH=%PGHOME%\\bin;%PATH%\n"); sTemp.Format("set PGPASSWORD=%s\n",sDBPwd ); MyFile.WriteString(sTemp); sTemp.Format("pg_dump -F c -h localhost -U postgres %s >D:\\isP-CMS\\Datebase\\%s.backup",sDBName,sDBBackName ); MyFile.WriteString(sTemp); MyFile.Close(); if (!FolderExist("D:\\isP-CMS")) { LOG4C_FUN( ( "D:\\isP-CMS" )); CreateDirectory("D:\\isP-CMS", NULL); } if (!FolderExist("D:\\isP-CMS\\Datebase")) CreateDirectory("D:\\isP-CMS\\Datebase", NULL); return 0; } BOOL InitWatchService() { CSocketHandle::InitLibrary( MAKEWORD(2,2) ); MTVERIFY (g_hRunObject = ::CreateEvent( NULL, /* Security */ TRUE, /* Manual event */ 0, /* Clear on creation */ "WatchService::g_hRunObject")); char szFileName[MAX_PATH]; sprintf(szFileName, "%s\\log4crc", g_strWatchDirectory); ///设置日志配置文件名 LOG4C_PARAM_CFG_FILE_NAME(szFileName); ///设置日志级别 LOG4C_PARAM_LOG_LEVEL("LOG_ERROR"); ///设置日志文件大小 LOG4C_PARAM_LOG_FILE_SIZE(10240); ///设置生成日志文件个数,达到最大个数将自动覆盖最旧的日志 LOG4C_PARAM_LOG_FILE_NUM(5); ///设置每次记录日志都重新读取日志配置文件 LOG4C_PARAM_REREAD_LOG_CFG_FILE(1); ///带参数日志模块初始化,以上所有设置了的参数都将生效,没有设置的采用缺省值 LOG4C_INIT_WITH_PARAM(); //char strBuffer[128] = "You are the Best One!\0 Yes."; //LOG4C_HEX_DUMP((LOG_INFO, strBuffer, sizeof(strBuffer))); //LOG4C_ORIGIN ((LOG_ERROR,"LOG4C_ORIGIN")); //LOG4C_NO_FILENUM((LOG_ERROR, "LOG4C_NO_FILENUM")); ////LOG4C_RETURN_WITH_VALUE(( LOG4C_PRIORITY_TRACE, "message"), 1); //LOG4C_FUN(("Hello World!")); //LOG4C((LOG_ERROR, "Hello World!")); //LOG4C_IF((4>3, LOG_ERROR, "LOG4C_IF:4>3")); //LOG4C_IF((2>3, LOG_ERROR, "LOG4C_IF:2>3")); g_nWindowsVer = GetWindowVersion(); //LOG4C_FUN( (g_strWatchDirectory )); //LOG4C_NO_FILENUM((LOG_NOTICE, "test")); // //LOG4C_NO_FILENUM_NO_LAYOUT((LOG_NOTICE, "test")); CString str; if( g_nTwoShipperIsServer==1 ) str.Format( "%s %s %s",g_strTwoShipperServerIP,g_strTwoShipperServerPort,"服务器" ); else str.Format( "%s %s %s",g_strTwoShipperServerIP,g_strTwoShipperServerPort,"客户端" ); LOG4C_FUN( (str )); //LogEvent("系统版本=%d", g_nWindowsVer); DWORD dwThreadId; #if 1 g_hWatchThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WatchThreadProc, NULL, 0, &dwThreadId); #endif // 连接IO服务器 #if 0 // 连接WatchService g_pWatchServerSocket = new CWatchServerSocket; if( !g_pWatchServerSocket->Connection(g_strWatchServerIP, g_strWatchServerPort) ) { g_pWatchServerSocket->m_bSocket = FALSE; } else { g_pWatchServerSocket->m_bSocket = TRUE; for( int i = 0; i < MAX_DLL_TYPE; i++ ) { g_dwServiceOnlineTick[i] = 0; } } if( g_hReConnectWatchSrvThread == NULL ) { MTVERIFY( g_hReConnectWatchSrvThread = ::CreateThread(NULL, 0, ReConnectWatchSrvThread, 0, 0, 0) ); } #endif if( g_hBackupDBThread == NULL ) { MTVERIFY( g_hBackupDBThread = ::CreateThread(NULL, 0, BackupDBThread, 0, 0, 0) ); } if( g_nTwoShipperIsServer==0 && g_hReConnectTwoShipperServerThread == NULL ) { MTVERIFY( g_hReConnectTwoShipperServerThread = ::CreateThread(NULL, 0, ReConnectTwoShipperServerThread, 0, 0, 0) ); } // 连接TwoShipper g_pTwoShipperSocket = new CTwoShipperSocket(g_nTwoShipperIsServer); switch( g_nTwoShipperIsServer ) { case 0://客户端 { if( !g_pTwoShipperSocket->DllC_LoginServer(g_strTwoShipperServerIP, g_strTwoShipperServerPort) ) { LOG4C_FUN( ("Login Server fail" )); g_pTwoShipperSocket->m_bClientLoginServerSuccess = false; } else { LOG4C_FUN( ("Login Server Success" )); g_pTwoShipperSocket->m_bClientLoginServerSuccess = true; } } break; case 1://服务器 { if( !g_pTwoShipperSocket->DllS_StartServer( g_strTwoShipperServerPort) ) { LOG4C_FUN( ("Start Server fail" )); } else LOG4C_FUN( ("Start Server Success" )); } break; } while(g_status.dwCurrentState != SERVICE_STOP_PENDING) { Sleep(1000); } UnInitWatchService(); return FALSE; } void UnInitWatchService() { //LogEvent("Watch Server Stop"); if (g_hRunObject != NULL) MTVERIFY( SetEvent( g_hRunObject ) ); if( g_pWatchServerSocket != NULL ) { g_pWatchServerSocket->DisConnection(); delete g_pWatchServerSocket; g_pWatchServerSocket = NULL; } if (g_hWatchThread != NULL) { MTVERIFY( WaitForSingleObject( g_hWatchThread, INFINITE ) != WAIT_FAILED ); MTVERIFY( CloseHandle(g_hWatchThread) ); g_hWatchThread = NULL; } if( g_hReConnectWatchSrvThread != NULL ) { MTVERIFY( WaitForSingleObject( g_hReConnectWatchSrvThread, INFINITE ) != WAIT_FAILED ); MTVERIFY( CloseHandle( g_hReConnectWatchSrvThread ) ); g_hReConnectWatchSrvThread = NULL; } if( g_hReConnectTwoShipperServerThread != NULL ) { MTVERIFY( WaitForSingleObject( g_hReConnectTwoShipperServerThread, INFINITE ) != WAIT_FAILED ); MTVERIFY( CloseHandle( g_hReConnectTwoShipperServerThread ) ); g_hReConnectTwoShipperServerThread = NULL; } LOG4C_FINI(); } //********************************************************* //Functiopn: Init //Description: 初始化 //Calls: main //Called By: //Table Accessed: //Table Updated: //Input: //Output: //Return: //Others: //History: // niying