Browse Source

添加runtime包, 调用平台接口

weijw 11 months ago
parent
commit
98988bec46

+ 4 - 0
.editorconfig

@@ -0,0 +1,4 @@
+[*.cs]
+
+# CS8618: 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
+dotnet_diagnostic.CS8618.severity = none

+ 2 - 0
ConfigHelper.cs

@@ -39,6 +39,7 @@ namespace xicheji
             config.PLCIP = device?.Attribute("IP")?.Value ?? "";
             config.PLCPort = device?.Attribute("Port")?.Value ?? "";
             config.PLCType = Enum.Parse<CpuType>(device?.Attribute("Type")?.Value ?? "S7200");
+            config.PLCMacAddress = device?.Attribute("MacAddress")?.Value ?? "";
             config.PLCReceiveInterval = int.Parse(device?.Attribute("ReceiveInterval")?.Value ?? "2");
 
             var camera = xdoc.Root!.Element("Camera");
@@ -94,6 +95,7 @@ namespace xicheji
         public string PLCIP { get; set; } = string.Empty;
         public string PLCPort { get; set; } = string.Empty;
         public CpuType PLCType { get; set; } = CpuType.S7200;
+        public string PLCMacAddress { get; set; } = string.Empty;
         public int PLCReceiveInterval { get; set; } = 2;
         public string CameraIP { get; set; } = string.Empty;
         public string CameraPort { get; set; } = string.Empty;

+ 7 - 1
HomeModule.cs

@@ -16,9 +16,15 @@ namespace xicheji
                 return "ok~";
             });
 
+            Get("/update", (req) =>
+            {
+                Program.MainForm.UpdateTitle(DateTime.Now);
+                return "ok~";
+            });
+
             Post("/update-car", (req) =>
             {
-                Program.MainForm.UpdateCarInfo(DateTime.Now);
+                //TODO
                 return "ok~";
             });
         }

+ 61 - 33
MainForm.Designer.cs

@@ -30,7 +30,8 @@
         {
             components = new System.ComponentModel.Container();
             System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
-            pictureBox1 = new PictureBox();
+            DataGridViewCellStyle dataGridViewCellStyle1 = new DataGridViewCellStyle();
+            pbCamera = new PictureBox();
             nowTimer = new System.Windows.Forms.Timer(components);
             uploadTimer = new System.Windows.Forms.Timer(components);
             receivePLCTimer = new System.Windows.Forms.Timer(components);
@@ -38,7 +39,7 @@
             btnSetting = new Button();
             btnConnectCamera = new Button();
             panel1 = new Panel();
-            pictureBox7 = new PictureBox();
+            pbLogo = new PictureBox();
             panel2 = new Panel();
             panel11 = new Panel();
             lblCurrentElectricity = new Label();
@@ -69,6 +70,7 @@
             label1 = new Label();
             panel3 = new Panel();
             panel10 = new Panel();
+            cboCameraChannel = new ComboBox();
             dataGridView1 = new DataGridView();
             colCarNum = new DataGridViewTextBoxColumn();
             colStartTime = new DataGridViewTextBoxColumn();
@@ -84,9 +86,9 @@
             label11 = new Label();
             label13 = new Label();
             label10 = new Label();
-            ((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)pbCamera).BeginInit();
             panel1.SuspendLayout();
-            ((System.ComponentModel.ISupportInitialize)pictureBox7).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)pbLogo).BeginInit();
             panel2.SuspendLayout();
             panel11.SuspendLayout();
             ((System.ComponentModel.ISupportInitialize)pictureBox3).BeginInit();
@@ -102,14 +104,14 @@
             ((System.ComponentModel.ISupportInitialize)dataGridView1).BeginInit();
             SuspendLayout();
             // 
-            // pictureBox1
+            // pbCamera
             // 
-            pictureBox1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
-            pictureBox1.Location = new Point(29, 53);
-            pictureBox1.Name = "pictureBox1";
-            pictureBox1.Size = new Size(811, 286);
-            pictureBox1.TabIndex = 6;
-            pictureBox1.TabStop = false;
+            pbCamera.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+            pbCamera.Location = new Point(156, 53);
+            pbCamera.Name = "pbCamera";
+            pbCamera.Size = new Size(582, 286);
+            pbCamera.TabIndex = 6;
+            pbCamera.TabStop = false;
             // 
             // nowTimer
             // 
@@ -156,7 +158,7 @@
             btnConnectCamera.FlatAppearance.BorderSize = 0;
             btnConnectCamera.FlatStyle = FlatStyle.Flat;
             btnConnectCamera.Image = (Image)resources.GetObject("btnConnectCamera.Image");
-            btnConnectCamera.Location = new Point(846, 59);
+            btnConnectCamera.Location = new Point(848, 89);
             btnConnectCamera.Name = "btnConnectCamera";
             btnConnectCamera.Size = new Size(24, 24);
             btnConnectCamera.TabIndex = 0;
@@ -167,21 +169,21 @@
             // 
             panel1.Controls.Add(lblTime);
             panel1.Controls.Add(btnSetting);
-            panel1.Controls.Add(pictureBox7);
+            panel1.Controls.Add(pbLogo);
             panel1.Dock = DockStyle.Top;
             panel1.Location = new Point(0, 0);
             panel1.Name = "panel1";
             panel1.Size = new Size(1193, 48);
             panel1.TabIndex = 9;
             // 
-            // pictureBox7
+            // pbLogo
             // 
-            pictureBox7.Anchor = AnchorStyles.None;
-            pictureBox7.Location = new Point(541, 4);
-            pictureBox7.Name = "pictureBox7";
-            pictureBox7.Size = new Size(111, 40);
-            pictureBox7.TabIndex = 9;
-            pictureBox7.TabStop = false;
+            pbLogo.Anchor = AnchorStyles.None;
+            pbLogo.Location = new Point(541, 4);
+            pbLogo.Name = "pbLogo";
+            pbLogo.Size = new Size(111, 40);
+            pbLogo.TabIndex = 9;
+            pbLogo.TabStop = false;
             // 
             // panel2
             // 
@@ -478,6 +480,7 @@
             // panel10
             // 
             panel10.BackColor = Color.WhiteSmoke;
+            panel10.Controls.Add(cboCameraChannel);
             panel10.Controls.Add(dataGridView1);
             panel10.Controls.Add(panel12);
             panel10.Controls.Add(label12);
@@ -485,7 +488,7 @@
             panel10.Controls.Add(label11);
             panel10.Controls.Add(label13);
             panel10.Controls.Add(label10);
-            panel10.Controls.Add(pictureBox1);
+            panel10.Controls.Add(pbCamera);
             panel10.Controls.Add(btnConnectCamera);
             panel10.Dock = DockStyle.Fill;
             panel10.Location = new Point(16, 16);
@@ -493,6 +496,15 @@
             panel10.Size = new Size(899, 592);
             panel10.TabIndex = 7;
             // 
+            // cboCameraChannel
+            // 
+            cboCameraChannel.FormattingEnabled = true;
+            cboCameraChannel.Location = new Point(744, 53);
+            cboCameraChannel.Name = "cboCameraChannel";
+            cboCameraChannel.Size = new Size(128, 25);
+            cboCameraChannel.TabIndex = 10;
+            cboCameraChannel.SelectedIndexChanged += cboCameraChannel_SelectedIndexChanged;
+            // 
             // dataGridView1
             // 
             dataGridView1.AllowUserToAddRows = false;
@@ -503,6 +515,14 @@
             dataGridView1.Columns.AddRange(new DataGridViewColumn[] { colCarNum, colStartTime, colEndTime, colWashTime, colDryTime, colTotalWater, colTotalElectricity, colWaterPressure });
             dataGridView1.Location = new Point(29, 383);
             dataGridView1.Name = "dataGridView1";
+            dataGridViewCellStyle1.Alignment = DataGridViewContentAlignment.MiddleCenter;
+            dataGridViewCellStyle1.BackColor = SystemColors.Control;
+            dataGridViewCellStyle1.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
+            dataGridViewCellStyle1.ForeColor = SystemColors.WindowText;
+            dataGridViewCellStyle1.SelectionBackColor = SystemColors.Highlight;
+            dataGridViewCellStyle1.SelectionForeColor = SystemColors.HighlightText;
+            dataGridViewCellStyle1.WrapMode = DataGridViewTriState.True;
+            dataGridView1.RowHeadersDefaultCellStyle = dataGridViewCellStyle1;
             dataGridView1.RowTemplate.Height = 25;
             dataGridView1.Size = new Size(843, 196);
             dataGridView1.TabIndex = 8;
@@ -518,47 +538,54 @@
             colStartTime.DataPropertyName = "StartTime";
             colStartTime.HeaderText = "开始时间";
             colStartTime.Name = "colStartTime";
+            colStartTime.Width = 120;
             // 
             // colEndTime
             // 
             colEndTime.DataPropertyName = "EndTime";
             colEndTime.HeaderText = "结束时间";
             colEndTime.Name = "colEndTime";
+            colEndTime.Width = 120;
             // 
             // colWashTime
             // 
             colWashTime.DataPropertyName = "WashTime";
             colWashTime.HeaderText = "洗车时长";
             colWashTime.Name = "colWashTime";
+            colWashTime.Width = 80;
             // 
             // colDryTime
             // 
             colDryTime.DataPropertyName = "DryTime";
             colDryTime.HeaderText = "风干时长";
             colDryTime.Name = "colDryTime";
+            colDryTime.Width = 80;
             // 
             // colTotalWater
             // 
             colTotalWater.DataPropertyName = "TotalWater";
             colTotalWater.HeaderText = "用水量";
             colTotalWater.Name = "colTotalWater";
+            colTotalWater.Width = 80;
             // 
             // colTotalElectricity
             // 
             colTotalElectricity.DataPropertyName = "TotalElectricity";
             colTotalElectricity.HeaderText = "用电量";
             colTotalElectricity.Name = "colTotalElectricity";
+            colTotalElectricity.Width = 80;
             // 
             // colWaterPressure
             // 
             colWaterPressure.DataPropertyName = "WaterPressure";
             colWaterPressure.HeaderText = "水压";
             colWaterPressure.Name = "colWaterPressure";
+            colWaterPressure.Width = 80;
             // 
             // panel12
             // 
             panel12.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
-            panel12.BackColor = Color.FromArgb(64, 64, 64);
+            panel12.BackColor = Color.Gray;
             panel12.Location = new Point(29, 372);
             panel12.Name = "panel12";
             panel12.Size = new Size(843, 5);
@@ -627,10 +654,10 @@
             ShowIcon = false;
             Text = "Form1";
             Load += MainForm_Load;
-            ((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit();
+            ((System.ComponentModel.ISupportInitialize)pbCamera).EndInit();
             panel1.ResumeLayout(false);
             panel1.PerformLayout();
-            ((System.ComponentModel.ISupportInitialize)pictureBox7).EndInit();
+            ((System.ComponentModel.ISupportInitialize)pbLogo).EndInit();
             panel2.ResumeLayout(false);
             panel11.ResumeLayout(false);
             panel11.PerformLayout();
@@ -653,7 +680,7 @@
         }
 
         #endregion
-        private PictureBox pictureBox1;
+        private PictureBox pbCamera;
         private System.Windows.Forms.Timer nowTimer;
         private System.Windows.Forms.Timer uploadTimer;
         private System.Windows.Forms.Timer receivePLCTimer;
@@ -690,8 +717,16 @@
         private Label label10;
         private Panel panel12;
         private Label label13;
-        private PictureBox pictureBox7;
+        private PictureBox pbLogo;
         private DataGridView dataGridView1;
+        private Label lblError;
+        private Label lblStatus;
+        private Label lblTotalElectricity;
+        private Label lblTotalWater;
+        private Label lblWashCount;
+        private Label lblCurrentElectricity;
+        private Label lblCurrentWaterP;
+        private ComboBox cboCameraChannel;
         private DataGridViewTextBoxColumn colCarNum;
         private DataGridViewTextBoxColumn colStartTime;
         private DataGridViewTextBoxColumn colEndTime;
@@ -700,12 +735,5 @@
         private DataGridViewTextBoxColumn colTotalWater;
         private DataGridViewTextBoxColumn colTotalElectricity;
         private DataGridViewTextBoxColumn colWaterPressure;
-        private Label lblError;
-        private Label lblStatus;
-        private Label lblTotalElectricity;
-        private Label lblTotalWater;
-        private Label lblWashCount;
-        private Label lblCurrentElectricity;
-        private Label lblCurrentWaterP;
     }
 }

+ 341 - 96
MainForm.cs

@@ -1,6 +1,10 @@
 using Hik.Api;
+using Hik.Api.Data;
+using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
+using RestSharp;
 using S7.Net;
+using System.Drawing.Imaging;
 using System.Threading.Channels;
 using System.Windows.Forms;
 
@@ -10,8 +14,10 @@ namespace xicheji
     {
         private readonly Config config;
         private readonly List<WashRecord> washRecords = new();
+        private static DateTime logDate = DateTime.Now;
+        private static StreamWriter logWriter;
         private DateTime lastReceiveTime = DateTime.MinValue;
-        private byte[] currentDataBlock;
+        private byte[]? currentDataBlock;
         private Plc? plc = null;
         private HikApi? hikApi = null;
 
@@ -19,16 +25,20 @@ namespace xicheji
         {
             InitializeComponent();
             config = ConfigHelper.GetConfig();
+            logWriter = new StreamWriter(DateTime.Now.ToString("yyyy_MM_dd") + ".log");
         }
 
-
         private void MainForm_Load(object sender, EventArgs e)
         {
             try
             {
-                //测试数据
+                dataGridView1.AutoGenerateColumns = false;
+                dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
+
+                #region 测试代码: 表格数据
                 washRecords.Add(new WashRecord()
                 {
+                    DeviceId = "asdf",
                     CarNum = "京123456",
                     StartTime = new DateTime(2024, 6, 1, 12, 00, 00),
                     EndTime = new DateTime(2024, 6, 1, 12, 30, 00),
@@ -38,11 +48,12 @@ namespace xicheji
                     TotalWater = 2,
                     WaterPressure = 6,
                 });
+                #endregion
 
                 dataGridView1.DataSource = washRecords;
 
                 ConnectPLC();
-                //ConnectCamera();
+                ConnectCamera();
 
                 receivePLCTimer.Interval = config.PLCReceiveInterval * 1000;
                 receivePLCTimer.Enabled = true;
@@ -53,11 +64,20 @@ namespace xicheji
                 MessageBox.Show(ex.Message + ex.StackTrace);
             }
         }
-        private void btnConnectCamera_Click(object sender, EventArgs e)
+
+        private void btnSetting_Click(object sender, EventArgs e)
         {
             try
             {
-                ConnectCamera();
+                var settingForm = new SettingForm();
+                if (settingForm.ShowDialog() == DialogResult.OK)
+                {
+                    ConnectPLC();
+                    ConnectCamera();
+
+                    receivePLCTimer.Enabled = true;
+                    uploadTimer.Enabled = true;
+                }
             }
             catch (Exception ex)
             {
@@ -75,6 +95,33 @@ namespace xicheji
             catch { }
         }
 
+        public static void Log(object message)
+        {
+            if (message == null) return;
+            if (DateTime.Now.Date != logDate.Date)
+            {
+                logDate = DateTime.Now;
+                logWriter = new StreamWriter(DateTime.Now.ToString("yyyy_MM_dd") + ".log");
+            }
+
+            logWriter.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff> ") + " " + message);
+            logWriter.Flush();
+        }
+
+        #region 读PLC数据
+
+        private void ConnectPLC()
+        {
+            plc = new Plc(config.PLCType, config.PLCIP, int.Parse(config.PLCPort), 0, 1);
+            plc.Open();
+
+            if (!plc.IsConnected)
+            {
+                MessageBox.Show("PLC连接失败!");
+                return;
+            }
+        }
+
         private void receivePLCTimer_Tick(object sender, EventArgs e)
         {
             try
@@ -89,6 +136,7 @@ namespace xicheji
             }
             catch (Exception ex)
             {
+                receivePLCTimer.Enabled = false;
                 MessageBox.Show(ex.Message + ex.StackTrace);
             }
         }
@@ -105,6 +153,21 @@ namespace xicheji
                 ReadPLCInt("当前分"),
                 ReadPLCInt("当前秒"));
 
+            var macAddress = ReadMacAddress();
+            Log("macAddress: " + macAddress);
+
+            if (string.IsNullOrEmpty(config.PLCMacAddress))
+            {
+                //第一次配置为空时,更新一下mac地址
+                config.PLCMacAddress = macAddress;
+            }
+            //if (config.PLCMacAddress != macAddress)
+            //{
+            //    //以后还不匹配就提示
+            //    MessageBox.Show("PLC设备Mac地址不匹配,请确认!");
+            //    return;
+            //}
+
             if (time <= lastReceiveTime)
             {
                 //已经读过这个时间的了
@@ -122,6 +185,111 @@ namespace xicheji
             //.Text = ReadPLCStringValue("当前流量");
             lblCurrentElectricity.Text = ReadPLCString("当前功率");
             lblCurrentWaterP.Text = ReadPLCString("当前压力");
+
+            var myCrc = CRCCheck(currentDataBlock);
+            var readCrc = ReadPLCInt("CRC");
+            if (myCrc != readCrc)
+            {
+                //receivePLCTimer.Enabled = false;
+                //MessageBox.Show("CRC不匹配!");
+                //return;
+            }
+
+            if (ReadPLCInt("最后一次洗车开始月") != 0)
+            {
+                //洗车完成后才有数据的
+
+                var washStartTime = new DateTime(
+                    DateTime.Now.Year,
+                    ReadPLCInt("最后一次洗车开始月"),
+                    ReadPLCInt("最后一次洗车开始日"),
+                    ReadPLCInt("最后一次洗车开始时"),
+                    ReadPLCInt("最后一次洗车开始分"),
+                    ReadPLCInt("最后一次洗车开始秒"));
+
+                var washEndTime = new DateTime(
+                    DateTime.Now.Year,
+                    ReadPLCInt("最后一次洗车结束月"),
+                    ReadPLCInt("最后一次洗车结束日"),
+                    ReadPLCInt("最后一次洗车结束时"),
+                    ReadPLCInt("最后一次洗车结束分"),
+                    ReadPLCInt("最后一次洗车结束秒"));
+
+                var washRecord = new WashRecord()
+                {
+                    DeviceId = macAddress,
+                    CarNum = "",//TODO
+                    StartTime = washStartTime,
+                    EndTime = washEndTime,
+                    DryTime = ReadPLCInt("最后一次洗车风干时长"),
+                    TotalElectricity = ReadPLCInt("最后一次洗车用电"),
+                    TotalWater = ReadPLCInt("最后一次洗车用水"),
+                    WashTime = ReadPLCInt("最后一次洗车总时长"),
+                    WaterPressure = ReadPLCInt("最后一次洗车水压"),
+                };
+
+                washRecords.Add(washRecord);
+            }
+        }
+
+        private static readonly ushort[] crcTable = new ushort[256] {
+                0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+                0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
+                0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
+                0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
+                0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
+                0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
+                0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
+                0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
+                0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
+                0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
+                0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
+                0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
+                0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
+                0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
+                0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
+                0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
+                0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
+                0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
+                0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
+                0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
+                0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
+                0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+                0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
+                0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
+                0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
+                0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
+                0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
+                0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
+                0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
+                0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
+                0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
+                0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
+           };
+
+        private static ushort CRCCheck(byte[] data)
+        {
+            ushort crc = 0xFFFF;
+
+            foreach (byte b in data)
+            {
+                byte tableIndex = (byte)(((crc >> 8) ^ b) & 0xFF);
+                crc = (ushort)((crc << 8) ^ crcTable[tableIndex]);
+            }
+
+            return crc;
+        }
+
+        private string ReadMacAddress()
+        {
+            var mac1 = ReadPLCString("MAC1");
+            var mac2 = ReadPLCString("MAC2");
+            var mac3 = ReadPLCString("MAC3");
+            var mac4 = ReadPLCString("MAC4");
+            var mac5 = ReadPLCString("MAC5");
+            var mac6 = ReadPLCString("MAC6");
+
+            return $"{mac1:X4}:{mac2:X4}:{mac3:X4}:{mac4:X4}:{mac5:X4}:{mac6:X4}";
         }
 
         private void ReadStatus()
@@ -163,19 +331,24 @@ namespace xicheji
         private string ReadPLCString(string name)
         {
             var variable = ConfigHelper.FindVariable(name);
-            if (variable == null)
+            if (variable == null || currentDataBlock == null)
                 return string.Empty;
 
-            Parse(variable.Key, out _, out _, out var varType, out var address, out var bitNumber);
+            ParsePLCKey(variable.Key, out _, out _, out var varType, out var address, out var bitNumber);
             if (varType == VarType.DWord)
             {
                 var value = S7.Net.Types.DWord.FromByteArray(currentDataBlock.Take(new Range(address, address + 4)).ToArray());
-                return $"{value} {variable.Desc}";
+                return $"{value} {variable.Desc}".TrimEnd();
             }
             else if (varType == VarType.Word)
             {
                 var value = S7.Net.Types.Word.FromByteArray(currentDataBlock.Take(new Range(address, address + 2)).ToArray());
-                return $"{value} {variable.Desc}";
+                return $"{value} {variable.Desc}".TrimEnd();
+            }
+            else if (varType == VarType.Byte)
+            {
+                var value = S7.Net.Types.Byte.FromByteArray(currentDataBlock.Take(new Range(address, address + 1)).ToArray());
+                return $"{value} {variable.Desc}".TrimEnd();
             }
             return string.Empty;
         }
@@ -183,10 +356,10 @@ namespace xicheji
         private int ReadPLCInt(string name)
         {
             var variable = ConfigHelper.FindVariable(name);
-            if (variable == null)
+            if (variable == null || currentDataBlock == null)
                 return 0;
 
-            Parse(variable.Key, out var dataType, out var dbNumber, out var varType, out var address, out var bitNumber);
+            ParsePLCKey(variable.Key, out var dataType, out var dbNumber, out var varType, out var address, out var bitNumber);
             if (varType == VarType.DWord)
             {
                 var value = S7.Net.Types.DWord.FromByteArray(currentDataBlock.Take(new Range(address, address + 4)).ToArray());
@@ -203,87 +376,23 @@ namespace xicheji
         private bool ReadPLCBool(string name)
         {
             var variable = ConfigHelper.FindVariable(name);
-            if (variable == null)
+            if (variable == null || currentDataBlock == null)
                 return false;
 
-            Parse(variable.Key, out _, out _, out _, out var address, out var bitNumber);
+            ParsePLCKey(variable.Key, out _, out _, out _, out var address, out var bitNumber);
             var value = S7.Net.Types.Boolean.GetValue(currentDataBlock[address], bitNumber);
             return value;
         }
 
-        private void uploadTimer_Tick(object sender, EventArgs e)
-        {
-
-        }
-
-        private void btnSetting_Click(object sender, EventArgs e)
-        {
-            try
-            {
-                var settingForm = new SettingForm();
-                if (settingForm.ShowDialog() == DialogResult.OK)
-                {
-                    ConnectPLC();
-                    ConnectCamera();
-
-                    receivePLCTimer.Enabled = true;
-                    uploadTimer.Enabled = true;
-                }
-            }
-            catch { }
-        }
-
-        private void ConnectPLC()
-        {
-            plc = new Plc(config.PLCType, config.PLCIP, int.Parse(config.PLCPort), 0, 1);
-            plc.Open();
-
-            if (!plc.IsConnected)
-            {
-                MessageBox.Show("PLC连接失败!");
-                return;
-            }
-        }
-
-        private void ConnectCamera()
-        {
-            try
-            {
-                hikApi = HikApi.Login(config.CameraIP, int.Parse(config.CameraPort),
-                    config.CameraUserName, config.CameraPassword) as HikApi;
-
-                if (hikApi == null || !hikApi.Connected)
-                {
-                    MessageBox.Show("摄像头连接失败!");
-                    return;
-                }
-
-                hikApi.PlaybackService.StartPlayBack(hikApi.DefaultIpChannel, pictureBox1.Handle);
-            }
-            catch (Exception ex)
-            {
-                MessageBox.Show(ex.Message + ex.StackTrace);
-            }
-        }
-
-        public void UpdateCarInfo(DateTime now)
-        {
-            this.Invoke(() =>
-            {
-                this.Text = now.ToString();
-            });
-        }
-
-
-        public static void Parse(string input, out DataType dataType, out int dbNumber, out VarType varType, out int address, out int bitNumber)
+        private static void ParsePLCKey(string plcKey, out DataType dataType, out int dbNumber, out VarType varType, out int address, out int bitNumber)
         {
             bitNumber = -1;
             dbNumber = 0;
 
-            switch (input.Substring(0, 2))
+            switch (plcKey.Substring(0, 2))
             {
                 case "DB":
-                    string[] strings = input.Split(new char[] { '.' });
+                    string[] strings = plcKey.Split(new char[] { '.' });
                     if (strings.Length < 2)
                         throw new InvalidAddressException("To few periods for DB address");
 
@@ -317,7 +426,7 @@ namespace xicheji
                     // Input byte
                     dataType = DataType.Input;
                     dbNumber = 0;
-                    address = int.Parse(input.Substring(2));
+                    address = int.Parse(plcKey.Substring(2));
                     varType = VarType.Byte;
                     return;
                 case "IW":
@@ -325,7 +434,7 @@ namespace xicheji
                     // Input word
                     dataType = DataType.Input;
                     dbNumber = 0;
-                    address = int.Parse(input.Substring(2));
+                    address = int.Parse(plcKey.Substring(2));
                     varType = VarType.Word;
                     return;
                 case "ID":
@@ -333,7 +442,7 @@ namespace xicheji
                     // Input double-word
                     dataType = DataType.Input;
                     dbNumber = 0;
-                    address = int.Parse(input.Substring(2));
+                    address = int.Parse(plcKey.Substring(2));
                     varType = VarType.DWord;
                     return;
                 case "QB":
@@ -342,7 +451,7 @@ namespace xicheji
                     // Output byte
                     dataType = DataType.Output;
                     dbNumber = 0;
-                    address = int.Parse(input.Substring(2));
+                    address = int.Parse(plcKey.Substring(2));
                     varType = VarType.Byte;
                     return;
                 case "QW":
@@ -351,7 +460,7 @@ namespace xicheji
                     // Output word
                     dataType = DataType.Output;
                     dbNumber = 0;
-                    address = int.Parse(input.Substring(2));
+                    address = int.Parse(plcKey.Substring(2));
                     varType = VarType.Word;
                     return;
                 case "QD":
@@ -360,32 +469,32 @@ namespace xicheji
                     // Output double-word
                     dataType = DataType.Output;
                     dbNumber = 0;
-                    address = int.Parse(input.Substring(2));
+                    address = int.Parse(plcKey.Substring(2));
                     varType = VarType.DWord;
                     return;
                 case "MB":
                     // Memory byte
                     dataType = DataType.Memory;
                     dbNumber = 0;
-                    address = int.Parse(input.Substring(2));
+                    address = int.Parse(plcKey.Substring(2));
                     varType = VarType.Byte;
                     return;
                 case "MW":
                     // Memory word
                     dataType = DataType.Memory;
                     dbNumber = 0;
-                    address = int.Parse(input.Substring(2));
+                    address = int.Parse(plcKey.Substring(2));
                     varType = VarType.Word;
                     return;
                 case "MD":
                     // Memory double-word
                     dataType = DataType.Memory;
                     dbNumber = 0;
-                    address = int.Parse(input.Substring(2));
+                    address = int.Parse(plcKey.Substring(2));
                     varType = VarType.DWord;
                     return;
                 default:
-                    switch (input.Substring(0, 1))
+                    switch (plcKey.Substring(0, 1))
                     {
                         case "E":
                         case "I":
@@ -409,7 +518,7 @@ namespace xicheji
                             // Timer
                             dataType = DataType.Timer;
                             dbNumber = 0;
-                            address = int.Parse(input.Substring(1));
+                            address = int.Parse(plcKey.Substring(1));
                             varType = VarType.Timer;
                             return;
                         case "Z":
@@ -417,14 +526,14 @@ namespace xicheji
                             // Counter
                             dataType = DataType.Counter;
                             dbNumber = 0;
-                            address = int.Parse(input.Substring(1));
+                            address = int.Parse(plcKey.Substring(1));
                             varType = VarType.Counter;
                             return;
                         default:
-                            throw new InvalidAddressException(string.Format("{0} is not a valid address", input.Substring(0, 1)));
+                            throw new InvalidAddressException(string.Format("{0} is not a valid address", plcKey.Substring(0, 1)));
                     }
 
-                    string txt2 = input.Substring(1);
+                    string txt2 = plcKey.Substring(1);
                     if (txt2.IndexOf(".") == -1)
                         throw new InvalidAddressException("To few periods for DB address");
 
@@ -436,6 +545,142 @@ namespace xicheji
             }
         }
 
-    }
+        #endregion
+
+        #region 上传到洗车平台
+
+        private async void uploadTimer_Tick(object sender, EventArgs e)
+        {
+            try
+            {
+                await UploadPlatform();
+            }
+            catch (Exception ex)
+            {
+                uploadTimer.Enabled = false;
+                MessageBox.Show(ex.Message + ex.StackTrace);
+            }
+        }
 
+        private async Task UploadPlatform()
+        {
+            var restClient = new RestClient(config.Server);
+            var request = new RestRequest("cyft/common/carWashRecord", Method.Post);
+            // 测试代码
+            WashRecord washRecord = new WashRecord();
+            var jsonBody = new
+            {
+                deviceId = washRecord.DeviceId, //洗车机器mac地址
+                carNo = washRecord.CarNum, //车牌号码
+                beginTime = washRecord.StartTime.ToString("yyyy-MM-dd HH:mm:ss"), //洗车开始时间
+                endTime = washRecord.EndTime.ToString("yyyy-MM-dd HH:mm:ss"), //洗车结束时间
+                washTime = washRecord.WashTime, //洗车时长(s)
+                widnowsDefender = washRecord.TotalWater, //用水量(t)
+                waterPressure = washRecord.WaterPressure, //压力(MPa)
+                picBase64 = ConvertImageToBase64(pbCamera.Image, ImageFormat.Jpeg), //洗车图片base64
+            };
+            request.AddParameter("application/json", JsonConvert.SerializeObject(jsonBody), ParameterType.RequestBody);
+            var response = await restClient.ExecuteAsync(request);
+            if (response == null) return;
+        }
+
+        private static string ConvertImageToBase64(Image image, ImageFormat format)
+        {
+            if (image == null) return string.Empty;
+
+            using var memoryStream = new MemoryStream();
+            image.Save(memoryStream, format);
+            var imageBytes = memoryStream.ToArray();
+            return Convert.ToBase64String(imageBytes);
+        }
+        #endregion
+
+        #region 摄像头
+
+        private void btnConnectCamera_Click(object sender, EventArgs e)
+        {
+            try
+            {
+                ConnectCamera();
+            }
+            catch (Exception ex)
+            {
+                MessageBox.Show(ex.Message + ex.StackTrace);
+            }
+        }
+
+        private void ConnectCamera()
+        {
+            try
+            {
+                cboCameraChannel.DisplayMember = "Display";
+                cboCameraChannel.ValueMember = "Value";
+                cboCameraChannel.Items.Clear();
+
+                hikApi = HikApi.Login(config.CameraIP, int.Parse(config.CameraPort),
+                    config.CameraUserName, config.CameraPassword) as HikApi;
+
+                if (hikApi == null || !hikApi.Connected)
+                {
+                    MessageBox.Show("摄像头连接失败!");
+                    return;
+                }
+
+                var channels = hikApi.IpChannels.ToList();
+
+                #region 测试代码: 测试摄像头信道
+                //channels = new List<IpChannel>();
+                //channels.Add(new IpChannel(33, true, "channl1"));
+                //channels.Add(new IpChannel(34, false, "channl2"));
+                //channels.Add(new IpChannel(35, true, "channl3"));
+                //channels.Add(new IpChannel(36, false, "channl4"));
+                //channels.Add(new IpChannel(37, false, "channl5")); 
+                #endregion
+
+                foreach (var c in channels)
+                {
+                    cboCameraChannel.Items.Add(new
+                    {
+                        Display = $"{c.Name}({c.ChannelNumber}) {(c.IsOnline ? "在线" : "离线")})",
+                        Value = c.ChannelNumber,
+                        Channel = c,
+                    });
+                }
+
+                if (cboCameraChannel.Items.Count > 0 && cboCameraChannel.SelectedIndex == -1)
+                {
+                    cboCameraChannel.SelectedIndex = 0;
+                }
+            }
+            catch (Exception ex)
+            {
+                MessageBox.Show(ex.Message + ex.StackTrace);
+            }
+        }
+
+        private void cboCameraChannel_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            try
+            {
+                var channelNumber = ((dynamic)(cboCameraChannel.SelectedItem)).Value;
+                hikApi?.PlaybackService.StartPlayBack(channelNumber, pbCamera.Handle);
+            }
+            catch (Exception ex)
+            {
+                MessageBox.Show(ex.Message + ex.StackTrace);
+            }
+        }
+        #endregion
+
+        #region 服务接口回调->更新汽车信息
+
+        public void UpdateTitle(DateTime now)
+        {
+            this.Invoke(() =>
+            {
+                this.Text = now.ToString();
+            });
+        }
+        #endregion
+    }
 }

+ 0 - 2
Program.cs

@@ -5,9 +5,7 @@ namespace xicheji
 {
     internal static class Program
     {
-#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
         public static MainForm MainForm { get; set; }
-#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
 
         /// <summary>
         ///  The main entry point for the application.

+ 4 - 0
README.md

@@ -1,5 +1,9 @@
 发布
 
 ```
+# 发布不依赖框架的,不用单文件发布
+dotnet publish "xicheji.csproj" -c Release -o ./release/ -r win-x64 --no-self-contained
+
+# 发布不依赖框架的,用单文件发布
 dotnet publish "xicheji.csproj" -c Release -o ./release/ -r win-x64 --no-self-contained /p:PublishSingleFile=true
 ```

+ 5 - 0
WashRecord.cs

@@ -11,6 +11,11 @@ namespace xicheji
     /// </summary>
     public class WashRecord
     {
+        /// <summary>
+        /// 洗车机器mac地址
+        /// </summary>
+        public string DeviceId { get; set; } = string.Empty;
+
         /// <summary>
         /// 车牌号
         /// </summary>

+ 10 - 9
config.xml

@@ -2,19 +2,20 @@
 <Config>
 	<!--Service Port只能从配置文件修改, 然后重新运行程序-->
 	<Service Port="9999"/>
-	<Platform Server="http[s]://+IP+Port+BasePath"  UploadInterval="2"/>
+	<!--<Platform Server="http://iot.cyftcn.cn:3033/"  UploadInterval="2"/>-->
+	<Platform Server="http://172.16.2.241:8088/"  UploadInterval="2"/>
 	<!--Type: S7200,Logo0BA8,S7200Smart,S7300,S7400,S71200,S71500-->
-	<Device IP="127.0.0.1" Port="1502" Type="S7200" ReceiveInterval="2" MacVariable="" Gateway="" Netmask="" />
+	<Device IP="127.0.0.1" Port="1502" Type="S7200" ReceiveInterval="2" MacAddress="" Gateway="" Netmask="" />
 	<Camera IP="127.0.0.1" Port="1502" UserName="user" Password="Wayclouds2024" />
 	<Variables DBName="DB1">
 		<Variable Name="FF" Key="DBX0"/>
 		<Variable Name="数据长度" Key="DBX1"/>
-		<Variable Name="MAC1" Key="DBX2"/>
-		<Variable Name="MAC2" Key="DBX3"/>
-		<Variable Name="MAC3" Key="DBX4"/>
-		<Variable Name="MAC4" Key="DBX5"/>
-		<Variable Name="MAC5" Key="DBX6"/>
-		<Variable Name="MAC6" Key="DBX7"/>
+		<Variable Name="MAC1" Key="DBB2"/>
+		<Variable Name="MAC2" Key="DBB3"/>
+		<Variable Name="MAC3" Key="DBB4"/>
+		<Variable Name="MAC4" Key="DBB5"/>
+		<Variable Name="MAC5" Key="DBB6"/>
+		<Variable Name="MAC6" Key="DBB7"/>
 		<Variable Name="急停" Key="DBX10.0"/>
 		<Variable Name="冲洗泵故障" Key="DBX10.1"/>
 		<Variable Name="反洗泵故障" Key="DBX10.2"/>
@@ -74,6 +75,6 @@
 		<Variable Name="最后一次洗车用水" Key="DBW86" Desc="t*0.01"/>
 		<Variable Name="最后一次洗车用电" Key="DBW88" Desc="kW·h*0.01"/>
 		<Variable Name="最后一次洗车水压" Key="DBW90" Desc="MPa*0.01"/>
-		<Variable Name="CRC" Key="DBW98" Desc="校验"/>
+		<Variable Name="CRC" Key="DBW98"/>
 	</Variables>
 </Config>

BIN
dotnet_desktop_runtime/windowsdesktop-runtime-6.0.31-win-x64.exe


BIN
refs/hik/Hik.Api.dll


BIN
refs/hik/Hik.Api.pdb


+ 1262 - 0
refs/hik/Hik.Api.xml

@@ -0,0 +1,1262 @@
+<?xml version="1.0"?>
+<doc>
+    <assembly>
+        <name>Hik.Api</name>
+    </assembly>
+    <members>
+        <member name="T:Hik.Api.Abstraction.IConfigService">
+            <summary>
+            
+            </summary>
+        </member>
+        <member name="M:Hik.Api.Abstraction.IConfigService.GetTime(System.Int32)">
+            <summary>
+            Gets the time.
+            </summary>
+            <param name="ipChannel">The ip channel.</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Abstraction.IConfigService.SetTime(System.DateTime,System.Int32)">
+            <summary>
+            Sets the time.
+            </summary>
+            <param name="dateTime">The date time.</param>
+            <param name="ipChannel">The ip channel.</param>
+        </member>
+        <member name="M:Hik.Api.Abstraction.IConfigService.GetDeviceConfig">
+            <summary>
+            Gets the device configuration.
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Abstraction.IConfigService.GetNetworkConfig">
+            <summary>
+            Gets the network configuration.
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Abstraction.IConfigService.GetHddStatus(System.Int32)">
+            <summary>
+            Gets the HDD status.
+            </summary>
+            <param name="ipChannel">The ip channel.</param>
+            <returns></returns>
+        </member>
+        <member name="T:Hik.Api.Abstraction.IFileService">
+            <summary>
+            
+            </summary>
+        </member>
+        <member name="M:Hik.Api.Abstraction.IFileService.FindFilesAsync(System.DateTime,System.DateTime)">
+            <summary>
+            Finds the files asynchronous.
+            </summary>
+            <param name="periodStart">The period start.</param>
+            <param name="periodEnd">The period end.</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Abstraction.IFileService.FindFilesAsync(System.DateTime,System.DateTime,System.Int32)">
+            <summary>
+            Finds the files asynchronous.
+            </summary>
+            <param name="periodStart">The period start.</param>
+            <param name="periodEnd">The period end.</param>
+            <param name="ipChannel">The ip channel.</param>
+            <returns></returns>
+        </member>
+        <member name="T:Hik.Api.Abstraction.IHikApi">
+            <summary>
+            Hikvision SDK Wrapper
+            </summary>
+        </member>
+        <member name="P:Hik.Api.Abstraction.IHikApi.UserId">
+            <summary>
+            Gets the user identifier.
+            </summary>
+            <value>
+            The user identifier.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Abstraction.IHikApi.DefaultIpChannel">
+            <summary>
+            Gets the default ip channel.
+            </summary>
+            <value>
+            The default ip channel.
+            </value>
+        </member>
+        <member name="E:Hik.Api.Abstraction.IHikApi.Disconnected">
+            <summary>
+            Occurs when [disconnected].
+            </summary>
+        </member>
+        <member name="P:Hik.Api.Abstraction.IHikApi.VideoService">
+            <summary>
+            Gets the video service.
+            </summary>
+            <value>
+            The video service.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Abstraction.IHikApi.PhotoService">
+            <summary>
+            Gets the photo service.
+            </summary>
+            <value>
+            The photo service.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Abstraction.IHikApi.PlaybackService">
+            <summary>
+            Gets the playback service.
+            </summary>
+            <value>
+            The playback service.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Abstraction.IHikApi.ConfigService">
+            <summary>
+            Gets the config service.
+            </summary>
+            <value>
+            The config service.
+            </value>
+        </member>
+        <member name="M:Hik.Api.Abstraction.IHikApi.Logout">
+            <summary>Logouts the user.</summary>
+        </member>
+        <member name="T:Hik.Api.Abstraction.IHikSDK">
+            <summary>
+            
+            </summary>
+        </member>
+        <member name="M:Hik.Api.Abstraction.IHikSDK.Initialize(System.Int32,System.String,System.Boolean,System.UInt32,System.UInt32,System.UInt32,System.Boolean)">
+            <summary>
+            Initializes this instance.
+            </summary>
+            <param name="logLevel">The log level.</param>
+            <param name="logDirectory">The log directory.</param>
+            <param name="autoDeleteLogs">if set to <c>true</c> [automatic delete logs].</param>
+            <param name="waitTimeMilliseconds">The wait time milliseconds.</param>
+            <param name="tryTimes">The try times.</param>
+            <param name="reconnectInterval">The reconnect interval.</param>
+            <param name="enableReconnect">if set to <c>true</c> [enable reconnect].</param>
+        </member>
+        <member name="M:Hik.Api.Abstraction.IHikSDK.Login(System.String,System.Int32,System.String,System.String)">
+            <summary>
+            Logins the specified ip address.
+            </summary>
+            <param name="ipAddress">The ip address.</param>
+            <param name="port">The port.</param>
+            <param name="userName">Name of the user.</param>
+            <param name="password">The password.</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Abstraction.IHikSDK.Cleanup">
+            <summary>
+            Cleanups this instance.
+            </summary>
+        </member>
+        <member name="T:Hik.Api.Abstraction.IPhotoService">
+            <summary>
+            
+            </summary>
+            <seealso cref="T:Hik.Api.Abstraction.IFileService" />
+        </member>
+        <member name="M:Hik.Api.Abstraction.IPhotoService.DownloadFile(System.String,System.Int64,System.String)">
+            <summary>
+            Downloads the file.
+            </summary>
+            <param name="remoteFileName">Name of the remote file.</param>
+            <param name="size">The size.</param>
+            <param name="destinationPath">The destination path.</param>
+        </member>
+        <member name="M:Hik.Api.Abstraction.IPhotoService.DownloadFile(Hik.Api.Data.HikRemoteFile,System.String)">
+            <summary>
+            Downloads the file.
+            </summary>
+            <param name="photo">The photo.</param>
+            <param name="destinationPath">The destination path.</param>
+        </member>
+        <member name="T:Hik.Api.Abstraction.IPlaybackService">
+            <summary>
+            
+            </summary>
+        </member>
+        <member name="M:Hik.Api.Abstraction.IPlaybackService.StartPlayBack(System.Int32,System.Nullable{System.IntPtr})">
+            <summary>
+            Starts the play back.
+            </summary>
+            <param name="channel">The channel.</param>
+            <param name="playbackWindowHandler">The playback window handler.</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Abstraction.IPlaybackService.StopPlayBack(System.Int32)">
+            <summary>
+            Stops the play back.
+            </summary>
+            <param name="playbackId">The playback identifier.</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Abstraction.IPlaybackService.StartRecording(System.Int32,System.String,System.Int32)">
+            <summary>
+            Starts the recording.
+            </summary>
+            <param name="playbackId">The playback identifier.</param>
+            <param name="filePath">The file path.</param>
+            <param name="channel">The channel.</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Abstraction.IPlaybackService.StopRecording(System.Int32)">
+            <summary>
+            Stops the recording.
+            </summary>
+            <param name="playbackId">The playback identifier.</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Abstraction.ISourceFile.ToRemoteFile">
+            <summary>
+            Converts to remotefile.
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="T:Hik.Api.Abstraction.IVideoService">
+            <summary>
+            
+            </summary>
+            <seealso cref="T:Hik.Api.Abstraction.IFileService" />
+        </member>
+        <member name="M:Hik.Api.Abstraction.IVideoService.StartDownloadFile(System.String,System.String)">
+            <summary>
+            Starts the download file.
+            </summary>
+            <param name="sourceFile">The source file.</param>
+            <param name="destinationPath">The destination path.</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Abstraction.IVideoService.StopDownloadFile(System.Int32)">
+            <summary>
+            Stops the download file.
+            </summary>
+            <param name="fileHandle">The file handle.</param>
+        </member>
+        <member name="M:Hik.Api.Abstraction.IVideoService.GetDownloadPosition(System.Int32)">
+            <summary>
+            Gets the download position.
+            </summary>
+            <param name="fileHandle">The file handle.</param>
+            <returns></returns>
+        </member>
+        <member name="T:Hik.Api.Data.DeviceConfig">
+            <summary>
+            Device Config
+            </summary>
+        </member>
+        <member name="P:Hik.Api.Data.DeviceConfig.AnalogChannel">
+            <summary>
+            Gets the analog channel.
+            </summary>
+            <value>
+            The analog channel.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.DeviceConfig.IPChannel">
+            <summary>
+            Gets the ip channel.
+            </summary>
+            <value>
+            The ip channel.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.DeviceConfig.ZeroChannel">
+            <summary>
+            Gets the zero channel.
+            </summary>
+            <value>
+            The zero channel.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.DeviceConfig.NetworkPort">
+            <summary>
+            Gets the network port.
+            </summary>
+            <value>
+            The network port.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.DeviceConfig.AlarmInPort">
+            <summary>
+            Gets the alarm in port.
+            </summary>
+            <value>
+            The alarm in port.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.DeviceConfig.AlarmOutPort">
+            <summary>
+            Gets the alarm out port.
+            </summary>
+            <value>
+            The alarm out port.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.DeviceConfig.Serial">
+            <summary>
+            Gets the serial.
+            </summary>
+            <value>
+            The serial.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.DeviceConfig.Version">
+            <summary>
+            Gets the version.
+            </summary>
+            <value>
+            The version.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.DeviceConfig.TypeName">
+            <summary>
+            Gets the name of the type.
+            </summary>
+            <value>
+            The name of the type.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.DeviceConfig.Name">
+            <summary>
+            Gets the name.
+            </summary>
+            <value>
+            The name.
+            </value>
+        </member>
+        <member name="T:Hik.Api.Data.HdInfo">
+            <summary>
+             Hard drive information
+            </summary>
+        </member>
+        <member name="M:Hik.Api.Data.HdInfo.#ctor">
+            <summary>Initializes a new instance of the <see cref="T:Hik.Api.Data.HdInfo" /> class.</summary>
+        </member>
+        <member name="P:Hik.Api.Data.HdInfo.IsErrorStatus">
+            <summary>Gets a value indicating whether this instance is error status.</summary>
+            <value>
+              <c>true</c> if this instance is error status; otherwise, <c>false</c>.</value>
+        </member>
+        <member name="P:Hik.Api.Data.HdInfo.Capacity">
+            <summary>Gets or sets the capacity.</summary>
+            <value>The capacity.</value>
+        </member>
+        <member name="P:Hik.Api.Data.HdInfo.FreeSpace">
+            <summary>Gets or sets the free space.</summary>
+            <value>The free space.</value>
+        </member>
+        <member name="P:Hik.Api.Data.HdInfo.HdStatus">
+            <summary>Gets or sets the hd status.</summary>
+            <value>The hd status.</value>
+        </member>
+        <member name="P:Hik.Api.Data.HdInfo.HDAttr">
+            <summary>Gets or sets the hd attribute.</summary>
+            <value>The hd attribute.</value>
+        </member>
+        <member name="P:Hik.Api.Data.HdInfo.HDType">
+            <summary>Gets or sets the type of the hd.</summary>
+            <value>The type of the hd.</value>
+        </member>
+        <member name="P:Hik.Api.Data.HdInfo.Recycling">
+            <summary>Gets or sets the recycling.</summary>
+            <value>The recycling.</value>
+        </member>
+        <member name="P:Hik.Api.Data.HdInfo.PictureCapacity">
+            <summary>Gets or sets the picture capacity.</summary>
+            <value>The picture capacity.</value>
+        </member>
+        <member name="P:Hik.Api.Data.HdInfo.FreePictureSpace">
+            <summary>Gets or sets the free picture space.</summary>
+            <value>The free picture space.</value>
+        </member>
+        <member name="M:Hik.Api.Data.HdInfo.ToString">
+            <summary>Converts to string.</summary>
+            <returns>A <see cref="T:System.String" /> that represents this instance.</returns>
+        </member>
+        <member name="T:Hik.Api.Data.HikRemoteFile">
+            <summary>
+             Remote file from camera
+            </summary>
+        </member>
+        <member name="M:Hik.Api.Data.HikRemoteFile.#ctor">
+            <summary>Initializes a new instance of the <see cref="T:Hik.Api.Data.HikRemoteFile" /> class.</summary>
+        </member>
+        <member name="P:Hik.Api.Data.HikRemoteFile.Name">
+            <summary>
+            Gets or sets the name.
+            </summary>
+            <value>
+            The name.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.HikRemoteFile.Date">
+            <summary>
+            Gets or sets the date.
+            </summary>
+            <value>
+            The date.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.HikRemoteFile.Duration">
+            <summary>
+            Gets or sets the duration.
+            </summary>
+            <value>
+            The duration.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.HikRemoteFile.Size">
+            <summary>
+            Gets or sets the size.
+            </summary>
+            <value>
+            The size.
+            </value>
+        </member>
+        <member name="T:Hik.Api.Data.IpChannel">
+            <summary>
+            IpChannel
+            </summary>
+        </member>
+        <member name="M:Hik.Api.Data.IpChannel.#ctor(System.Int32,System.Boolean,System.String)">
+            <summary>
+            Initializes a new instance of the <see cref="T:Hik.Api.Data.IpChannel"/> class.
+            </summary>
+            <param name="iChanNo">The i chan no.</param>
+            <param name="byOnline">if set to <c>true</c> [by online].</param>
+            <param name="name">The name.</param>
+        </member>
+        <member name="P:Hik.Api.Data.IpChannel.ChannelNumber">
+            <summary>
+            Gets the channel number.
+            </summary>
+            <value>
+            The channel number.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.IpChannel.IsOnline">
+            <summary>
+            Gets a value indicating whether this instance is online.
+            </summary>
+            <value>
+              <c>true</c> if this instance is online; otherwise, <c>false</c>.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.IpChannel.Name">
+            <summary>
+            Gets the name.
+            </summary>
+            <value>
+            The name.
+            </value>
+        </member>
+        <member name="T:Hik.Api.Data.NetworkConfig">
+            <summary>
+            Network config
+            </summary>
+        </member>
+        <member name="P:Hik.Api.Data.NetworkConfig.IPAddress">
+            <summary>
+            Gets the ip address.
+            </summary>
+            <value>
+            The ip address.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.NetworkConfig.GateWay">
+            <summary>
+            Gets the gate way.
+            </summary>
+            <value>
+            The gate way.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.NetworkConfig.SubMask">
+            <summary>
+            Gets the sub mask.
+            </summary>
+            <value>
+            The sub mask.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.NetworkConfig.Dns">
+            <summary>
+            Gets the DNS.
+            </summary>
+            <value>
+            The DNS.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.NetworkConfig.HostIP">
+            <summary>
+            Gets the host ip.
+            </summary>
+            <value>
+            The host ip.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.NetworkConfig.PPPoEName">
+            <summary>
+            Gets the name of the pp po e.
+            </summary>
+            <value>
+            The name of the pp po e.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.NetworkConfig.PPPoEPassword">
+            <summary>
+            Gets the pp po e password.
+            </summary>
+            <value>
+            The pp po e password.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.NetworkConfig.AlarmHostIpPort">
+            <summary>
+            Gets the alarm host ip port.
+            </summary>
+            <value>
+            The alarm host ip port.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.NetworkConfig.HttpPort">
+            <summary>
+            Gets the HTTP port.
+            </summary>
+            <value>
+            The HTTP port.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.NetworkConfig.DVRPort">
+            <summary>
+            Gets the DVR port.
+            </summary>
+            <value>
+            The DVR port.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.NetworkConfig.DHCP">
+            <summary>
+            Gets a value indicating whether this <see cref="T:Hik.Api.Data.NetworkConfig"/> is DHCP.
+            </summary>
+            <value>
+              <c>true</c> if DHCP; otherwise, <c>false</c>.
+            </value>
+        </member>
+        <member name="P:Hik.Api.Data.NetworkConfig.PPPoE">
+            <summary>
+            Gets a value indicating whether [pp po e].
+            </summary>
+            <value>
+              <c>true</c> if [pp po e]; otherwise, <c>false</c>.
+            </value>
+        </member>
+        <member name="T:Hik.Api.Helpers.HikRemoteFileExtensions">
+            <summary>
+            Hik Remote File Extensions
+            </summary>
+        </member>
+        <member name="M:Hik.Api.Helpers.HikRemoteFileExtensions.ToVideoUserFriendlyString(Hik.Api.Data.HikRemoteFile)">
+            <summary>
+            Converts to user friendly string. For video files
+            </summary>
+            <param name="file">The file.</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Helpers.HikRemoteFileExtensions.ToPhotoFileNameString(Hik.Api.Data.HikRemoteFile)">
+            <summary>
+            Converts to user friendly file name. For photo files.
+            </summary>
+            <param name="file">The file.</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Helpers.HikRemoteFileExtensions.ToDirectoryNameString(Hik.Api.Data.HikRemoteFile)">
+            <summary>
+            Gets Relative path in format YYYY-MM\\DD\\HH
+            </summary>
+            <param name="file">The file.</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Helpers.HikRemoteFileExtensions.ToVideoFileNameString(Hik.Api.Data.HikRemoteFile)">
+            <summary>
+            Converts to user friendly file name. For video files.
+            </summary>
+            <param name="file">The file.</param>
+            <returns></returns>
+        </member>
+        <member name="T:Hik.Api.HikApi">
+            <summary>
+            Implementation of IHikApi
+            </summary>
+        </member>
+        <member name="E:Hik.Api.HikApi.Disconnected">
+            <summary>
+            When connection is lost
+            </summary>
+        </member>
+        <member name="M:Hik.Api.HikApi.#ctor">
+            <summary>
+            Initializes a new instance of the <see cref="T:Hik.Api.HikApi"/> class.
+            </summary>
+        </member>
+        <member name="P:Hik.Api.HikApi.VideoService">
+            <summary>Gets the video service.</summary>
+            <value>The video service.</value>
+        </member>
+        <member name="P:Hik.Api.HikApi.PhotoService">
+            <summary>Gets the photo service.</summary>
+            <value>The photo service.</value>
+        </member>
+        <member name="P:Hik.Api.HikApi.PlaybackService">
+            <summary>Gets the playback service.</summary>
+            <value>The playback service.</value>
+        </member>
+        <member name="P:Hik.Api.HikApi.ConfigService">
+            <summary>
+            Config service
+            </summary>
+        </member>
+        <member name="P:Hik.Api.HikApi.Connected">
+            <summary>
+            Gets a value indicating whether this <see cref="T:Hik.Api.HikApi" /> is connected.
+            </summary>
+            <value>
+              <c>true</c> if connected; otherwise, <c>false</c>.
+            </value>
+        </member>
+        <member name="P:Hik.Api.HikApi.UserId">
+            <summary>
+            Gets the user identifier.
+            </summary>
+            <value>
+            The user identifier.
+            </value>
+        </member>
+        <member name="P:Hik.Api.HikApi.Host">
+            <summary>
+            Gets the Host identifier.
+            </summary>
+            <value>
+            The Host identifier.
+            </value>
+        </member>
+        <member name="P:Hik.Api.HikApi.DefaultIpChannel">
+            <summary>Gets the default ip channel.</summary>
+            <value>The default ip channel.</value>
+        </member>
+        <member name="P:Hik.Api.HikApi.IpChannels">
+            <summary>Gets the ip channels.</summary>
+            <value>The ip channels.</value>
+        </member>
+        <member name="M:Hik.Api.HikApi.Initialize(System.Int32,System.String,System.Boolean,System.UInt32,System.UInt32,System.UInt32,System.Boolean)">
+            <summary>
+            Initialize the SDK and call other SDK functions.
+            </summary>
+            <param name="logLevel">[in] Log level. 0- close log(default), 1- output ERROR log only, 2- output ERROR and DEBUG log, 3- output all log, including ERROR, DEBUG and INFO log</param>
+            <param name="logDirectory">[in] Log file saving path, if set to NULL, the default path for Windows is "C:\\SdkLog\\", and the default path for Linux is ""/home/sdklog/" </param>
+            <param name="autoDeleteLogs">[bool] Whether to delete the files which exceed the number limit. Default: TRUE</param>
+            <param name="waitTimeMilliseconds">Timeout,unit: ms, value range: [300,75000], the actual max timeout time is different with different system connecting timeout</param>
+            <param name="tryTimes">Connecting attempt times (reserved)</param>
+            <param name="reconnectInterval">Reconnecting interval, unit: milliseconds, default value:30 seconds</param>
+            <param name="enableReconnect">Enable or disable reconnect function, 0-disable, 1-enable(default)</param>
+            <returns>TRUE means success, FALSE means failure. </returns>
+            <remarks>This API is used to initialize SDK. Please call this API before calling any other API</remarks>
+        </member>
+        <member name="M:Hik.Api.HikApi.Login(System.String,System.Int32,System.String,System.String)">
+            <summary>
+            This API is used to login user to the device.
+            </summary>
+            <param name="ipAddress">device IP address</param>
+            <param name="port">device port number</param>
+            <param name="userName">Login username</param>
+            <param name="password">password.</param>
+            <returns>User session</returns>
+            <remarks>It supports 32 different user names for DS7116, DS81xx, DS90xx and DS91xx series devices, and 128 users login at the same time.Other devices support 16 different user names and 128 users login at the same time. SDK supports 512 * login.UserID is incremented one by one, from 0 to 511 and then return to 0. Logout and NET_DVR_Cleanup will not initialize the UserID to 0. If client offline abnormally, the device will keep the UserID 5 minutes, and the UserID will invalid after the valid time.</remarks>
+        </member>
+        <member name="M:Hik.Api.HikApi.Cleanup">
+            <summary>
+            Release SDK resources, last call before the end
+            </summary>
+            <returns>TRUE means success, FALSE means failure</returns>
+            <remarks>This API is used to release SDK resource. Please calling it before closing the program.</remarks>
+        </member>
+        <member name="M:Hik.Api.HikApi.Logout">
+            <summary>
+            This API is used to logout certain user.
+            </summary>
+            <returns>
+            TRUE means success, FALSE means failure
+            </returns>
+            <remarks>
+            It is suggested to call this API to logout.
+            </remarks>
+        </member>
+        <member name="M:Hik.Api.HikApi.Dispose">
+            <summary>
+             Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+            </summary>
+        </member>
+        <member name="M:Hik.Api.HikApi.NET_DVR_Init">
+            <summary>
+            Initialize the SDK and call other SDK functions.
+            </summary>
+            <returns>TRUE means success, FALSE means failure. </returns>
+            <remarks>This API is used to initialize SDK. Please call this API before calling any other API</remarks>
+        </member>
+        <member name="M:Hik.Api.HikApi.NET_DVR_SetLogToFile(System.Int32,System.String,System.Boolean)">
+            <summary>
+            Enable log file writing interface
+            </summary>
+            <param name="bLogEnable">The level of the log (default is 0): 0- means to close the log, 1- means only output ERROR error log, 2- output ERROR error information and DEBUG debugging information, 3- output ERROR All information such as error information, DEBUG debugging information and INFO general information</param>
+            <param name="strLogDir">The path of the log file, the default value of windows is "C:\\SdkLog\\"; the default value of linux is "/home/sdklog/"</param>
+            <param name="bAutoDel">Whether to delete the excess number of files, the default value is TRUE.. When it is TRUE, it means the overwrite mode. When the number of log files exceeds the SDK limit, the excess files will be automatically deleted. The SDK limit is 10 by default</param>
+            <returns>Return TRUE on success, FALSE on failure. Please call NET_DVR_GetLastError to get the error code.</returns>
+        </member>
+        <member name="M:Hik.Api.HikApi.NET_DVR_Login_V30(System.String,System.Int32,System.String,System.String,Hik.Api.Struct.NET_DVR_DEVICEINFO_V30@)">
+            <summary>
+            This API is used to login user to the device.
+            </summary>
+            <param name="sDVRIP">device IP address</param>
+            <param name="wDVRPort">device port number</param>
+            <param name="sUserName">Login username</param>
+            <param name="sPassword">password.</param>
+            <param name="lpDeviceInfo">device information.</param>
+            <returns>-1 indicates failure, other values indicate the returned user ID value</returns>
+            <remarks>It supports 32 different user names for DS7116, DS81xx, DS90xx and DS91xx series devices, and 128 users login at the same time.Other devices support 16 different user names and 128 users login at the same time. SDK supports 512 * login.UserID is incremented one by one, from 0 to 511 and then return to 0. Logout and NET_DVR_Cleanup will not initialize the UserID to 0. If client offline abnormally, the device will keep the UserID 5 minutes, and the UserID will invalid after the valid time.</remarks>
+        </member>
+        <member name="M:Hik.Api.HikApi.NET_DVR_Logout(System.Int32)">
+            <summary>
+            This API is used to logout certain user.
+            </summary>
+            <param name="iUserID">User ID, the return value of NET_DVR_Login_V30</param>
+            <returns>TRUE means success, FALSE means failure</returns>
+            <remarks>It is suggested to call this API to logout.</remarks>
+        </member>
+        <member name="M:Hik.Api.HikApi.NET_DVR_Cleanup">
+            <summary>
+            Release SDK resources, last call before the end
+            </summary>
+            <returns>TRUE means success, FALSE means failure</returns>
+            <remarks>This API is used to release SDK resource. Please calling it before closing the program.</remarks>
+        </member>
+        <member name="M:Hik.Api.HikApi.NET_DVR_SetConnectTime(System.UInt32,System.UInt32)">
+            <summary>
+            Set the network connection timeout and the number of connection attempts
+            </summary>
+            <param name="dwWaitTime">Timeout,unit: ms, value range: [300,75000], the actual max timeout time is different with different system connecting timeout</param>
+            <param name="dwTryTimes">Connecting attempt times (reserved)</param>
+            <returns>Return TRUE on success, FALSE on failure. Please call NET_DVR_GetLastError to get the error code.</returns>
+            <remarks>Default timeout of SDK to establish a connection is 3 seconds. Interface will not return FASLE when the set timeout value is greater or less than the limit, it will take the nearest upper and lower limit value as the actual timeout.</remarks>
+        </member>
+        <member name="M:Hik.Api.HikApi.NET_DVR_SetReconnect(System.UInt32,System.Int32)">
+            <summary>
+            Set the reconnection function.
+            </summary>
+            <param name="dwInterval">Reconnecting interval, unit: milliseconds, default value:30 seconds</param>
+            <param name="bEnableRecon">Enable or disable reconnect function, 0-disable, 1-enable(default)</param>
+            <returns>Return TRUE on success, FALSE on failure. Please call NET_DVR_GetLastError to get the error code.</returns>
+            <remarks>This API can set the reconnect function for preview, transparent channel and alar on guard state.If the user does not call this API, the SDK will initial the reconnect function for preview, transparent channel and alarm on guard state by default, and the reconnect interval is 5 seconds.</remarks>
+        </member>
+        <member name="T:Hik.Api.HikException">
+            <summary>
+            Hik Exception
+            </summary>
+            <seealso cref="T:System.Exception" />
+        </member>
+        <member name="P:Hik.Api.HikException.ErrorMessage">
+            <summary>
+            Gets the error message.
+            </summary>
+            <value>
+            The error message.
+            </value>
+        </member>
+        <member name="M:Hik.Api.HikException.#ctor(System.String,System.String)">
+            <summary>
+            Initializes a new instance of the <see cref="T:Hik.Api.HikException"/> class.
+            </summary>
+            <param name="method">The method.</param>
+            <param name="error">The error.</param>
+        </member>
+        <member name="M:Hik.Api.HikException.ToString">
+            <summary>
+            Converts to string.
+            </summary>
+            <returns>
+            A <see cref="T:System.String" /> that represents this instance.
+            </returns>
+        </member>
+        <member name="M:Hik.Api.HikException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+            <summary>
+            Initializes a new instance of the <see cref="T:Hik.Api.HikException"/> class.
+            </summary>
+            <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo" /> that holds the serialized object data about the exception being thrown.</param>
+            <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext" /> that contains contextual information about the source or destination.</param>
+        </member>
+        <member name="T:Hik.Api.HikSDK">
+            <summary>
+            HikSDK
+            </summary>
+            <seealso cref="T:Hik.Api.Abstraction.IHikSDK" />
+        </member>
+        <member name="M:Hik.Api.HikSDK.Cleanup">
+            <summary>
+            Cleanups this instance.
+            </summary>
+        </member>
+        <member name="M:Hik.Api.HikSDK.Initialize(System.Int32,System.String,System.Boolean,System.UInt32,System.UInt32,System.UInt32,System.Boolean)">
+            <summary>
+            Initializes this instance.
+            </summary>
+            <param name="logLevel">The log level.</param>
+            <param name="logDirectory">The log directory.</param>
+            <param name="autoDeleteLogs">if set to <c>true</c> [automatic delete logs].</param>
+            <param name="waitTimeMilliseconds">The wait time milliseconds.</param>
+            <param name="tryTimes">The try times.</param>
+            <param name="reconnectInterval">The reconnect interval.</param>
+            <param name="enableReconnect">if set to <c>true</c> [enable reconnect].</param>
+        </member>
+        <member name="M:Hik.Api.HikSDK.Login(System.String,System.Int32,System.String,System.String)">
+            <summary>
+            Logins the specified ip address.
+            </summary>
+            <param name="ipAddress">The ip address.</param>
+            <param name="port">The port.</param>
+            <param name="userName">Name of the user.</param>
+            <param name="password">The password.</param>
+            <returns></returns>
+        </member>
+        <member name="T:Hik.Api.Services.ConfigService">
+            <summary>
+            Config service
+            </summary>
+        </member>
+        <member name="M:Hik.Api.Services.ConfigService.#ctor(Hik.Api.Abstraction.IHikApi)">
+            <summary>
+            Initializes a new instance of the <see cref="T:Hik.Api.Services.ConfigService"/> class.
+            </summary>
+            <param name="session">The session.</param>
+        </member>
+        <member name="M:Hik.Api.Services.ConfigService.GetTime(System.Int32)">
+            <summary>
+            Get device current time
+            </summary>
+            <param name="ipChannel">Default value 1</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Services.ConfigService.SetTime(System.DateTime,System.Int32)">
+            <summary>
+            Set device current time
+            </summary>
+            <param name="dateTime">The date time.</param>
+            <param name="ipChannel">Default value -1</param>
+        </member>
+        <member name="M:Hik.Api.Services.ConfigService.GetDeviceConfig">
+            <summary>
+            Get device configuration information.
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Services.ConfigService.GetNetworkConfig">
+            <summary>
+            Get device network information.
+            </summary>
+            <returns>
+            Network information
+            </returns>
+        </member>
+        <member name="M:Hik.Api.Services.ConfigService.GetHddStatus(System.Int32)">
+            <summary>
+            Get SD Card info, capacity, free space, status etc.
+            </summary>
+            <param name="ipChannel">Default value -1</param>
+            <returns>HdInfo</returns>
+        </member>
+        <member name="M:Hik.Api.Services.ConfigService.NET_DVR_GetDVRConfig(System.Int32,System.UInt32,System.Int32,System.IntPtr,System.UInt32,System.UInt32@)">
+            <summary>
+            Get device configuration information.
+            </summary>
+            <param name="lUserID">Return value of login interface such as NET_DVR_Login_V40</param>
+            <param name="dwCommand">[in] Channel number, different commands correspond to different values, if this parameter is invalid, set it to 0xFFFFFFFF, see "Remarks" for details.</param>
+            <param name="lChannel"> Channel number, different commands correspond to different values, if this parameter is invalid, set it to 0xFFFFFFFF, see "Remarks" for details.</param>
+            <param name="lpOutBuffer">[out] Buffer pointer for receiving data</param>
+            <param name="dwOutBufferSize">[in] The buffer length of received data (in bytes), which cannot be 0</param>
+            <param name="lpBytesReturned">[out] The actual received data length pointer, which cannot be NULL</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Services.ConfigService.NET_DVR_SetDVRConfig(System.Int32,System.UInt32,System.Int32,System.IntPtr,System.UInt32)">
+            <summary>
+            Set the configuration information of the device.
+            </summary>
+            <param name="lUserID">Return value of login interface such as NET_DVR_Login_V40</param>
+            <param name="dwCommand">Device configuration command, see "Remarks" for details</param>
+            <param name="lChannel">Channel number, different commands correspond to different values, if this parameter is invalid, set it to 0xFFFFFFFF, see "Remarks" for details</param>
+            <param name="lpInBuffer">Buffer pointer for input data.</param>
+            <param name="dwInBufferSize">The buffer length of the input data (in bytes)</param>
+            <returns></returns>
+            <remarks>Different acquisition functions correspond to different structures and command numbers</remarks>
+        </member>
+        <member name="T:Hik.Api.Services.FileService">
+            <summary>
+            Base class to download files
+            </summary>
+        </member>
+        <member name="F:Hik.Api.Services.FileService.session">
+            <summary>
+            session
+            </summary>
+        </member>
+        <member name="M:Hik.Api.Services.FileService.#ctor(Hik.Api.Abstraction.IHikApi)">
+            <summary>
+            Initializes a new instance of the <see cref="T:Hik.Api.Services.FileService"/> class.
+            </summary>
+            <param name="session">The session.</param>
+        </member>
+        <member name="M:Hik.Api.Services.FileService.FindFilesAsync(System.DateTime,System.DateTime)">
+            <summary>
+            Finds the files asynchronous.
+            </summary>
+            <param name="periodStart">The period start.</param>
+            <param name="periodEnd">The period end.</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Services.FileService.FindFilesAsync(System.DateTime,System.DateTime,System.Int32)">
+            <summary>
+            Get files list for specific channel
+            </summary>
+            <param name="periodStart">The period start.</param>
+            <param name="periodEnd">The period end.</param>
+            <param name="ipChannel">The ip channel.</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Services.FileService.StartFind(System.DateTime,System.DateTime,System.Int32)">
+            <summary>
+            Starts the find.
+            </summary>
+            <param name="periodStart">The period start.</param>
+            <param name="periodEnd">The period end.</param>
+            <param name="channel">The channel.</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Services.FileService.StopFind(System.Int32)">
+            <summary>
+            Stops the find.
+            </summary>
+            <param name="findId">The find identifier.</param>
+            <returns>Success</returns>
+        </member>
+        <member name="M:Hik.Api.Services.FileService.FindNext(System.Int32,Hik.Api.Abstraction.ISourceFile@)">
+            <summary>
+            Finds the next.
+            </summary>
+            <param name="findId">The find identifier.</param>
+            <param name="source">The source.</param>
+            <returns>Success</returns>
+        </member>
+        <member name="M:Hik.Api.Services.FileService.GetFindResults(System.Int32)">
+            <summary>
+            Gets the find results.
+            </summary>
+            <param name="findId">The find identifier.</param>
+            <returns></returns>
+        </member>
+        <member name="T:Hik.Api.Services.PhotoService">
+            <summary>
+            Photo service
+            </summary>
+        </member>
+        <member name="M:Hik.Api.Services.PhotoService.#ctor(Hik.Api.Abstraction.IHikApi)">
+            <summary>
+            Initializes a new instance of the <see cref="T:Hik.Api.Services.PhotoService"/> class.
+            </summary>
+            <param name="session">The session.</param>
+        </member>
+        <member name="M:Hik.Api.Services.PhotoService.DownloadFile(System.String,System.Int64,System.String)">
+            <summary>
+            Download File
+            </summary>
+            <param name="remoteFileName">remote file name</param>
+            <param name="size">Remote file size</param>
+            <param name="destinationPath">Save path</param>
+        </member>
+        <member name="M:Hik.Api.Services.PhotoService.DownloadFile(Hik.Api.Data.HikRemoteFile,System.String)">
+            <summary>
+            Download file
+            </summary>
+            <param name="photo">Hik remote file</param>
+            <param name="destinationPath">Save path</param>
+        </member>
+        <member name="M:Hik.Api.Services.PhotoService.StopFind(System.Int32)">
+            <summary>Stops the find.</summary>
+            <param name="findId">The find identifier.</param>
+            <returns>Success</returns>
+        </member>
+        <member name="M:Hik.Api.Services.PhotoService.StartFind(System.DateTime,System.DateTime,System.Int32)">
+            <summary>Starts the find.</summary>
+            <param name="periodStart">The period start.</param>
+            <param name="periodEnd">The period end.</param>
+            <param name="channel">The channel.</param>
+            <returns>Find identifier</returns>
+        </member>
+        <member name="M:Hik.Api.Services.PhotoService.NET_DVR_FindPicture(System.Int32,Hik.Api.Struct.Photo.NET_DVR_FIND_PICTURE_PARAM@)">
+            <summary>
+            This API is used to get picture one by one.
+            </summary>
+            <param name="lUserID">[in] Handle of file searching, the return value of NET_DVR_FindPicture </param>
+            <param name="pFindParam">Pointer for saving picture information </param>
+            <returns>Return -1 if it is failed, and the other values stand for current status or other information. Please call NET_DVR_GetLastError to get the error code.</returns>
+            <remarks>Before calling this function, please call NET_DVR_FindPicture to get current handle firstly. The interface only supports to get one picture. We should call the interface repetitively to get all pictures.</remarks>
+        </member>
+        <member name="M:Hik.Api.Services.PhotoService.NET_DVR_FindNextPicture_V50(System.Int32,Hik.Api.Struct.Photo.NET_DVR_FIND_PICTURE_V50@)">
+            <summary>
+            Get picture information one by one in search result.
+            </summary>
+            <param name="lFindHandle">[in] Handle of finding picture, the return value of NET_DVR_FindPicture </param>
+            <param name="lpFindData">[out] Save compass for picture information. </param>
+            <returns>Return -1 for failure, other values indicate the current getting status. When -1 is returned, callNET_DVR_GetLastError to get the error code.</returns>
+            <remarks>Before calling this API to get the searched picture information, call NET_DVR_FindPicture to get the current searching handle. This API is used to get one searched picture information. To get all the searched pictures information, you should call this API in loop.</remarks>
+        </member>
+        <member name="M:Hik.Api.Services.PhotoService.NET_DVR_CloseFindPicture(System.Int32)">
+            <summary>
+            This API is used to close finding picture and release resource.
+            </summary>
+            <param name="lpFindHandle">[in] Handle of finding picture, the return value of NET_DVR_FindPicture </param>
+            <returns>Returns TRUE on success, FALSE on failure. Please call NET_DVR_GetLastError to get the error code.</returns>
+        </member>
+        <member name="M:Hik.Api.Services.PhotoService.NET_DVR_GetPicture_V50(System.Int32,Hik.Api.Struct.Photo.NET_DVR_PIC_PARAM@)">
+            <summary>
+            This API is used to get picture data and save it in specified memory space.
+            </summary>
+            <param name="lUserID">User ID, the return value of NET_DVR_Login_V40 </param>
+            <param name="lpPicParam">Return temporary file</param>
+            <returns>Returns TRUE for success, and FALSE for failure. When FALSE is returned, call NET_DVR_GetLastError to get the error code.</returns>
+        </member>
+        <member name="M:Hik.Api.Services.PhotoService.NET_DVR_GetPicture(System.Int32,System.String,System.String)">
+            <summary>
+            Nets the DVR get picture.
+            </summary>
+            <param name="lUserID">User ID, the returned value of API NET_DVR_Login_V40 </param>
+            <param name="sDVRFileName">in] Name of picture to download</param>
+            <param name="sSavedFileName">[in] Saving path (including file name) for downloaded pictures</param>
+            <returns>Return TRUE for success, and return FALSE for failure. If API returns FALSE, call NET_DVR_GetLastError to get error code.</returns>
+            <remarks>The picture format is JPEG, and the postfix of file name is ".jpg".</remarks>
+        </member>
+        <member name="T:Hik.Api.Services.PlaybackService">
+            <summary>
+            Playback Service
+            </summary>
+        </member>
+        <member name="M:Hik.Api.Services.PlaybackService.#ctor(Hik.Api.Abstraction.IHikApi)">
+            <summary>
+            Initializes a new instance of the <see cref="T:Hik.Api.Services.PlaybackService"/> class.
+            </summary>
+            <param name="session">The session.</param>
+        </member>
+        <member name="M:Hik.Api.Services.PlaybackService.StartPlayBack(System.Int32,System.Nullable{System.IntPtr})">
+            <summary>
+            Start live preview without callback, all receiver live data will be handled by PictureBox Handle
+            </summary>
+            <param name="channel">channel.</param>
+            <param name="playbackWindowHandler">System.Windows.Forms.PictureBox Handle</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Services.PlaybackService.StopPlayBack(System.Int32)">
+            <summary>
+            Stop real-time preview
+            </summary>
+            <param name="playbackId">The playback identifier.</param>
+            <returns>
+            TRUE means success, FALSE means failure
+            </returns>
+        </member>
+        <member name="M:Hik.Api.Services.PlaybackService.StartRecording(System.Int32,System.String,System.Int32)">
+            <summary>
+            Start recording live stream to filePath in .mp4 format
+            </summary>
+            <param name="playbackId">playback identifier.</param>
+            <param name="filePath">file path.</param>
+            <param name="channel">channel.</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Services.PlaybackService.StopRecording(System.Int32)">
+            <summary>
+            Stop recording live stream to filePath
+            </summary>
+            <param name="playbackId">The playback identifier.</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Services.PlaybackService.NET_DVR_MakeKeyFrame(System.Int32,System.Int32)">
+            <summary>
+            Make the main stream create a key frame(I frame)
+            </summary>
+            <param name="lUserID">The return value of NET_DVR_Login_V30</param>
+            <param name="lChannel">Channel number.</param>
+            <returns>Return TRUE on success, FALSE on failure. Please call NET_DVR_GetLastError to get the error code.</returns>
+            <remarks>The interface is used to reset I frame, please call NET_DVR_MakeKeyFrame or NET_DVR_MakeKeyFrameSub to reset I frame for the main stream or sub stream according to the set preview parameter NET_DVR_CLIENTINFO.</remarks>
+        </member>
+        <member name="M:Hik.Api.Services.PlaybackService.NET_DVR_SaveRealData(System.Int32,System.String)">
+            <summary>
+            Capture data and save to assigned file
+            </summary>
+            <param name="lRealHandle">The return value of NET_DVR_RealPlay_V30</param>
+            <param name="sFileName">Pointer of file path</param>
+            <returns>Return TRUE on success, FALSE on failure. Please call NET_DVR_GetLastError to get the error code</returns>
+        </member>
+        <member name="M:Hik.Api.Services.PlaybackService.NET_DVR_StopSaveRealData(System.Int32)">
+            <summary>
+            Stop save real data.
+            </summary>
+            <param name="lRealHandle">The return value of NET_DVR_RealPlay_V30</param>
+            <returns>Return TRUE on success, FALSE on failure. Please call NET_DVR_GetLastError to get the error code.</returns>
+        </member>
+        <member name="M:Hik.Api.Services.PlaybackService.NET_DVR_RealPlay_V40(System.Int32,Hik.Api.Struct.Video.NET_DVR_PREVIEWINFO@,Hik.Api.Services.PlaybackService.REALDATACALLBACK,System.IntPtr)">
+            <summary>
+            Real-time preview.
+            </summary>
+            <param name="iUserID">The return value of NET_DVR_Login() or NET_DVR_Login_V30()</param>
+            <param name="lpPreviewInfo">Preview parameters</param>
+            <param name="fRealDataCallBack_V30">code stream data callback function</param>
+            <param name="pUser">User data</param>
+            <returns>1 means failure, other values are used as handle parameters of functions such as NET_DVR_StopRealPlay</returns>
+        </member>
+        <member name="T:Hik.Api.Services.PlaybackService.REALDATACALLBACK">
+            <summary>
+            preview callback
+            </summary>
+            <param name="lRealHandle">The current preview handle</param>
+            <param name="dwDataType"> data type</param>
+            <param name="pBuffer">pointer to the buffer where the data is stored.</param>
+            <param name="dwBufSize">buffer size.</param>
+            <param name="pUser">user data</param>
+        </member>
+        <member name="M:Hik.Api.Services.PlaybackService.NET_DVR_StopRealPlay(System.Int32)">
+            <summary>
+            Stop real-time preview
+            </summary>
+            <param name="iRealHandle">real-time preview handle</param>
+            <returns>TRUE means success, FALSE means failure</returns>
+        </member>
+        <member name="T:Hik.Api.Services.VideoService">
+            <summary>
+            Video service
+            </summary>
+        </member>
+        <member name="M:Hik.Api.Services.VideoService.#ctor(Hik.Api.Abstraction.IHikApi)">
+            <summary>
+            Initializes a new instance of the <see cref="T:Hik.Api.Services.VideoService"/> class.
+            </summary>
+            <param name="session">The session.</param>
+        </member>
+        <member name="M:Hik.Api.Services.VideoService.StartDownloadFile(System.String,System.String)">
+            <summary>
+            Start download File
+            </summary>
+            <param name="sourceFile">Hik remote file name</param>
+            <param name="destinationPath">Save path</param>
+            <returns>Download handler</returns>
+        </member>
+        <member name="M:Hik.Api.Services.VideoService.StopDownloadFile(System.Int32)">
+            <summary>
+            Stop Download File
+            </summary>
+            <param name="fileHandle">Download handler</param>
+        </member>
+        <member name="M:Hik.Api.Services.VideoService.GetDownloadPosition(System.Int32)">
+            <summary>
+            Get the progress of the current download video file
+            </summary>
+            <param name="fileHandle">Download handler</param>
+            <returns></returns>
+        </member>
+        <member name="M:Hik.Api.Services.VideoService.FindNext(System.Int32,Hik.Api.Abstraction.ISourceFile@)">
+             <summary>
+            Get the found file information one by one
+             </summary>
+             <param name="findId">The find identifier.</param>
+             <param name="source">The source.</param>
+             <returns>-1 means failure, and other values are used as parameters of functions such as NET_DVR_FindClose. </returns>
+        </member>
+        <member name="M:Hik.Api.Services.VideoService.StartFind(System.DateTime,System.DateTime,System.Int32)">
+            <summary>Starts the find.</summary>
+            <param name="periodStart">The period start.</param>
+            <param name="periodEnd">The period end.</param>
+            <param name="channel">The channel.</param>
+            <returns>Download handler </returns>
+        </member>
+        <member name="M:Hik.Api.Services.VideoService.StopFind(System.Int32)">
+            <summary>Close the file search and release resources.</summary>
+            <param name="findId">The find identifier.</param>
+            <returns>TRUE means success, FALSE means failure.</returns>
+        </member>
+        <member name="M:Hik.Api.Services.VideoService.NET_DVR_FindClose_V30(System.Int32)">
+            <summary>
+            This API is used to close file search and release the resource.
+            </summary>
+            <param name="lFindHandle">File search handle, return value of NET_DVR_FindFile_V40, NET_DVR_FindFileByEvent or NET_DVR_FindFile_V30</param>
+            <returns>TRUE means success, FALSE means failure.</returns>
+        </member>
+        <member name="M:Hik.Api.Services.VideoService.NET_DVR_FindNextFile_V30(System.Int32,Hik.Api.Struct.Video.NET_DVR_FINDDATA_V30@)">
+            <summary>
+            Get the found file information one by one
+            </summary>
+            <param name="lFindHandle">File search handle, return value of NET_DVR_FindFile_V40 or NET_DVR_FindFile_V30</param>
+            <param name="lpFindData">The pointer to save the file information</param>
+            <returns>-1 indicates failure, and other values indicate the current acquisition status and other information. </returns>
+            <remarks>Before calling this function, please call NET_DVR_FindFile_V30 to get current handle firstly. The interface only supports to get one file. We should call the interface repetitively to get all files. We can get other information, like card number and whether the file is locked,  by calling this API as well.</remarks>
+        </member>
+        <member name="M:Hik.Api.Services.VideoService.NET_DVR_FindFile_V40(System.Int32,Hik.Api.Struct.Video.NET_DVR_FILECOND_V40@)">
+            <summary>
+            Find device video files according to file type and time.
+            </summary>
+            <param name="lUserID">The return value of login interface such as NET_DVR_Login_V40</param>
+            <param name="pFindCond">The file information structure to be found</param>
+            <returns>-1 means failure, and other values are used as parameters of functions such as NET_DVR_FindClose. </returns>
+            <remarks>This interface specifies the information of the video file to be found. After the call is successful, you can call the NET_DVR_FindNextFile_V40 interface to obtain the file information. </remarks>
+        </member>
+        <member name="M:Hik.Api.Services.VideoService.NET_DVR_GetFileByName(System.Int32,System.String,System.String)">
+            <summary>
+            Download video file by file name
+            </summary>
+            <param name="lUserID">The return value of NET_DVR_Login or NET_DVR_Login_V30</param>
+            <param name="sDVRFileName">The name of the video file to be downloaded, the length of the file name must be less than 100 bytes. </param>
+            <param name="sSavedFileName">The file path saved to the PC after downloading, must be an absolute path (including the file name). </param>
+            <returns>Return -1 if it is failed, and other values could be used as the parameter of functions NET_DVR_StopGetFile. Please call NET_DVR_GetLastError to get the error code. </returns>
+            <remarks>Before calling this interface to download file, we can call the interface of searching record file to get file name. The interface have assigned the file to be downloaded currently. After calling it successfully, it needs to call starting play control command NET_DVR_PLAYSTART of NET_DVR_PlayBackControl_V40 to download file. </remarks>
+        </member>
+        <member name="M:Hik.Api.Services.VideoService.NET_DVR_PlayBackControl_V40(System.Int32,System.UInt32,System.IntPtr,System.UInt32,System.IntPtr,System.UInt32@)">
+            <summary>
+            This API is used to control playback status.
+            </summary>
+            <param name="lPlayHandle">play handle, return value of NET_DVR_PlayBackByName, NET_DVR_PlayBackReverseByName or NET_DVR_PlayBackByTime_V40, NET_DVR_PlayBackReverseByTime_V40. </param>
+            <param name="dwControlCode">Control video playback status command</param>
+            <param name="lpInBuffer">Pointer to the input parameter</param>
+            <param name="dwInValue">Input parameter length. Not used, reserved. </param>
+            <param name="lpOutBuffer">Pointer to the output parameter</param>
+            <param name="lPOutValue">The length of the output parameter</param>
+            <returns>TRUE means success, FALSE means failure.</returns>
+        </member>
+        <member name="M:Hik.Api.Services.VideoService.NET_DVR_GetDownloadPos(System.Int32)">
+            <summary>
+            Get the progress of the current download video file
+            </summary>
+            <param name="lFileHandle">Download handle, return value of NET_DVR_GetFileByName, NET_DVR_GetFileByTime_V40 or NET_DVR_GetFileByTime </param>
+            <returns>-1 means failure; 0~100 means the progress of the download; 100 means the end of the download; the normal range is 0-100, if it returns 200, it means that there is a network exception. </returns>
+            <remarks>This interface is used to obtain the download progress when downloading video files by file name. </remarks>
+        </member>
+        <member name="M:Hik.Api.Services.VideoService.NET_DVR_StopGetFile(System.Int32)">
+            <summary>
+            This API is used to stop downloading record files.
+            </summary>
+            <param name="lFileHandle">Download handle, return value of NET_DVR_GetFileByName, NET_DVR_GetFileByTime_V40 or NET_DVR_GetFileByTime. </param>
+            <returns>TRUE means success, FALSE means failure.</returns>
+        </member>
+    </members>
+</doc>

+ 14 - 13
xicheji.csproj

@@ -8,29 +8,26 @@
     <ImplicitUsings>enable</ImplicitUsings>
   </PropertyGroup>
 
+  <ItemGroup>
+    <Compile Remove="release\**" />
+    <EmbeddedResource Remove="release\**" />
+    <None Remove="release\**" />
+  </ItemGroup>
+
   <ItemGroup>
     <PackageReference Include="FreeSql" Version="3.2.825" />
     <PackageReference Include="FreeSql.Provider.Sqlite" Version="3.2.825" />
     <PackageReference Include="Hik.Api" Version="2.0.0" />
     <PackageReference Include="Nancy" Version="2.0.0" />
     <PackageReference Include="Nancy.Hosting.Self" Version="2.0.0" />
-    <PackageReference Include="RestClient" Version="3.1024.23771" />
+    <PackageReference Include="RestSharp" Version="111.2.0" />
     <PackageReference Include="S7netplus" Version="0.20.0" />
   </ItemGroup>
 
   <ItemGroup>
-    <Compile Update="Properties\Resources.Designer.cs">
-      <DesignTime>True</DesignTime>
-      <AutoGen>True</AutoGen>
-      <DependentUpon>Resources.resx</DependentUpon>
-    </Compile>
-  </ItemGroup>
-
-  <ItemGroup>
-    <EmbeddedResource Update="Properties\Resources.resx">
-      <Generator>ResXFileCodeGenerator</Generator>
-      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
-    </EmbeddedResource>
+    <Reference Include="Hik.Api">
+      <HintPath>refs\hik\Hik.Api.dll</HintPath>
+    </Reference>
   </ItemGroup>
 
   <ItemGroup>
@@ -39,4 +36,8 @@
     </None>
   </ItemGroup>
 
+  <ItemGroup>
+    <Folder Include="Properties\" />
+  </ItemGroup>
+
 </Project>

+ 5 - 0
xicheji.sln

@@ -5,6 +5,11 @@ VisualStudioVersion = 17.8.34316.72
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "xicheji", "xicheji.csproj", "{6BAB5EB5-68FC-4C50-A36A-9BBD96FCD7FF}"
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{520592AB-E307-4289-8503-0244FEF8AE8F}"
+	ProjectSection(SolutionItems) = preProject
+		.editorconfig = .editorconfig
+	EndProjectSection
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU