HJUnzipDlg.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. // JHUnzipDlg.cpp : 实现文件
  2. //
  3. #include "stdafx.h"
  4. #include "HJUnzip.h"
  5. #include "HJUnzipDlg.h"
  6. #include "afxdialogex.h"
  7. #include "../jsonLib/json/json.h"
  8. #include "../ZLibWrapLib/ZLibWrapLib.h"
  9. #include "../Util/Util.h"
  10. #include "../Util/typedef_struct.h"
  11. #include "UnZipService.h"
  12. #include "shlwapi.h"
  13. #include <io.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #ifdef _DEBUG
  17. #define new DEBUG_NEW
  18. #endif
  19. extern HWND g_hMain;
  20. #define TIMER_HEART 0x1000
  21. CLog g_log;
  22. extern CDataBaseService g_dataBaseService;
  23. void RestoreBatchDB(int resid, wstring strPath);
  24. CHJUnzipDlg::CHJUnzipDlg(CWnd* pParent /*=NULL*/)
  25. : CDialogEx(CHJUnzipDlg::IDD, pParent)
  26. {
  27. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  28. InitializeCriticalSection(&m_criticalIdsLock);
  29. }
  30. void CHJUnzipDlg::DoDataExchange(CDataExchange* pDX)
  31. {
  32. CDialogEx::DoDataExchange(pDX);
  33. }
  34. BEGIN_MESSAGE_MAP(CHJUnzipDlg, CDialogEx)
  35. ON_WM_PAINT()
  36. ON_WM_QUERYDRAGICON()
  37. ON_WM_COPYDATA()
  38. ON_WM_TIMER()
  39. END_MESSAGE_MAP()
  40. BOOL CHJUnzipDlg::OnInitDialog()
  41. {
  42. CDialogEx::OnInitDialog();
  43. SetIcon(m_hIcon, TRUE); // 设置大图标
  44. SetIcon(m_hIcon, FALSE); // 设置小图标
  45. ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW); //隐藏任务栏
  46. WINDOWPLACEMENT wp;
  47. wp.length = sizeof(WINDOWPLACEMENT);
  48. wp.flags = WPF_RESTORETOMAXIMIZED;
  49. wp.showCmd = SW_HIDE;
  50. SetWindowPlacement(&wp);
  51. GetModuleDir(m_strModuleDir);
  52. wstring strConfigPath = m_strModuleDir + L"config.ini";
  53. WCHAR share_dir[MAX_PATH] = { 0 };
  54. GetPrivateProfileString(_T("USER"), _T("share_path"), _T(""), share_dir, MAX_PATH, strConfigPath.c_str());
  55. m_strShareDir = share_dir;
  56. m_strScanExePath = m_strModuleDir;
  57. m_strScanExePath.append(L"ScanExe.exe");
  58. wstring _logdir(m_strModuleDir);
  59. _logdir.append(L"log");
  60. if (!PathIsDirectory(_logdir.c_str()))
  61. {
  62. ::CreateDirectory(_logdir.c_str(), 0);
  63. }
  64. wchar_t _logpath[1024] = { 0 };
  65. SYSTEMTIME systime;
  66. GetLocalTime(&systime);
  67. _stprintf(_logpath, L"%slog\\unzip_%04d%02d%02d.log", m_strModuleDir.c_str(),
  68. systime.wYear, systime.wMonth, systime.wDay);
  69. g_log.Init(UnicodeToGB2312(_logpath).c_str(), LogLvlInfo);
  70. HANDLE hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, NULL, SHARE_MEMORY_NAME);
  71. if (hMapFile)
  72. {
  73. LPVOID lpBase = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
  74. share_memory_block* _data_block = (share_memory_block*)lpBase;
  75. char szHandle[64] = { 0 };
  76. sprintf(szHandle, "%p", reinterpret_cast<long>(GetSafeHwnd()));
  77. strcpy(_data_block->unzip_handle, szHandle);
  78. UnmapViewOfFile(lpBase);
  79. CloseHandle(hMapFile);
  80. }
  81. SetTimer(TIMER_HEART, 10 * 1000, NULL);
  82. wstring _zipfiledir(m_strModuleDir);
  83. _zipfiledir.append(L"zipfile");
  84. if (!PathIsDirectory(_zipfiledir.c_str()))
  85. {
  86. ::CreateDirectory(_zipfiledir.c_str(), 0);
  87. }
  88. wstring _indexdir(m_strModuleDir);
  89. _indexdir.append(L"index.db3");
  90. if (!PathFileExists(_indexdir.c_str()))
  91. {
  92. RestoreBatchDB(IDR_DB_INDEX, _indexdir);
  93. }
  94. vector<int> vct;
  95. CUnZipService _unzip(_indexdir, vct);
  96. for (auto& iter : vct)
  97. {
  98. m_queueIds.push({ iter, 0, 0, 0 });
  99. }
  100. DetectZipFile();
  101. return TRUE;
  102. }
  103. DWORD WINAPI ThreadZipFile(LPVOID lpThreadParameter)
  104. {
  105. CHJUnzipDlg* _service = (CHJUnzipDlg*)lpThreadParameter;
  106. _service->DoDetectZipFile();
  107. return 0;
  108. }
  109. DWORD WINAPI ThreadScan(LPVOID lpThreadParameter)
  110. {
  111. CHJUnzipDlg* _service = (CHJUnzipDlg*)lpThreadParameter;
  112. _service->DoThreadScan();
  113. return 0;
  114. }
  115. void CHJUnzipDlg::DetectZipFile()
  116. {
  117. m_hThreadDetect = CreateThread(NULL, 0, ThreadZipFile, this, 0, 0);
  118. m_hThreadScan = CreateThread(NULL, 0, ThreadScan, this, 0, 0);
  119. }
  120. void CHJUnzipDlg::DoDetectZipFile()
  121. {
  122. while (true)
  123. {
  124. CFileFind finder;
  125. CString path;
  126. if (PathFileExists(m_strShareDir.c_str()))
  127. {
  128. path.Format(_T("%s/*.zip"), m_strShareDir.c_str());
  129. bool bWorking = finder.FindFile(path);
  130. if (bWorking)
  131. {
  132. finder.FindNextFile();
  133. wchar_t _zipfiledir[1024] = { 0 };
  134. _stprintf(_zipfiledir, L"%szipfile\\%s_%lld\\", m_strModuleDir.c_str(), finder.GetFileTitle(), std::time(0));
  135. ::CreateDirectory(_zipfiledir, 0);
  136. wstring _indexdbpath(m_strModuleDir);
  137. _indexdbpath.append(L"index.db3");
  138. wstring _batchdbpath(_zipfiledir);
  139. _batchdbpath.append(L"batch.db3");
  140. RestoreBatchDB(IDR_DB_BATCH, _batchdbpath);
  141. wstring _imagepath(_zipfiledir);
  142. _imagepath.append(L"papers");
  143. ::CreateDirectory(_imagepath.c_str(), 0);
  144. wstring _zipfilepath(_zipfiledir);
  145. _zipfilepath.append(finder.GetFileName());
  146. wstring _sharefilename(finder.GetFileTitle());
  147. wstring _sharefilepath(finder.GetFilePath());
  148. g_log.PutMsg(LogLvlInfo, "开始解压:%s", UnicodeToGB2312(_sharefilepath.c_str()).c_str());
  149. BOOL unzip_rlt = FALSE;
  150. int unzip_count = 3;
  151. while (unzip_count > 0)
  152. {
  153. unzip_rlt = ZipExtract(finder.GetFilePath(), _imagepath.c_str());
  154. if (unzip_rlt)
  155. {
  156. break;
  157. }
  158. else
  159. {
  160. unzip_count--;
  161. Sleep(60 * 1000);
  162. }
  163. }
  164. g_log.PutMsg(LogLvlInfo, "解压结束:%s,结果:%s", UnicodeToGB2312(_sharefilepath.c_str()).c_str(), unzip_rlt ? "成功" : "失败");
  165. wstring strZipPath = finder.GetFileTitle();
  166. string _zip_path = UnicodeToGB2312(strZipPath.c_str());
  167. char szParam[1024] = { 0 };
  168. sprintf(szParam, "【%s】解压%s", _zip_path.c_str(), unzip_rlt ? "成功" : "失败");
  169. SetShareMemoryData(szParam);
  170. CUnZipService _Service(_indexdbpath, _batchdbpath, _imagepath, _zipfiledir, _sharefilename, _sharefilepath);
  171. _Service.InsertBatchInfo();
  172. if (unzip_rlt)
  173. {
  174. int _last_id(0);
  175. bool _rlt = _Service.ParseImageDir(_last_id);
  176. if (_rlt)
  177. {
  178. ::EnterCriticalSection(&m_criticalIdsLock);
  179. m_queueIds.push({ _last_id, 0, 0, 0 });
  180. ::LeaveCriticalSection(&m_criticalIdsLock);
  181. sprintf(szParam, "【%s】入库成功", _zip_path.c_str());
  182. }
  183. else
  184. {
  185. sprintf(szParam, "【%s】试卷非偶数倍(仅支持JPG格式的图片)", _zip_path.c_str());
  186. }
  187. SetShareMemoryData(szParam);
  188. }
  189. else
  190. {
  191. _Service.InsertBatchFail(batch_exc_unzip, 0);
  192. }
  193. BOOL move_rlt = FALSE;
  194. int move_count = 3;
  195. while (move_count > 0)
  196. {
  197. move_rlt = MoveFile(finder.GetFilePath(), _zipfilepath.c_str());
  198. if (move_rlt)
  199. {
  200. break;
  201. }
  202. else
  203. {
  204. move_rlt--;
  205. Sleep(5 * 1000);
  206. }
  207. }
  208. g_log.PutMsg(LogLvlInfo, "入库成功:%s", UnicodeToGB2312(_sharefilepath.c_str()).c_str());
  209. }
  210. }
  211. Sleep(10000);
  212. }
  213. }
  214. void CHJUnzipDlg::DoThreadScan()
  215. {
  216. while (true)
  217. {
  218. ::EnterCriticalSection(&m_criticalIdsLock);
  219. if (!m_queueIds.empty())
  220. {
  221. tagScanPaper& _scanpaper = m_queueIds.front();
  222. if (_scanpaper.scan_umbers == 0)
  223. {
  224. _scanpaper.scan_time = std::time(0);
  225. _scanpaper.scan_umbers = 1;
  226. RunScanExe(_scanpaper.batch_id);
  227. char info[256] = { 0 };
  228. sprintf(info, "扫描批次号:%d 开始", _scanpaper.batch_id);
  229. g_log.PutMsg(LogLvlInfo, info);
  230. SetShareMemoryData(info);
  231. }
  232. else if ((std::time(0) - _scanpaper.scan_time) > 30)
  233. {
  234. wstring _indexdbpath(m_strModuleDir);
  235. _indexdbpath.append(L"index.db3");
  236. if (_scanpaper.paper_cnt == 0)
  237. {
  238. g_dataBaseService.GetBatchCount(_indexdbpath, _scanpaper.batch_id, _scanpaper.paper_cnt);
  239. }
  240. if (_scanpaper.scan_umbers < _scanpaper.paper_cnt + 1)
  241. {
  242. _scanpaper.scan_time = std::time(0);
  243. _scanpaper.scan_umbers++;
  244. RunScanExe(_scanpaper.batch_id);
  245. char info[256] = { 0 };
  246. sprintf(info, "扫描批次号:%d 崩溃,第%d次重启ScanExe.exe", _scanpaper.batch_id, _scanpaper.scan_umbers);
  247. g_log.PutMsg(LogLvlFailed, info);
  248. SetShareMemoryData(info);
  249. }
  250. else
  251. {
  252. int batch_id = _scanpaper.batch_id;
  253. m_queueIds.pop();
  254. KillProgress(L"ScanExe.exe");
  255. char info[256] = { 0 };
  256. sprintf(info, "扫描批次号:%d 崩溃,重试%d次仍崩溃,放弃本批次扫描", _scanpaper.batch_id, _scanpaper.scan_umbers);
  257. g_log.PutMsg(LogLvlFailed, info);
  258. SetShareMemoryData(info);
  259. g_dataBaseService.UpdateBatchSchemaErro(_indexdbpath, batch_id);
  260. }
  261. }
  262. }
  263. ::LeaveCriticalSection(&m_criticalIdsLock);
  264. Sleep(5000);
  265. }
  266. }
  267. void CHJUnzipDlg::RunScanExe(int batch_id)
  268. {
  269. KillProgress(L"ScanExe.exe");
  270. TCHAR szParam[1024] = { 0 };
  271. _stprintf(szParam, _T("window=%p batchid=%d"), reinterpret_cast<long>(GetSafeHwnd()), batch_id);
  272. PROCESS_INFORMATION _ProcStruct;
  273. STARTUPINFO StartInfo;
  274. memset(&StartInfo, 0, sizeof(STARTUPINFO));
  275. StartInfo.cb = sizeof(STARTUPINFO);
  276. if (::CreateProcess(
  277. (LPCTSTR)m_strScanExePath.c_str(),
  278. szParam,
  279. NULL,
  280. NULL,
  281. FALSE,
  282. CREATE_NO_WINDOW,
  283. NULL,
  284. NULL,
  285. &StartInfo,
  286. &_ProcStruct))
  287. {
  288. CloseHandle(_ProcStruct.hProcess);
  289. CloseHandle(_ProcStruct.hThread);
  290. }
  291. g_log.PutMsg(LogLvlInfo, "启动扫描程序,参数:%s", UnicodeToGB2312(szParam).c_str());
  292. }
  293. // 如果向对话框添加最小化按钮,则需要下面的代码
  294. // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
  295. // 这将由框架自动完成。
  296. void CHJUnzipDlg::OnPaint()
  297. {
  298. if (IsIconic())
  299. {
  300. CPaintDC dc(this); // 用于绘制的设备上下文
  301. SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
  302. // 使图标在工作区矩形中居中
  303. int cxIcon = GetSystemMetrics(SM_CXICON);
  304. int cyIcon = GetSystemMetrics(SM_CYICON);
  305. CRect rect;
  306. GetClientRect(&rect);
  307. int x = (rect.Width() - cxIcon + 1) / 2;
  308. int y = (rect.Height() - cyIcon + 1) / 2;
  309. // 绘制图标
  310. dc.DrawIcon(x, y, m_hIcon);
  311. }
  312. else
  313. {
  314. CDialogEx::OnPaint();
  315. }
  316. }
  317. BOOL CHJUnzipDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
  318. {
  319. if (pCopyDataStruct && pCopyDataStruct->lpData && pCopyDataStruct->cbData > 0)
  320. {
  321. ::EnterCriticalSection(&m_criticalIdsLock);
  322. std::string str((char*)pCopyDataStruct->lpData, pCopyDataStruct->cbData);
  323. if (SCANEXE_HEART == str)
  324. {
  325. tagScanPaper& _scanpaper = m_queueIds.front();
  326. _scanpaper.scan_time = std::time(0);
  327. }
  328. else if (SCANEXE_DONE == str)
  329. {
  330. if (!m_queueIds.empty())
  331. {
  332. tagScanPaper _scanpaper = m_queueIds.front();
  333. m_queueIds.pop();
  334. KillProgress(L"ScanExe.exe");
  335. char info[256] = { 0 };
  336. sprintf(info, "扫描批次号:%d 完成,一共尝试了%d次扫描", _scanpaper.batch_id, _scanpaper.scan_umbers);
  337. g_log.PutMsg(LogLvlInfo, info);
  338. SetShareMemoryData(info);
  339. }
  340. }
  341. else if (str.find(UNHANDL_RESCAN) != std::string::npos)
  342. {
  343. vector<string> _vct;
  344. split(str, ":", _vct);
  345. if (_vct.size() > 1)
  346. {
  347. m_queueIds.push({ atoi(_vct[1].c_str()), 0, 0, 0 });
  348. }
  349. }
  350. ::LeaveCriticalSection(&m_criticalIdsLock);
  351. }
  352. return CWnd::OnCopyData(pWnd, pCopyDataStruct);
  353. }
  354. //当用户拖动最小化窗口时系统调用此函数取得光标
  355. //显示。
  356. HCURSOR CHJUnzipDlg::OnQueryDragIcon()
  357. {
  358. return static_cast<HCURSOR>(m_hIcon);
  359. }
  360. void CHJUnzipDlg::OnTimer(UINT_PTR nIDEvent)
  361. {
  362. // TODO: 在此添加消息处理程序代码和/或调用默认值
  363. switch (nIDEvent)
  364. {
  365. default:
  366. break;
  367. case TIMER_HEART:
  368. {
  369. HANDLE hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, NULL, SHARE_MEMORY_NAME);
  370. if (hMapFile)
  371. {
  372. LPVOID lpBase = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
  373. share_memory_block* _data_block = (share_memory_block*)lpBase;
  374. _data_block->unzip_tickcount = std::time(0);
  375. UnmapViewOfFile(lpBase);
  376. CloseHandle(hMapFile);
  377. }
  378. else
  379. {
  380. HANDLE hself = GetCurrentProcess();
  381. TerminateProcess(hself, 0);
  382. ::WaitForSingleObject(hself, INFINITE);
  383. CloseHandle(hself);
  384. }
  385. }
  386. break;
  387. }
  388. }
  389. void CHJUnzipDlg::SetShareMemoryData(char* szParam)
  390. {
  391. HANDLE hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, NULL, SHARE_MEMORY_NAME);
  392. if (hMapFile)
  393. {
  394. LPVOID lpBase = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
  395. share_memory_block* _data_block = (share_memory_block*)lpBase;
  396. _data_block->unzip_tickcount = std::time(0);
  397. strcpy(_data_block->msg_info, szParam);
  398. UnmapViewOfFile(lpBase);
  399. CloseHandle(hMapFile);
  400. }
  401. else
  402. {
  403. HANDLE hself = GetCurrentProcess();
  404. TerminateProcess(hself, 0);
  405. ::WaitForSingleObject(hself, INFINITE);
  406. CloseHandle(hself);
  407. }
  408. }
  409. void RestoreBatchDB(int resid, wstring strPath)
  410. {
  411. HRSRC hrsrc = FindResource(theApp.m_hInstance, MAKEINTRESOURCE(resid), L"db");
  412. HANDLE hglob = LoadResource(theApp.m_hInstance, hrsrc);
  413. char* _buf = (char*)LockResource(hglob);
  414. unsigned int _len = SizeofResource(theApp.m_hInstance, hrsrc);
  415. CFile file;
  416. file.Open(strPath.c_str(), CFile::modeCreate | CFile::modeWrite);
  417. file.Write(_buf, _len);
  418. file.Close();
  419. FreeResource(hglob);
  420. }