MainWindow.xaml.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. using DeviceCenter.model;
  2. using DeviceCenter.utils;
  3. using DeviceCenter.views;
  4. using FluentScheduler;
  5. using log4net;
  6. using Microsoft.Win32;
  7. using Notifications.Wpf;
  8. using System;
  9. using System.Collections.ObjectModel;
  10. using System.Drawing;
  11. using System.IO;
  12. using System.Linq;
  13. using System.Runtime.InteropServices;
  14. using System.Text;
  15. using System.Threading;
  16. using System.Threading.Tasks;
  17. using System.Windows;
  18. using System.Windows.Interop;
  19. namespace DeviceCenter
  20. {
  21. /// <summary>
  22. /// MainWindow.xaml 的交互逻辑
  23. /// </summary>
  24. public partial class MainWindow : Window
  25. {
  26. public static readonly ILog log = LogManager.GetLogger("DeviceCenter");
  27. private NotificationManager notificationManager = new NotificationManager();
  28. private ObservableCollection<Device> devices = new ObservableCollection<Device>();
  29. private Config config = Config.getInstance();
  30. private CHCNetSDK.MSGCallBack alarmCallback = null;
  31. private static CarCamSDK.FGetImageCB2 carPlateCallback;
  32. private int m_lGetCardCfgHandle = -1;
  33. private CHCNetSDK.RemoteConfigCallback g_fGetGatewayCardCallback = null;
  34. private System.Windows.Forms.NotifyIcon notifyIcon = null;
  35. private System.Windows.Forms.ContextMenu contextMenuExit;
  36. private System.Windows.Forms.MenuItem menuItem1;
  37. private System.Windows.Forms.MenuItem menuItem2;
  38. private System.ComponentModel.IContainer components;
  39. public MainWindow()
  40. {
  41. InitializeComponent();
  42. notifyIcon = new System.Windows.Forms.NotifyIcon();
  43. notifyIcon.Click += new EventHandler(notifyIcon_Click);
  44. notifyIcon.Icon = new Icon("assets\\icon.ico");
  45. components = new System.ComponentModel.Container();
  46. contextMenuExit = new System.Windows.Forms.ContextMenu();
  47. menuItem1 = new System.Windows.Forms.MenuItem();
  48. menuItem2 = new System.Windows.Forms.MenuItem();
  49. // Initialize contextMenuExit
  50. this.contextMenuExit.MenuItems.AddRange(
  51. new System.Windows.Forms.MenuItem[] { this.menuItem1, menuItem2 });
  52. // Initialize menuItem1
  53. this.menuItem1.Index = 0;
  54. this.menuItem1.Text = "退出";
  55. this.menuItem1.Click += new EventHandler(this.menuItem1_Click);
  56. menuItem2.Index = 1;
  57. menuItem2.Text = "开机自启";
  58. menuItem2.Click += new EventHandler(this.menuItem2_Click);
  59. menuItem2.Checked = AppUtil.isAutoStart();
  60. notifyIcon.ContextMenu = this.contextMenuExit;
  61. initSdk();
  62. lv_device.ItemsSource = devices;
  63. //System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
  64. //dispatcherTimer.Tick += GetAllCard;
  65. //dispatcherTimer.Interval = new TimeSpan(0, 0, 5);
  66. //dispatcherTimer.Start();
  67. //System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
  68. //timer.Tick += (s, e) =>
  69. //{
  70. // ((System.Windows.Threading.DispatcherTimer)s).Stop();
  71. // GetAllCard(null, null);
  72. //};
  73. //timer.Interval = new TimeSpan(0, 0, 5);
  74. //timer.Start();
  75. ScheduleJob();
  76. }
  77. private void ScheduleJob()
  78. {
  79. JobManager.Initialize();
  80. JobManager.AddJob(
  81. () =>
  82. {
  83. DateTime now = DateTime.Now;
  84. DateTime start = new DateTime(now.Year, now.Month, now.Day, 0, 0, 0);
  85. DateTime end = new DateTime(now.Year, now.Month, now.Day, 23, 59, 59);
  86. foreach (Device device in devices)
  87. {
  88. if (device.status == DeviceStatus.CONNECTED && device.type == DeviceType.ACS)
  89. {
  90. ((AcsDevice)device).getEvent(start, end);
  91. }
  92. }
  93. },
  94. s => s.ToRunEvery(1).Days().At(3, 0)
  95. );
  96. }
  97. private void Window_Loaded(object sender, RoutedEventArgs e)
  98. {
  99. notifyIcon.Visible = true;
  100. string imageDir = AppDomain.CurrentDomain.BaseDirectory + "Picture";
  101. if (!Directory.Exists(imageDir))
  102. {
  103. Directory.CreateDirectory(imageDir);
  104. }
  105. }
  106. private void notifyIcon_Click(object sender, EventArgs e)
  107. {
  108. Show();
  109. }
  110. private void menuItem1_Click(object Sender, EventArgs e)
  111. {
  112. ExitConfirm ex = new ExitConfirm();
  113. if (ex.ShowDialog() ?? false)
  114. {
  115. if (ex.password.Password == config.password)
  116. {
  117. notifyIcon.Dispose();
  118. Application.Current.Shutdown();
  119. }
  120. else
  121. {
  122. notificationManager.Show(new NotificationContent
  123. {
  124. Title = "Error",
  125. Message = "密码错误",
  126. Type = NotificationType.Error
  127. });
  128. }
  129. }
  130. }
  131. private void menuItem2_Click(object Sender, EventArgs e)
  132. {
  133. if (AppUtil.isAutoStart())
  134. {
  135. AppUtil.disableAutoStart();
  136. menuItem2.Checked = false;
  137. }
  138. else
  139. {
  140. AppUtil.enableAutoStart();
  141. menuItem2.Checked = true;
  142. }
  143. }
  144. private async void initSdk()
  145. {
  146. await Task.Run(() =>
  147. {
  148. long ts = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();
  149. carPlateCallback = new CarCamSDK.FGetImageCB2(onGetCarPlate);
  150. CarCamSDK.Net_RegImageRecv2(carPlateCallback);
  151. //UsbSwitch.usb_relay_init();
  152. alarmCallback = new CHCNetSDK.MSGCallBack(onAlarm);
  153. if (CHCNetSDK.NET_DVR_SetDVRMessageCallBack_V50(0, alarmCallback, IntPtr.Zero))
  154. {
  155. log.Info("NET_DVR_SetDVRMessageCallBack_V50 Succeed");
  156. notificationManager.Show(new NotificationContent
  157. {
  158. Title = "Success",
  159. Message = "NET_DVR_SetDVRMessageCallBack_V50 Succeed",
  160. Type = NotificationType.Success
  161. });
  162. }
  163. else
  164. {
  165. notificationManager.Show(new NotificationContent
  166. {
  167. Title = "Error",
  168. Message = "NET_DVR_SetDVRMessageCallBack_V50 Fail",
  169. Type = NotificationType.Error
  170. });
  171. }
  172. notificationManager.Show(new NotificationContent
  173. {
  174. Title = "Info",
  175. Message = "init finish, toke " + (new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds() - ts) + "ms",
  176. Type = NotificationType.Information
  177. });
  178. Application.Current.Dispatcher.Invoke((Action)(() =>
  179. {
  180. config.devices.ForEach(i =>
  181. {
  182. i.Init();
  183. devices.Add(i);
  184. });
  185. }));
  186. });
  187. }
  188. private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
  189. {
  190. e.Cancel = true;
  191. Hide();
  192. }
  193. private void btn_add_device_Click(object sender, RoutedEventArgs e)
  194. {
  195. AddDevice addDevice = new AddDevice();
  196. if (addDevice.ShowDialog() ?? false)
  197. {
  198. config.devices.Add(addDevice.device);
  199. config.save();
  200. devices.Add(addDevice.device);
  201. addDevice.device.Init();
  202. }
  203. }
  204. private void btn_del_device_Click(object sender, RoutedEventArgs e)
  205. {
  206. //NotificationUtil.show("连接设备失败", "请检查网络");
  207. if (lv_device.SelectedIndex == -1)
  208. {
  209. return;
  210. }
  211. Console.WriteLine(lv_device.SelectedItem);
  212. MessageBoxResult messageBoxResult = MessageBox.Show("确认删除?", "提示", MessageBoxButton.YesNo);
  213. if (messageBoxResult == MessageBoxResult.Yes)
  214. {
  215. int i = lv_device.SelectedIndex;
  216. if (devices[i].status != DeviceStatus.IDLE)
  217. {
  218. devices[i].dispose();
  219. }
  220. devices.RemoveAt(i);
  221. config.devices.RemoveAt(i);
  222. config.save();
  223. // lv_device.Items.Refresh();
  224. }
  225. }
  226. private void onAlarm(int lCommand, ref CHCNetSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
  227. {
  228. switch (lCommand)
  229. {
  230. case CHCNetSDK.COMM_ALARM_ACS:
  231. ProcessCommAlarmACS(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
  232. break;
  233. default:
  234. break;
  235. }
  236. }
  237. private void ProcessCommAlarmACS(ref CHCNetSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
  238. {
  239. foreach (Device device in devices)
  240. {
  241. if (device.type == DeviceType.ACS)
  242. {
  243. AcsDevice acsDevice = (AcsDevice)device;
  244. if (acsDevice.userId == pAlarmer.lUserID)
  245. {
  246. acsDevice.onAlarm(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
  247. }
  248. }
  249. }
  250. }
  251. private int onGetCarPlate(int tHandle, uint uiImageId, ref CarCamSDK.T_ImageUserInfo2 tImageInfo, ref CarCamSDK.T_PicInfo tPicInfo)
  252. {
  253. foreach (Device device in devices)
  254. {
  255. if (device.type == DeviceType.ACS)
  256. {
  257. CarCamDevice carCamDevice = (CarCamDevice)device;
  258. if (tHandle == carCamDevice.userId)
  259. {
  260. return carCamDevice.onGetCarPlate(tHandle, uiImageId, ref tImageInfo, ref tPicInfo);
  261. }
  262. }
  263. }
  264. return 0;
  265. }
  266. private void GetAllCard(object source, EventArgs e)
  267. {
  268. int m_userId = -1;
  269. AcsDevice device = null;
  270. try
  271. {
  272. device = (AcsDevice)devices.First(i => i.type == DeviceType.ACS && i.status == DeviceStatus.CONNECTED);
  273. }
  274. catch { }
  275. if (device == null)
  276. {
  277. log.Info("no connected device");
  278. return;
  279. }
  280. m_userId = device.userId;
  281. if (-1 != m_lGetCardCfgHandle)
  282. {
  283. if (CHCNetSDK.NET_DVR_StopRemoteConfig(m_lGetCardCfgHandle))
  284. {
  285. m_lGetCardCfgHandle = -1;
  286. }
  287. }
  288. CHCNetSDK.NET_DVR_CARD_CFG_COND struCond = new CHCNetSDK.NET_DVR_CARD_CFG_COND();
  289. struCond.dwSize = (uint)Marshal.SizeOf(struCond);
  290. struCond.wLocalControllerID = 0;
  291. struCond.dwCardNum = 0xffffffff;
  292. struCond.byCheckCardNo = 1;
  293. int dwSize = Marshal.SizeOf(struCond);
  294. IntPtr ptrStruCond = Marshal.AllocHGlobal(dwSize);
  295. Marshal.StructureToPtr(struCond, ptrStruCond, false);
  296. g_fGetGatewayCardCallback = new CHCNetSDK.RemoteConfigCallback(ProcessGetGatewayCardCallback);
  297. m_lGetCardCfgHandle = CHCNetSDK.NET_DVR_StartRemoteConfig(m_userId, CHCNetSDK.NET_DVR_GET_CARD_CFG_V50, ptrStruCond, dwSize, g_fGetGatewayCardCallback, new WindowInteropHelper(this).Handle);
  298. if (m_lGetCardCfgHandle == -1)
  299. {
  300. log.Info(string.Format("NET_DVR_GET_CARD_CFG_V50 FAIL, ERROR CODE {0}", CHCNetSDK.NET_DVR_GetLastError()));
  301. Marshal.FreeHGlobal(ptrStruCond);
  302. return;
  303. }
  304. else
  305. {
  306. log.Info("SUCC NET_DVR_GET_CARD_CFG_V50");
  307. }
  308. Marshal.FreeHGlobal(ptrStruCond);
  309. }
  310. private void ProcessGetGatewayCardCallback(uint dwType, IntPtr lpBuffer, uint dwBufLen, IntPtr pUserData)
  311. {
  312. if (pUserData == null)
  313. {
  314. return;
  315. }
  316. if (dwType == (uint)CHCNetSDK.NET_SDK_CALLBACK_TYPE.NET_SDK_CALLBACK_TYPE_DATA)
  317. {
  318. CHCNetSDK.NET_DVR_CARD_CFG_V50 struCardCfg = new CHCNetSDK.NET_DVR_CARD_CFG_V50();
  319. struCardCfg = (CHCNetSDK.NET_DVR_CARD_CFG_V50)Marshal.PtrToStructure(lpBuffer, typeof(CHCNetSDK.NET_DVR_CARD_CFG_V50));
  320. string strCardNo = System.Text.Encoding.UTF8.GetString(struCardCfg.byCardNo);
  321. IntPtr pCardInfo = Marshal.AllocHGlobal(Marshal.SizeOf(struCardCfg));
  322. Marshal.StructureToPtr(struCardCfg, pCardInfo, true);
  323. CHCNetSDK.PostMessage(pUserData, 1003, (Int64)pCardInfo, 0);
  324. string cardNo = Encoding.UTF8.GetString(struCardCfg.byCardNo);
  325. string isValid = 1 == struCardCfg.byCardValid ? "YES" : "NO";
  326. string cardPasswod = Encoding.UTF8.GetString(struCardCfg.byCardPassword);
  327. string cardType = (struCardCfg.byCardType == 0 || struCardCfg.byCardType > 7) ?
  328. AcsDemoPublic.strCardType[0] : AcsDemoPublic.strCardType[struCardCfg.byCardType];
  329. string leaderCard = 1 == struCardCfg.byLeaderCard ? "YES" : "NO";
  330. string name = Encoding.UTF8.GetString(struCardCfg.byName);
  331. log.Info($"cardNo:{cardNo} name:{name} departmentNo:{struCardCfg.wDepartmentNo}");
  332. //var request = new RestRequest("staffInfo/saveStaffInfo", DataFormat.Json);
  333. //request.AddParameter("name", name);
  334. //request.AddParameter("cardNo", cardNo);
  335. //restClient.Post(request);
  336. }
  337. else if (dwType == (uint)CHCNetSDK.NET_SDK_CALLBACK_TYPE.NET_SDK_CALLBACK_TYPE_STATUS)
  338. {
  339. uint dwStatus = (uint)Marshal.ReadInt32(lpBuffer);
  340. if (dwStatus == (uint)CHCNetSDK.NET_SDK_CALLBACK_STATUS_NORMAL.NET_SDK_CALLBACK_STATUS_SUCCESS)
  341. {
  342. log.Info("NET_DVR_GET_CARD_CFG_V50 Get finish");
  343. CHCNetSDK.PostMessage(pUserData, 1002, 0, 0);
  344. }
  345. else if (dwStatus == (uint)CHCNetSDK.NET_SDK_CALLBACK_STATUS_NORMAL.NET_SDK_CALLBACK_STATUS_FAILED)
  346. {
  347. byte[] bRawData = new byte[40];//4字节状态 + 4字节错误码 + 32字节卡号
  348. Marshal.Copy(lpBuffer, bRawData, 0, 40);//将非托管内存指针数据复制到数组中
  349. byte[] errorb = new byte[4];//4字节错误码
  350. Array.Copy(bRawData, 4, errorb, 0, 4);
  351. int errorCode = BitConverter.ToInt32(errorb, 0);
  352. byte[] byCardNo = new byte[32];//32字节卡号
  353. Array.Copy(bRawData, 8, byCardNo, 0, 32);
  354. string strCardNo = Encoding.ASCII.GetString(byCardNo).TrimEnd('\0');
  355. log.Info(string.Format("NET_DVR_GET_CARD_CFG_V50 Get Failed,ErrorCode:{0},CardNo:{1}", errorCode, byCardNo));
  356. CHCNetSDK.PostMessage(pUserData, 1002, 0, 0);
  357. }
  358. }
  359. return;
  360. }
  361. public void getDepartments()
  362. {
  363. int m_userId = -1;
  364. AcsDevice device = null;
  365. try
  366. {
  367. device = (AcsDevice)devices.First(i => i.type == DeviceType.ACS && i.status == DeviceStatus.CONNECTED);
  368. }
  369. catch { }
  370. if (device == null)
  371. {
  372. log.Info("no connected device");
  373. return;
  374. }
  375. IntPtr lpRequestUrl = IntPtr.Zero;
  376. try
  377. {
  378. CHCNetSDK.NET_DVR_XML_CONFIG_INPUT input = new CHCNetSDK.NET_DVR_XML_CONFIG_INPUT();
  379. CHCNetSDK.NET_DVR_XML_CONFIG_INPUT output = new CHCNetSDK.NET_DVR_XML_CONFIG_INPUT();
  380. string url = "/ISAPI/AccessControl/DepartmentParam/capabilities";
  381. lpRequestUrl = Marshal.StringToHGlobalAnsi(url);
  382. input.lpRequestUrl = lpRequestUrl;
  383. IntPtr inputPtr = new IntPtr();
  384. IntPtr outputPtr = new IntPtr();
  385. Marshal.StructureToPtr(input, inputPtr, true);
  386. CHCNetSDK.NET_DVR_STDXMLConfig(m_userId, inputPtr, outputPtr);
  387. }
  388. catch (Exception e) { }
  389. finally
  390. {
  391. if (lpRequestUrl != IntPtr.Zero)
  392. {
  393. Marshal.FreeHGlobal(lpRequestUrl);
  394. }
  395. }
  396. }
  397. private void btn_upload_staff_Click(object sender, RoutedEventArgs e)
  398. {
  399. OpenFileDialog openFileDialog = new OpenFileDialog();
  400. openFileDialog.Filter = "Excel (*.xlsx)|*.xlsx";
  401. if (openFileDialog.ShowDialog() == true)
  402. {
  403. Console.WriteLine(openFileDialog.FileName);
  404. Boolean canOpen = false;
  405. try
  406. {
  407. FileStream fileStream = File.OpenRead(openFileDialog.FileName);
  408. canOpen = true;
  409. fileStream.Close();
  410. }
  411. catch (IOException ee)
  412. {
  413. MessageBox.Show(ee.Message);
  414. }
  415. if (canOpen)
  416. {
  417. notificationManager.Show(new NotificationContent
  418. {
  419. Title = "OK",
  420. Message = "上传成功",
  421. Type = NotificationType.Success
  422. });
  423. http.upload<string>("staffInfo/import", openFileDialog.FileName);
  424. }
  425. }
  426. }
  427. private void ProcessAcsEvent(ref CHCNetSDK.NET_DVR_ACS_EVENT_CFG struCFG, ref bool flag)
  428. {
  429. int employNo = (int)struCFG.struAcsEventInfo.dwEmployeeNo;
  430. string cardNo = Encoding.UTF8.GetString(struCFG.struAcsEventInfo.byCardNo).TrimEnd('\0');
  431. string time = $"{struCFG.struTime.dwYear:D4}-{struCFG.struTime.dwMonth:D2}-{struCFG.struTime.dwDay:D2} {struCFG.struTime.dwHour:D2}:{struCFG.struTime.dwMinute:D2}:{struCFG.struTime.dwSecond:D2}";
  432. log.Info($"receive acs event employNo:{employNo} cardNo:{cardNo} time:{time}");
  433. }
  434. private void Get_Event_Click(object sender, RoutedEventArgs e)
  435. {
  436. AskDate dialog = new AskDate();
  437. if (dialog.ShowDialog() ?? false)
  438. {
  439. foreach (Device device in devices)
  440. {
  441. if (device.status == DeviceStatus.CONNECTED && device.type == DeviceType.ACS)
  442. {
  443. ((AcsDevice)device).getEvent(dialog.start, dialog.end);
  444. }
  445. }
  446. }
  447. }
  448. }
  449. }