Service.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. // Service.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include "SysLib.h"
  5. #include "ascprocess.h"
  6. #include "tcpprocess.h"
  7. #include "rtuprocess.h"
  8. #include "icpdasprocess.h"
  9. #include "SnmpProcess.h"
  10. #include "NoticeQueue.h"
  11. #include "MainPro.h"
  12. #include "CheckDog.h"
  13. #include "upsparadigmProcess.h"
  14. #include "stulzprocess.h"
  15. #include "Separate.h"
  16. #include "MostDevice.h"
  17. #include "stdio.h"
  18. #include "tchar.h"
  19. #include <windows.h>
  20. #include "winsvc.h"
  21. #include "ping.h"
  22. //定义全局函数变量
  23. void Init();
  24. BOOL IsInstalled();
  25. BOOL Install();
  26. BOOL Uninstall();
  27. void WINAPI ServiceMain();
  28. void WINAPI ServiceStrl(DWORD dwOpcode);
  29. BOOL InitIOService();
  30. void UnInitIOService();
  31. SERVICE_STATUS_HANDLE g_hServiceStatus;
  32. SERVICE_STATUS g_status;
  33. DWORD dwThreadID;
  34. HINSTANCE g_hLangDLL;
  35. int CALLBACK Sms_NoticeConfig( BOOL bEnableAlarm )
  36. {
  37. if( bEnableAlarm==1 )
  38. LOG4C((LOG_NOTICE, "收到恢复所有报警通知短信"));
  39. if( bEnableAlarm==0 )
  40. LOG4C((LOG_NOTICE, "收到关闭所有报警通知短信"));
  41. g_bAlarmNoticeFlag = bEnableAlarm;
  42. return 0;
  43. }
  44. //#define UNIQE_NAME "isP-CMS IO Service" //定义唯一的,以免冲突
  45. //#define ra_MSG "isP-CMS_IOService_MSG"
  46. //const UINT ID_RA_MSG =::RegisterWindowMessage(ra_MSG);
  47. //HANDLE m_hMutexInstance;
  48. int _tmain(int argc, _TCHAR* argv[])
  49. {
  50. //HWND hwnd = GetForegroundWindow(); // 直接获得前景窗口的句柄
  51. //SendMessage(hwnd , WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(NULL,MAKEINTRESOURCE(IDI_MICON)));
  52. Init();
  53. dwThreadID = ::GetCurrentThreadId();
  54. SERVICE_TABLE_ENTRY st[] =
  55. {
  56. { g_szServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain },
  57. { NULL, NULL }
  58. };
  59. CSocketHandle::InitLibrary( MAKEWORD(2,2) );
  60. GetSysData();
  61. CHAR strFile[MAX_FILE_LENGTH + 1] = "";
  62. if( stricmp(g_strLanguage, "CHS") == 0 )
  63. {
  64. wsprintf(strFile, "%s\\ChineseRes.dll", g_strDirectory);
  65. g_hLangDLL = ::LoadLibrary(strFile);
  66. }
  67. else if( stricmp(g_strLanguage, "CHT") == 0 )
  68. {
  69. wsprintf(strFile, "%s\\TaiwanRes.dll", g_strDirectory);
  70. g_hLangDLL = ::LoadLibrary(strFile);
  71. }
  72. else if( stricmp(g_strLanguage, "ENG") == 0 )
  73. {
  74. wsprintf(strFile, "%s\\EnglishRes.dll", g_strDirectory);
  75. g_hLangDLL = ::LoadLibrary(strFile);
  76. }
  77. AfxSetResourceHandle(g_hLangDLL);
  78. GetResourceString();
  79. if(argc > 1)
  80. {
  81. if (stricmp((char *)argv[1], "/install") == 0)
  82. {
  83. Install();
  84. }
  85. else if (stricmp((char *)argv[1], "/uninstall") == 0)
  86. {
  87. Uninstall();
  88. }
  89. else
  90. {
  91. if (!::StartServiceCtrlDispatcher(st))
  92. {
  93. LOG4C((LOG_NOTICE, _T("Register Service Main Function Error!")));
  94. }
  95. }
  96. }
  97. else
  98. {
  99. if (!::StartServiceCtrlDispatcher(st))
  100. {
  101. LOG4C((LOG_NOTICE, _T("Register Service Main Function Error!")));
  102. }
  103. }
  104. return 0;
  105. }
  106. BOOL InitIOService()
  107. {
  108. MTVERIFY (g_hRunObject = ::CreateEvent(
  109. NULL, /* Security */
  110. TRUE, /* Manual event */
  111. 0, /* Clear on creation */
  112. 0));
  113. CString strFileName;
  114. strFileName.Format("%s\\log4crc", g_strDirectory);
  115. LogEvent(strFileName);
  116. ///设置日志配置文件名
  117. LOG4C_PARAM_CFG_FILE_NAME(strFileName);
  118. ///设置日志级别
  119. LOG4C_PARAM_LOG_LEVEL("NOTICE");
  120. ///设置日志文件大小
  121. LOG4C_PARAM_LOG_FILE_SIZE(10240);
  122. ///设置生成日志文件个数,达到最大个数将自动覆盖最旧的日志
  123. LOG4C_PARAM_LOG_FILE_NUM(5);
  124. ///设置每次记录日志都重新读取日志配置文件
  125. LOG4C_PARAM_REREAD_LOG_CFG_FILE(1);
  126. ///带参数日志模块初始化,以上所有设置了的参数都将生效,没有设置的采用缺省值
  127. LOG4C_INIT_WITH_PARAM();
  128. if( ProgramEncrypt(NULL) == 0 ) return FALSE;
  129. g_pDevicesManager = new CDevicesManager();
  130. // 初始化软件狗
  131. #if IS_USE_DOG
  132. if( InitDog() != 0 )
  133. {
  134. if( g_hRunObject != NULL )
  135. {
  136. MTVERIFY( CloseHandle( g_hRunObject ) );
  137. g_hRunObject = NULL;
  138. }
  139. return FALSE;
  140. }
  141. #endif
  142. //LOG4C((LOG_NOTICE, "%s", g_strConnectString));
  143. //连接数据库
  144. //LOG4C((LOG_NOTICE, "Enter OpenDataBase"));
  145. CDBConnection::GetInstancePtr()->OpenDataBase(g_strConnectString);
  146. //LOG4C((LOG_NOTICE, "Leave OpenDataBase"));
  147. //LOG4C((LOG_NOTICE, "Enter DBConnectionCheckThreadStart"));
  148. CDBConnection::GetInstancePtr()->DBConnectionCheckThreadStart();
  149. //LOG4C((LOG_NOTICE, "Leave DBConnectionCheckThreadStart"));
  150. //LOG4C((LOG_NOTICE, "Enter SetDBType"));
  151. CDBInterface::GetInstancePtr()->SetDBType(g_strDBType);
  152. //LOG4C((LOG_NOTICE, "Leave SetDBType"));
  153. //LOG4C((LOG_NOTICE, "Enter InitUserRoleInfo"));
  154. // 分配用户角色
  155. CDBInterface::GetInstancePtr()->InitUserRoleInfo();
  156. //LOG4C((LOG_NOTICE, "Leave InitUserRoleInfo"));
  157. //LOG4C((LOG_NOTICE, "Enter InitNotice"));
  158. MTVERIFY( g_hDeleteVarSem = CreateEvent(NULL, TRUE, TRUE, "DeleteVarList") );
  159. InitializeCriticalSection( &g_csVarNotice );
  160. InitializeCriticalSection( &g_csSendNotice );
  161. if( g_nSendNotice )
  162. {
  163. InitNotice();
  164. }
  165. else
  166. LOG4C((LOG_NOTICE, "没有启用语言报警"));
  167. // 初始化Sms
  168. if( g_nSendSms==1 )
  169. {
  170. CString strCommPort = CString(g_strSmsComPort);
  171. strCommPort = strCommPort.Mid( 3 );
  172. if( 0==InitSms( 0, atoi(strCommPort), g_nSmsRate, g_nSmsDataBit,
  173. g_nSmsStopBit, g_nSmsParity, g_nSmsInterval, g_nSmsLanguageTrans, g_nSmsMaxChar, g_nSmsMakeCall ) )
  174. {
  175. #if 1
  176. if( pSmsDllSetCallBack )
  177. {
  178. LOG4C((LOG_NOTICE, "启用短信回调函数"));
  179. pSmsDllSetCallBack( Sms_NoticeConfig );
  180. }
  181. #endif
  182. }
  183. }
  184. else if( g_nSendSms==2 )
  185. {
  186. LOG4C((LOG_NOTICE, "启用支持短信平台服务"));
  187. }
  188. else
  189. LOG4C((LOG_NOTICE, "没有启用短信报警"));
  190. // 初始化Email
  191. if( g_nSendEmail )
  192. {
  193. InitEmail(g_strEmailSMTPSrv, g_nEmailSMTPPort, g_nEmailIsNeed, g_strEmailUserAcc, g_strEmailUserPwd,
  194. g_strEmailFromAddr, g_nEmailTimeOut);
  195. }
  196. else
  197. LOG4C((LOG_NOTICE, "没有启用email报警"));
  198. #if 0
  199. // Tcp服务器
  200. g_pTcpServer = new CServerSocket();
  201. CString strPort;
  202. strPort.Format("%d", SOCKET_SERVER_PORT);
  203. g_pTcpServer->SvrStart(strPort);
  204. #else
  205. //LOG4C((LOG_NOTICE, "open listen port"));
  206. // Tcp服务器
  207. g_pServerSocket[0] = new CServerSocket();
  208. CString strPort;
  209. strPort.Format("%d", SOCKET_SERVER_PORT);
  210. g_pServerSocket[0]->SvrStart(strPort);
  211. #endif
  212. InitPing();
  213. // 开始采集I/O设备
  214. StartMain();
  215. LOG4C((LOG_NOTICE, "system startup success!"));
  216. while(g_status.dwCurrentState != SERVICE_STOP_PENDING)
  217. {
  218. Sleep(1000);
  219. }
  220. LOG4C((LOG_NOTICE, _T("Service stopped")));
  221. UnInitIOService();
  222. return TRUE;
  223. }
  224. void UnInitIOService()
  225. {
  226. MTVERIFY( SetEvent( g_hDeleteVarSem ) );
  227. DeleteCriticalSection( &g_csVarNotice );
  228. DeleteCriticalSection( &g_csSendNotice );
  229. if( g_hDeleteVarSem )
  230. {
  231. MTVERIFY( CloseHandle( g_hDeleteVarSem) );
  232. g_hDeleteVarSem = NULL;
  233. }
  234. if (g_hRunObject != NULL)
  235. MTVERIFY( SetEvent( g_hRunObject ) );
  236. EndMain();
  237. #if 0
  238. if (g_pTcpServer != NULL)
  239. {
  240. g_pTcpServer->SocketStop();
  241. delete g_pTcpServer;
  242. g_pTcpServer = NULL;
  243. }
  244. #else
  245. for( int i = 0; i < MAX_SERVER_LISTEN; i++ )
  246. {
  247. if( NULL != g_pServerSocket[i] )
  248. {
  249. g_pServerSocket[i]->SocketStop();
  250. delete g_pServerSocket[i];
  251. g_pServerSocket[i] = NULL;
  252. }
  253. }
  254. #endif
  255. UnInitRtuDll();
  256. UnInitTcpDll();
  257. UnInitAscDll();
  258. UnInitIcpdasDll();
  259. UnInitSnmpDll();
  260. UnInitParadigmDll();
  261. UnInitStulzDll();
  262. UnInitSeparateDll();
  263. UnInitNotice();
  264. if( g_nSendEmail )
  265. {
  266. UnInitEmail();
  267. }
  268. if( g_nSendSms==1 )
  269. {
  270. UnInitSms();
  271. }
  272. //回收用户角色
  273. CDBInterface::GetInstancePtr()->UnInitUserRoleInfo();
  274. CDBConnection::GetInstancePtr()->DBConnectionCheckThreadStop();
  275. // 释放软件狗
  276. #if IS_USE_DOG
  277. UnInitDog();
  278. #endif
  279. if( g_pDevicesManager )
  280. {
  281. delete g_pDevicesManager;
  282. g_pDevicesManager = NULL;
  283. }
  284. if( g_hRunObject != NULL )
  285. {
  286. MTVERIFY( CloseHandle( g_hRunObject ) );
  287. }
  288. if(g_hLangDLL)
  289. {
  290. AfxFreeLibrary(g_hLangDLL);
  291. }
  292. UnInitPing();
  293. ///关闭日志模块防止内存/资源泄漏
  294. LOG4C_FINI();
  295. }
  296. //*********************************************************
  297. //Functiopn: Init
  298. //Description: 初始化
  299. //Calls: main
  300. //Called By:
  301. //Table Accessed:
  302. //Table Updated:
  303. //Input:
  304. //Output:
  305. //Return:
  306. //Others:
  307. //History:
  308. // <author>niying <time>2006-8-10 <version> <desc>
  309. //*********************************************************
  310. void Init()
  311. {
  312. g_hServiceStatus = NULL;
  313. g_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  314. g_status.dwCurrentState = SERVICE_STOPPED;
  315. g_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
  316. g_status.dwWin32ExitCode = 0;
  317. g_status.dwServiceSpecificExitCode = 0;
  318. g_status.dwCheckPoint = 0;
  319. g_status.dwWaitHint = 0;
  320. }
  321. //*********************************************************
  322. //Functiopn: ServiceMain
  323. //Description: 服务主函数,这在里进行控制对服务控制的注册
  324. //Calls:
  325. //Called By:
  326. //Table Accessed:
  327. //Table Updated:
  328. //Input:
  329. //Output:
  330. //Return:
  331. //Others:
  332. //History:
  333. // <author>niying <time>2006-8-10 <version> <desc>
  334. //*********************************************************
  335. void WINAPI ServiceMain()
  336. {
  337. // Register the control request handler
  338. g_status.dwCurrentState = SERVICE_START_PENDING;
  339. g_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
  340. //注册服务控制
  341. g_hServiceStatus = RegisterServiceCtrlHandler(g_szServiceName, ServiceStrl);
  342. if (g_hServiceStatus == NULL)
  343. {
  344. return;
  345. }
  346. SetServiceStatus(g_hServiceStatus, &g_status);
  347. g_status.dwWin32ExitCode = S_OK;
  348. g_status.dwCheckPoint = 0;
  349. g_status.dwWaitHint = 0;
  350. g_status.dwCurrentState = SERVICE_RUNNING;
  351. SetServiceStatus(g_hServiceStatus, &g_status);
  352. //延时10S,开机自启动时,等待串口服务器和数据库都启动完再开始服务
  353. #if 0
  354. int i = 0;
  355. while (i < 11)
  356. {
  357. Sleep(1000);
  358. i++;
  359. }
  360. //
  361. #endif
  362. InitIOService();
  363. g_status.dwCurrentState = SERVICE_STOPPED;
  364. SetServiceStatus(g_hServiceStatus, &g_status);
  365. }
  366. //*********************************************************
  367. //Functiopn: ServiceStrl
  368. //Description: 服务控制主函数,这里实现对服务的控制,
  369. // 当在服务管理器上停止或其它操作时,将会运行此处代码
  370. //Calls:
  371. //Called By:
  372. //Table Accessed:
  373. //Table Updated:
  374. //Input: dwOpcode:控制服务的状态
  375. //Output:
  376. //Return:
  377. //Others:
  378. //History:
  379. // <author>niying <time>2006-8-10 <version> <desc>
  380. //*********************************************************
  381. void WINAPI ServiceStrl(DWORD dwOpcode)
  382. {
  383. switch (dwOpcode)
  384. {
  385. case SERVICE_CONTROL_STOP:
  386. //UnInitIOService();
  387. g_status.dwCurrentState = SERVICE_STOP_PENDING;
  388. SetServiceStatus(g_hServiceStatus, &g_status);
  389. PostThreadMessage(dwThreadID, WM_CLOSE, 0, 0);
  390. break;
  391. case SERVICE_CONTROL_PAUSE:
  392. break;
  393. case SERVICE_CONTROL_CONTINUE:
  394. break;
  395. case SERVICE_CONTROL_INTERROGATE:
  396. break;
  397. case SERVICE_CONTROL_SHUTDOWN:
  398. UnInitIOService();
  399. break;
  400. default:
  401. LOG4C((LOG_NOTICE, _T("Bad service request")));
  402. }
  403. }
  404. //*********************************************************
  405. //Functiopn: IsInstalled
  406. //Description: 判断服务是否已经被安装
  407. //Calls:
  408. //Called By:
  409. //Table Accessed:
  410. //Table Updated:
  411. //Input:
  412. //Output:
  413. //Return:
  414. //Others:
  415. //History:
  416. // <author>niying <time>2006-8-10 <version> <desc>
  417. //*********************************************************
  418. BOOL IsInstalled()
  419. {
  420. BOOL bResult = FALSE;
  421. //打开服务控制管理器
  422. SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  423. if (hSCM != NULL)
  424. {
  425. //打开服务
  426. SC_HANDLE hService = ::OpenService(hSCM, g_szServiceName, SERVICE_QUERY_CONFIG);
  427. if (hService != NULL)
  428. {
  429. bResult = TRUE;
  430. ::CloseServiceHandle(hService);
  431. }
  432. ::CloseServiceHandle(hSCM);
  433. }
  434. return bResult;
  435. }
  436. //*********************************************************
  437. //Functiopn: Install
  438. //Description: 安装服务函数
  439. //Calls:
  440. //Called By:
  441. //Table Accessed:
  442. //Table Updated:
  443. //Input:
  444. //Output:
  445. //Return:
  446. //Others:
  447. //History:
  448. // <author>niying <time>2006-8-10 <version> <desc>
  449. //*********************************************************
  450. BOOL Install()
  451. {
  452. if (IsInstalled())
  453. return TRUE;
  454. //打开服务控制管理器
  455. SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  456. if (hSCM == NULL)
  457. {
  458. //MessageBox(NULL, _T("Couldn't open service manager"), g_szServiceName, MB_OK);
  459. return FALSE;
  460. }
  461. // Get the executable file path
  462. TCHAR szFilePath[MAX_PATH];
  463. ::GetModuleFileName(NULL, szFilePath, MAX_PATH);
  464. //创建服务
  465. SC_HANDLE hService = ::CreateService(
  466. hSCM,
  467. g_szServiceName,
  468. g_szServiceName,
  469. SERVICE_ALL_ACCESS,
  470. SERVICE_WIN32_OWN_PROCESS,
  471. SERVICE_DEMAND_START, //SERVICE_AUTO_START,
  472. SERVICE_ERROR_NORMAL,
  473. szFilePath,
  474. NULL,
  475. NULL,
  476. _T(""),
  477. NULL,
  478. NULL);
  479. SERVICE_DESCRIPTION ServiceDesc;
  480. static TCHAR szDescription[MAX_PATH];
  481. _tcscpy(szDescription, g_strServiceName);
  482. ServiceDesc.lpDescription = szDescription;
  483. ::ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &ServiceDesc);
  484. if (hService == NULL)
  485. {
  486. ::CloseServiceHandle(hSCM);
  487. //MessageBox(NULL, _T("Couldn't create service"), g_szServiceName, MB_OK);
  488. return FALSE;
  489. }
  490. ::CloseServiceHandle(hService);
  491. ::CloseServiceHandle(hSCM);
  492. return TRUE;
  493. }
  494. //*********************************************************
  495. //Functiopn: Uninstall
  496. //Description: 删除服务函数
  497. //Calls:
  498. //Called By:
  499. //Table Accessed:
  500. //Table Updated:
  501. //Input:
  502. //Output:
  503. //Return:
  504. //Others:
  505. //History:
  506. // <author>niying <time>2006-8-10 <version> <desc>
  507. //*********************************************************
  508. BOOL Uninstall()
  509. {
  510. if (!IsInstalled())
  511. return TRUE;
  512. SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  513. if (hSCM == NULL)
  514. {
  515. //MessageBox(NULL, _T("Couldn't open service manager"), g_szServiceName, MB_OK);
  516. return FALSE;
  517. }
  518. SC_HANDLE hService = ::OpenService(hSCM, g_szServiceName, SERVICE_STOP | DELETE);
  519. if (hService == NULL)
  520. {
  521. ::CloseServiceHandle(hSCM);
  522. //MessageBox(NULL, _T("Couldn't open service"), g_szServiceName, MB_OK);
  523. return FALSE;
  524. }
  525. SERVICE_STATUS g_status;
  526. ::ControlService(hService, SERVICE_CONTROL_STOP, &g_status);
  527. //删除服务
  528. BOOL bDelete = ::DeleteService(hService);
  529. ::CloseServiceHandle(hService);
  530. ::CloseServiceHandle(hSCM);
  531. if (bDelete)
  532. return TRUE;
  533. LOG4C((LOG_NOTICE, _T("Service could not be deleted")));
  534. return FALSE;
  535. }