Service.cpp 14 KB

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