Selaa lähdekoodia

图片上传修改

liu.ben 4 päivää sitten
vanhempi
commit
253a781521

+ 337 - 93
MainForm/ClassFile/XiaomiAPI_MES/XiaomiMESHttp_UpLoadFile.cs

@@ -1,9 +1,13 @@
 using Newtonsoft.Json;
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
+using System.Net.Http;
+using System.Security.Cryptography;
 using System.Security.Policy;
 using System.Text;
+using System.Threading.Tasks;
 using static MainForm.ClassFile.XiaomiAPI.XiaomiMqttClient_Extend;
 using static MainForm.ClassFile.XiaomiAPI_MES.XiaomiMESHttp_StationInbound;
 
@@ -27,146 +31,386 @@ namespace MainForm.ClassFile.XiaomiAPI_MES
         /// </summary>
         protected new static string Method { set; get; } = "UploadMqtt";
         #endregion 变量
+        /// <summary>
+        /// 文件上传到 MES 系统
+        /// </summary>
+        /// <param name="wJPath">文件路径</param>
+        /// <param name="fileUpload_X5">文件上传参数</param>
+        /// <param name="fileMqttPayload">MQTT 负载参数</param>
+        /// <returns>(状态码, 结果信息)</returns>
+        public static async Task<(int, string)> FileUoladToMes(string wJPath, FileUpload_X5 fileUpload_X5, FileMqttPayload fileMqttPayload,string toPath)
+        {
+            try
+            {
+                // 基础参数
+                string url = "https://im.pre.mi.com/file/x5/file/upload/mqtt";
+                //这个之后要加到配置文件config中
+                string appid = "Auto-Soft";
+                //这个之后要加到配置文件config中
+                string appkey = "5984710e-bb38-4806-b94d-7a9a727e3880";
+                string method = "UploadMqtt";
+
+                // 检查文件是否存在
+                if (!System.IO.File.Exists(wJPath))
+                {
+                    return (-1, "文件不存在");
+                }
+                string newPath=CopyAndDeleteFile(wJPath, toPath);
+                // 获取文件信息
+                FileInfo file = new FileInfo(newPath);
+                string fileMd5Hex = GetMD5Hex(file);
+
+                // 构造 body
+                string body = BuildBody(fileUpload_X5, fileMqttPayload);
+
+                // 计算 sign
+                string sign = GetSign(appid + body + appkey); // MD5 加密
+
+                // 构造 header
+                Dictionary<string, string> header = BuildHeader(url, appid, method, sign);
+
+                // 构造 data 参数
+                Dictionary<string, object> dataParam = new Dictionary<string, object>
+                {
+                    { "header", header },
+                    { "body", body }
+                };
+
+                // 将 data 参数序列化为 Base64 编码的字符串
+                string data = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(dataParam)));
+
+                // 调用上传方法
+                var uploadResult = await UploadFile(url, file, data);
+
+                // 判断上传结果
+                if (!string.IsNullOrEmpty(uploadResult) && !uploadResult.StartsWith("异常:") && !uploadResult.StartsWith("HTTP 错误:"))
+                {
+                    return (0, "文件上传成功");
+                }
+                else
+                {
+                    return (-2, $"文件上传失败: {uploadResult}");
+                }
+            }
+            catch (Exception ex)
+            {
+                return (-3, $"发生异常: {ex.Message}");
+            }
+        }
 
         /// <summary>
-        /// 小米上传文档
+        /// 将文件复制到目标文件夹,并删除源文件
         /// </summary>
-        /// <param name="requestBody"></param>
+        /// <param name="sourceFilePath">源文件路径</param>
+        /// <param name="destinationFolderPath">目标文件夹路径</param>
+        static string CopyAndDeleteFile(string sourceFilePath, string destinationFolderPath)
+        {
+            try
+            {
+                // 检查目标文件夹是否存在,如果不存在则创建
+                if (!Directory.Exists(destinationFolderPath))
+                {
+                    Directory.CreateDirectory(destinationFolderPath);
+                }
+
+                // 构建目标文件的完整路径
+                string fileName = Path.GetFileName(sourceFilePath); // 获取源文件的文件名
+                string destinationFilePath = Path.Combine(destinationFolderPath, fileName);
+
+                // 如果目标文件已存在,则删除已有文件以避免冲突
+                if (File.Exists(destinationFilePath))
+                {
+                    File.Delete(destinationFilePath); // 删除已有文件
+                }
+
+                // 检查文件是否准备好
+                if (!IsFileReady(sourceFilePath))
+                {
+                    throw new IOException($"文件 {sourceFilePath} 正被其他进程占用,无法进行复制和删除操作。");
+                }
+
+                // 复制文件到目标文件夹
+                File.Copy(sourceFilePath, destinationFilePath);
+
+                // 删除源文件
+                File.Delete(sourceFilePath);
+
+                Console.WriteLine($"文件已从 {sourceFilePath} 成功复制到 {destinationFilePath} 并删除原文件。");
+
+                // 返回目标文件路径
+                return destinationFilePath;
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine($"文件转移失败: {ex.Message}");
+                return null; // 或者返回空字符串,根据需求决定
+            }
+        }
+        public static bool IsFileReady(string filePath)
+        {
+            try
+            {
+                using (FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
+                {
+                    stream.Close();
+                }
+                return true;
+            }
+            catch (IOException)
+            {
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// 文件MD5加密
+        /// </summary>
+        /// <param name="file"></param>
         /// <returns></returns>
-        public static XmMES_UpFile_Response UpFilePost(XmMES_UpFile_Request_Body body)
+        public static string GetMD5Hex(FileInfo file)
         {
-            XmMES_UpFile_Response stationInResponse = new XmMES_UpFile_Response();
-
-            string bodyJson = JsonConvert.SerializeObject(body);
-            XiaomiMES_X5RequestHeader header = new XiaomiMES_X5RequestHeader();
-            header.appid = Appid;                               // 系统分配的应⽤ID
-            header.method = Method;                             // API接⼝名称
-            header.sign = GetSign_Up(Appid, bodyJson, Appkey);  // md5签名
-            header.url = UpFileUrl;                                // 接⼝地址
-
-            //XmMES_StationInRequest request = new XmMES_StationInRequest();
-            //request.header = header;
-            //request.body = body;
-            //string data = JsonConvert.SerializeObject(request);
-
-            //转base64
-            dynamic requestData = new { header = header, body = bodyJson };
-            var serializedBody = JsonConvert.SerializeObject(requestData);
-            var base64EncodedBody = Convert.ToBase64String(Encoding.UTF8.GetBytes(serializedBody));
-            XiaomiMES_X5Response response = Post(UpFileUrl, base64EncodedBody);
-            // ZS保存日志
-
-
-            stationInResponse.header = response.header;
-            string responseBody = response.body;
-            stationInResponse.body = JsonConvert.DeserializeObject<XmMES_UpFile_Response_Body>(responseBody);
-            return stationInResponse;
+            using (MD5 md5 = MD5.Create())
+            {
+                using (FileStream stream = file.OpenRead())
+                {
+                    byte[] hashBytes = md5.ComputeHash(stream);
+                    StringBuilder sb = new StringBuilder();
+                    for (int i = 0; i < hashBytes.Length; i++)
+                    {
+                        sb.Append(hashBytes[i].ToString("x2"));
+                    }
+                    return sb.ToString();
+                }
+            }
         }
+        /// <summary>
+        /// 数据pin接
+        /// </summary>
+        /// <param name="file"></param>
+        /// <param name="fileMd5Hex"></param>
+        /// <returns></returns>
+        public static string BuildBody(FileUpload_X5 file, FileMqttPayload payload)
+        {
+            Dictionary<string, object> fileMetadata = new Dictionary<string, object>();
+            Dictionary<string, string> mqttPayLoad = new Dictionary<string, string>();
+            mqttPayLoad.Add("factory", payload.factory);
+            mqttPayLoad.Add("project_name", payload.project_name);
+            mqttPayLoad.Add("product_mode", payload.product_mode);
+            mqttPayLoad.Add("line_no", payload.line_no);
+            mqttPayLoad.Add("work_station_no", payload.work_station_no);
+            mqttPayLoad.Add("equipment_no", payload.equipment_no);
+            mqttPayLoad.Add("station_no", payload.station_no);
+            mqttPayLoad.Add("file_id", payload.file_id);
+            mqttPayLoad.Add("file_name", payload.file_name);
+            mqttPayLoad.Add("sn", payload.sn);
+            mqttPayLoad.Add("opt_time", payload.opt_time);
+            mqttPayLoad.Add("file_type", payload.file_type);
+            mqttPayLoad.Add("file_category", payload.file_category);
+            mqttPayLoad.Add("tag", payload.tag);
+            mqttPayLoad.Add("reference_info", Newtonsoft.Json.JsonConvert.SerializeObject(new object[] { new { pass_station_id = payload.pass_station_id } }));
+
 
-        #region 入参
+            fileMetadata.Add("bucket", file.bucket);
+            fileMetadata.Add("name", file.name);
+            fileMetadata.Add("uuid", file.uuid);
+            fileMetadata.Add("md5", file.md5);
+            fileMetadata.Add("uploadCloud", file.uploadCloud);
+            fileMetadata.Add("informMqtt", file.informMqtt);
+            fileMetadata.Add("mqttPayload", Newtonsoft.Json.JsonConvert.SerializeObject(mqttPayLoad));
+            string body = Newtonsoft.Json.JsonConvert.SerializeObject(fileMetadata);
+            return body;
+        }
         /// <summary>
-        /// 上传图片 - 入参
+        /// 数据头拼接
         /// </summary>
-        public class XmMES_UpFile_Request
+        /// <param name="url"></param>
+        /// <param name="appid"></param>
+        /// <param name="method"></param>
+        /// <param name="sign"></param>
+        /// <returns></returns>
+        public static Dictionary<string, string> BuildHeader(string url, string appid, string method, string sign)
         {
-            /// <summary>
-            /// 进站接⼝ - 入参 - header
-            /// </summary>
-            public XiaomiMES_X5RequestHeader header { get; set; } = new XiaomiMES_X5RequestHeader();
+            Dictionary<string, string> header = new Dictionary<string, string>();
+            header.Add("appid", appid);
+            header.Add("method", method);
+            header.Add("sign", sign);
+            header.Add("url", url);
+            return header;
+        }
 
-            /// <summary>
-            /// 进站接⼝ - 入参 - body
-            /// </summary>
-            public XmMES_UpFile_Request_Body body { get; set; } = new XmMES_UpFile_Request_Body();
+        public static string GetGuid()
+        {
+            return (System.Guid.NewGuid().ToString("N"));
         }
 
         /// <summary>
-        /// 进站接⼝ - 入参 - Body 实体
+        /// 异步文件上传
         /// </summary>
-        public class XmMES_UpFile_Request_Body
+        /// <param name="url">上传地址</param>
+        /// <param name="file">文件路径</param>
+        /// <param name="data">上传的数据</param>
+        /// <returns>返回上传结果</returns>
+        public static async Task<string> UploadFile(string url, FileInfo file, string data)
+        {
+            using (var httpClient = new HttpClient())
+            {
+                var formData = new MultipartFormDataContent();
+                // 添加文件
+                var fileContent = new StreamContent(file.OpenRead());
+                formData.Add(fileContent, "file", file.Name);
+                // 添加数据
+                formData.Add(new StringContent(data), "data");
+
+                try
+                {
+                    var response = await httpClient.PostAsync(url, formData);
+                    if (response.IsSuccessStatusCode)
+                    {
+                        return await response.Content.ReadAsStringAsync();
+                    }
+                    else
+                    {
+                        return $"HTTP 错误: {response.StatusCode}";
+                    }
+                }
+                catch (Exception e)
+                {
+                    return $"异常: {e.Message}";
+                }
+            }
+        }
+
+        /// <summary>
+        /// MD5加密
+        /// </summary>
+        /// <param name="data"></param>
+        /// <returns></returns>
+        public static string GetSign(string data)
+        {
+            // 实例化一个md5对像
+            MD5 md5 = MD5.Create();
+            // MD5加密
+            byte[] encodingMd5Data = md5.ComputeHash(Encoding.UTF8.GetBytes(data));
+            // 生成签名字段
+            string sign = "";
+            for (int i = 0; i < encodingMd5Data.Length; i++)
+            {
+                // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符
+                sign += encodingMd5Data[i].ToString("X2");
+            }
+            return sign;
+        }
+
+
+        public class FileUpload_X5
         {
             /// <summary>
-            /// ⽂件所属包  格式为:/A/B,如/home/work/app
+            /// ⽂件所属包
+            /// 必填
+            /*
+             ${file_category}/${file_type}/${项⽬号}/${⽣
+                产阶段}/${运⾏模式}/${过站结果}/${装备编
+                码}/${sn}/${pass_station_id}
+                • 其中file_category的枚举值为:
+                ◦ IMAGE
+                ◦ TEXT
+                • 若对应字段的值为空,则使⽤默认值
+                UNKNOWN
+                注意:⾸位不能出现/,否则会出现路径错误
+                问题。
+                如:
+                正确⽰例
+                IMAGE/IMAGE/N3/debug/online/PASS/MPA-0001/P320N000006B/382f55e9-c2bb 
+             */
             /// </summary>
             public string bucket { get; set; } = string.Empty;
             /// <summary>
-            /// ⽂件名
+            /// 件名
             /// </summary>
             public string name { get; set; } = string.Empty;
             /// <summary>
-            /// ⽂件内容
-            /// </summary>
-            public string file { get; set; } = string.Empty;
-            /// <summary>
-            /// ⽂件唯⼀标识  可选项,⽤于⾃⾏⽣成⽂件标识符,⽂件服务后台会进⾏判重
+            /// 文件唯一标识符
             /// </summary>
             public string uuid { get; set; } = string.Empty;
             /// <summary>
-            /// 可选项,⽤于校验⽂件上传是否正确
+            /// md5 传空
             /// </summary>
             public string md5 { get; set; } = string.Empty;
             /// <summary>
-            /// 是否上云
-            /// </summary>
-            public bool uploadCloud { get; set; } = false;
-            /// <summary>
-            /// 是否通知mqtt
+            /// 是否上云 默认true
             /// </summary>
-            public bool informMqtt { get; set; } = false;
+            public Boolean uploadCloud { get; set; }
             /// <summary>
-            /// 发送通知时的负载
+            /// 是否通知Mqtt 默认true
             /// </summary>
-            public string mqttPayload { get; set; } = string.Empty;
-        }
-        #endregion
+            public Boolean informMqtt { get; set; }
 
+        }
 
-        #region 出参
-        /// <summary>
-        /// 上传图片 - 出参
-        /// </summary>
-        public class XmMES_UpFile_Response
+        public class FileMqttPayload
         {
             /// <summary>
-            /// header字段描述
+            /// 工厂编码
             /// </summary>
-            public XiaomiMES_X5ResponseHeader header { get; set; } = new XiaomiMES_X5ResponseHeader();
-
+            public string factory { get; set; } = string.Empty;
             /// <summary>
-            /// body字段描述
+            /// 项目号
             /// </summary>
-            public XmMES_UpFile_Response_Body body { get; set; } = new XmMES_UpFile_Response_Body();
-        }
-
-        /// <summary>
-        /// 出参
-        /// </summary>
-        public class XmMES_UpFile_Response_Body
-        {
+            public string project_name { get; set; } = string.Empty;
             /// <summary>
-            /// 关键参数代码
-            /// 200:成功
-            /// 400:参数错误
-            /// 500:服务器内部错误
+            /// 生产阶段
             /// </summary>
-            public string code { get; set; } = string.Empty;
+            public string product_mode { get; set; } = string.Empty;
             /// <summary>
-            /// 关键参数msg
+            /// 线体
             /// </summary>
-            public string msg { get; set; } = string.Empty;
+            public string line_no { get; set; } = string.Empty;
             /// <summary>
-            /// 关键参数值,如果是⽂件,这⾥是下载⽂件的url
+            /// 工站
             /// </summary>
-            public UploadResult data { get; set; } = new UploadResult();
-
+            public string work_station_no { get; set; } = string.Empty;
+            /// <summary>
+            /// 装备
+            /// </summary>
+            public string equipment_no { get; set; } = string.Empty;
+            /// <summary>
+            /// 工位
+            /// </summary>
+            public string station_no { get; set; } = string.Empty;
+            /// <summary>
+            /// 文件ID
+            /// </summary>
+            public string file_id { get; set; } = string.Empty;
+            /// <summary>
+            /// 文件名
+            /// </summary>
+            public string file_name { get; set; } = string.Empty;
+            /// <summary>
+            /// 产品sn    
+            /// </summary>
+            public string sn { get; set; } = string.Empty;
+            /// <summary>
+            /// 文件生成时间
+            /// </summary>
+            public string opt_time { get; set; } = string.Empty;
+            /// <summary>
+            /// 文件类型
+            /// </summary>
+            public string file_type { get; set; } = string.Empty;
+            /// <summary>
+            /// 文件类别
+            /// </summary>
+            public string file_category { get; set; } = string.Empty;
+            /// <summary>
+            /// 自定义标签信息
+            /// </summary>
+            public string tag { get; set; } = string.Empty;
+            /// <summary>
+            /// 关联业务信息
+            /// </summary>
+            public string pass_station_id { get; set; } = string.Empty;
         }
 
-        public class UploadResult
-        {
-            public string uuid { get; set; } = string.Empty;
-
-        }
-        #endregion 出参
     }
 
 

+ 208 - 215
MainForm/FaForm/Form_Home.cs

@@ -40,6 +40,7 @@ using System.Net.Http;
 using static MainForm.ClassFile.XiaomiAPI_MES.XiaomiMESHttp_UpLoadFile;
 using MathNet.Numerics.Statistics;
 using System.Runtime.Remoting.Contexts;
+using System.Collections;
 
 /*
  * 注:本源码对外提供,所以有些地方使用中文命名方法及变量
@@ -1203,10 +1204,10 @@ namespace MainForm
         /// <returns>上传成功时返回1;失败返回0</returns>
         private int SwitctProcessData(string stationNameStr, List<TestItem> items, string equipmentCode, string processItem,
             string workorder_code, string batch_num, string mtltmrk, string proDate,
-            string supplierCode, string sn, bool pass, string vehicleSn, string vehicleSlot, string MachineId, string StationId, string PartBarcode)
+            string supplierCode, string sn, bool pass, string vehicleSn, string vehicleSlot, string MachineId, string StationId, string PartBarcode, string fileName, string bucket, Dictionary<Guid, string> uuidDictionary)
         {
             return SaveProcessDataByDB(stationNameStr, items, equipmentCode, processItem, workorder_code, batch_num, mtltmrk,
-                proDate, supplierCode, sn, pass, vehicleSn, vehicleSlot, MachineId, StationId, PartBarcode);
+                proDate, supplierCode, sn, pass, vehicleSn, vehicleSlot, MachineId, StationId, PartBarcode, fileName, bucket,uuidDictionary);
         }
 
         /// <summary>
@@ -1224,7 +1225,7 @@ namespace MainForm
         /// <returns>上传成功时返回1;失败返回0</returns>
         public int SaveProcessDataByDB(string stationNameStr, List<TestItem> items, string equipmentCode,
             string processItem, string workorder_code, string batch_num, string mtltmrk,
-            string proDate, string supplierCode, string sn, bool pass, string vehicleSn, string vehicleSlot, string machineId, string stationId, string partBarcode)
+            string proDate, string supplierCode, string sn, bool pass, string vehicleSn, string vehicleSlot, string machineId, string stationId, string partBarcode,string fileName,string bucket, Dictionary<Guid, string> uuidDictionary)
         {
             int upload = 0;
             int result = 0;
@@ -1274,6 +1275,19 @@ namespace MainForm
                         });  // 设备数据 - 部件码
                     }
 
+                    //图片上传的uuid
+                    foreach (var entry in uuidDictionary)
+                    {
+                        Guid uuid = entry.Key; // 获取 UUID
+                        outRequest_Body.unitData.fileData.Add(
+                       new XmMES_StationOutRequest_Body.XmStationOut_FileData()
+                       {
+                           fileName = fileName,
+                           fileId= uuid.ToString(),
+                           bucket = bucket
+                       });  
+                    }
+
                     string jsonstr1 = JsonConvert.SerializeObject(outRequest_Body);
 
                     if (GlobalContext.IsSendProcessData)
@@ -1331,14 +1345,18 @@ namespace MainForm
         /// <param name="stationName"></param>
         private void SaveDBbyFileInfo(OP40_MesData_t stPLC_MesData, string stationCode, string stationName)
         {
-            string path = GlobalContext.UpFilePath;
+            //string path = GlobalContext.UpFilePath;
+            string path = "D:\\TempNew";
             string leftPath = path + "\\Left";
             string rightPath = path + "\\Right";
+            string toPath = "D:\\Temp";
             string sql = "";
             Guid guid;
             int result = 0;
             var formData = new MultipartFormDataContent();
 
+            // 创建一个字典,键为 UUID
+            Dictionary<Guid, string> uuidDictionary = new Dictionary<Guid, string>();
             // 获取所有图片文件
             List<string> imageFiles_L = GetAllImageFiles(leftPath);
             List<string> imageFiles_R = GetAllImageFiles(rightPath);
@@ -1347,7 +1365,7 @@ namespace MainForm
                 foreach (string imageFile in imageFiles_L)
                 {
                     guid = Guid.NewGuid();
-                    //formData = MultipartbyFile(imageFile);
+                    uuidDictionary[guid] = "";
                     sql = string.Format("INSERT INTO [dbo].[DataFiles](stationCode,stationName,CarrierBarcode,ProductBarcode,bucket,fileName,fileContext,uuid,fileUrl,status,submitTime,createTime) " +
                         "VALUES('{0}','{1}','{2}' ,'{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}')"
                         , stationCode
@@ -1364,11 +1382,48 @@ namespace MainForm
                         , DateTime.Now
                         );
                     string ret = SQLHelper_New.ExecuteNonQuery(sql, null);
-                    sendPostFile(path, Path.GetFileName(imageFile), guid.ToString(), "");
+
+
+                    FileUpload_X5 fileUpload_X5 = new FileUpload_X5();
+                    string bucket = string.Empty;
+                    bucket = "IMAGE/IMAGE/N3/debug/online/PASS/M0002PA-0001/P320N000006B/382f55e9-c2bb";
+                    fileUpload_X5.bucket = bucket;
+                    fileUpload_X5.name = imageFile;
+                    fileUpload_X5.md5 = "";
+                    fileUpload_X5.uploadCloud = true;
+                    fileUpload_X5.informMqtt = true;
+
+                    FileMqttPayload fileMqttPayload = new FileMqttPayload();
+                    fileMqttPayload.factory = "";
+                    fileMqttPayload.project_name = "";
+                    fileMqttPayload.product_mode = "";
+                    fileMqttPayload.line_no = "";
+                    fileMqttPayload.work_station_no = "";
+                    fileMqttPayload.equipment_no = "";
+                    fileMqttPayload.station_no = "";
+                    fileMqttPayload.file_id = "";
+                    fileMqttPayload.file_name = "";
+                    fileMqttPayload.sn = "";
+                    fileMqttPayload.opt_time = "";
+                    fileMqttPayload.file_type = "";
+                    fileMqttPayload.file_category = "";
+                    fileMqttPayload.tag = "";
+                    fileMqttPayload.pass_station_id = "";
+
+                    //FileUpload_X5 fileUpload_X5 = new FileUpload_X5();
+                    //FileMqttPayload fileMqttPayload = new FileMqttPayload();
+                    //fileUpload_X5.bucket = "IMAGE/IMAGE/N3/debug/online/PASS/M0002PA-0001/P320N000006B/382f55e9-c2bb";
+                    //fileUpload_X5.name = "test";
+                    //fileUpload_X5.md5 = "";
+                    //fileUpload_X5.uploadCloud = true;
+                    //fileUpload_X5.informMqtt = true;
+
+                    var fileresult = XiaomiMESHttp_UpLoadFile.FileUoladToMes(imageFile, fileUpload_X5, fileMqttPayload, toPath);
                 }
                 foreach (string imageFile in imageFiles_R)
                 {
-                    //formData = MultipartbyFile(imageFile);
+                    guid = Guid.NewGuid();
+                    uuidDictionary[guid] = "";
                     sql = string.Format("INSERT INTO [dbo].[DataFiles](stationCode,stationName,CarrierBarcode,ProductBarcode,bucket,fileName,fileContext,uuid,fileUrl,status,submitTime,createTime) " +
                         "VALUES('{0}','{1}','{2}' ,'{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}')"
                         , stationCode
@@ -1440,69 +1495,6 @@ namespace MainForm
             }
         }
 
-        public int sendPostFile(string bucket, string filename,string guid, string context)
-        {
-            int result = 0;
-
-            XmMES_UpFile_Request_Body inRequest_Body = new XmMES_UpFile_Request_Body();
-            inRequest_Body.bucket = bucket;
-            inRequest_Body.name = filename;
-            inRequest_Body.uuid = guid;
-            inRequest_Body.file = context;     
-
-            string json_Body = JsonConvert.SerializeObject(inRequest_Body);
-            //await Task.Delay(200);
-            // 上传MES
-            if (GlobalContext.IsSendStationIn)
-            {
-                try
-                {
-                    XmMES_UpFile_Response response = new XmMES_UpFile_Response();
-                    string mesRet = string.Empty;
-                    int i = 0;
-                    while (i < 2)  // 1009会多次尝试上传
-                    {
-                        response = XiaomiMESHttp_UpLoadFile.UpFilePost(inRequest_Body);
-                        if (response != null && response.header.code == "200")
-                            break;
-                        else if (!mesRet.Contains("1009"))  // 1009是未知错误
-                            i++;
-
-                        i++;
-
-                        mesRet = $"[{response?.header?.code}]{response?.header?.desc}";
-                        // 记录失败原因
-                        OnMessage(LogType.Error, "上传出站数据到MES服务器---失败!正在重新上传!接口报错信息:" + mesRet + "参数:" + json_Body);
-                    }
-
-
-                    if (response?.header?.code == "200")
-                    {
-                        //string sql_Upd = stationIn.ToStringUpdateStatusByID(1);
-                        //string ret_Upd = SQLHelper_New.ExecuteNonQuery(sql_Upd, null);
-                        //result = ret_Upd == "成功" ? 1 : 6;
-                        //AddMessage(LogType.Info, $"【进站数据 SN {stationIn.Sn}】上传MES服务器---成功");
-                    }
-                    else
-                    {
-                        result = 5;
-                        //AddMessage(LogType.Info, $"【进站数据 SN {stationIn.Sn}】上传MES服务器---失败!接口报错信息:" + mesRet);
-                    }
-                    //string sql_response = stationIn.ToStringUpdateStationInReturn_body(JsonConvert.SerializeObject(response));
-                    //SQLHelper_New.ExecuteNonQuery(sql_response, null);
-                }
-                catch (Exception ex)
-                {
-                    result = 6;
-                    string str = ex.StackTrace;
-                    //AddMessage_Station(stationNameStr, LogType.Error, $"PLC上传进站数据MES报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
-                }
-            }
-
-            return result;
-        }
-
-
         //private void CollectAndProcessDataLeft(string sn, string direction, string ip, string port, int connectTimeOut, int sendDataTimeOut)
         //{
         //    Stopwatch stopwatch = new Stopwatch();
@@ -2108,7 +2100,7 @@ namespace MainForm
 
                 //出站接口
                 int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
-    , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId, "");
+    , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId, "", "", "", null);
 
                 byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
 
@@ -2403,7 +2395,7 @@ namespace MainForm
 
 
                 int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
-   , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId, PartBarcode);
+   , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId, PartBarcode, "", "", null);
 
                 byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
 
@@ -2790,7 +2782,7 @@ namespace MainForm
                 if (direction == "Right")
                 { 
                      result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
-   , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId, "");
+   , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId, "", "", "", null);
                 }
 
                 byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
@@ -3073,6 +3065,142 @@ namespace MainForm
                 sn = strProductBarcode;
                 AddMessage(LogType.Info, $"载具码:{CarrierBarcode};产品码:{sn}");
 
+                //图片上传,这个地方之后可以放到一个方法里,uuid先 生成传进去就好
+                string path = GlobalContext.UpFilePath;
+                string leftPath = path + "\\Left";
+                string rightPath = path + "\\Right";
+                string toPath = "D:\\MESFile\\ImageLog"; //这个参数之后写GlobalContext和那些log的地址参数放一起,全局搜WorkLogDir可以找到
+                DateTime now = DateTime.Now;
+                //复制图片的地址
+                string fullToPath = Path.Combine(
+                    toPath,
+                    $"{now:yyyy-MM-dd}", // 年月日
+                    $"{sn}_{now:HHmmss}" // SN 加上时间(小时分钟秒)
+                );
+                string sql = "";
+                string fileName = string.Empty;
+                string bucket = string.Empty;
+                Guid guid;
+
+                // 创建一个字典,这个字段之后作为参数传给出站接口
+                Dictionary<Guid, string> uuidDictionary = new Dictionary<Guid, string>();
+                // 获取所有图片文件
+                List<string> imageFiles_L = GetAllImageFiles(leftPath);
+                List<string> imageFiles_R = GetAllImageFiles(rightPath);
+                try
+                {
+                    foreach (string imageFile in imageFiles_L)
+                    {
+                        guid = Guid.NewGuid();
+                        uuidDictionary[guid] = "";
+                        fileName = Path.GetFileName(imageFile);
+                        sql = string.Format("INSERT INTO [dbo].[DataFiles](stationCode,stationName,CarrierBarcode,ProductBarcode,bucket,fileName,fileContext,uuid,fileUrl,status,submitTime,createTime) " +
+                            "VALUES('{0}','{1}','{2}' ,'{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}')"
+                            , stationCode
+                            , stationName
+                            , stPLC_MesData.BarcodeSet.strCarrierBarcode
+                            , stPLC_MesData.BarcodeSet.strProductBarcode
+                            , "/mesCommToPC/pic/left"
+                            , fileName
+                            , ""
+                            , guid.ToString()
+                            , ""
+                            , 0
+                            , ""
+                            , DateTime.Now
+                            );
+                        string ret = SQLHelper_New.ExecuteNonQuery(sql, null);
+
+
+                        FileUpload_X5 fileUpload_X5 = new FileUpload_X5();
+                        //这个字段现在随便写写,有几个参数不确认拿什么值
+                        bucket = "IMAGE/IMAGE/N3/debug/online/PASS/M0002PA-0001/P320N000006B/382f55e9-c2bb";
+                        fileUpload_X5.bucket = bucket;
+                        fileUpload_X5.name = imageFile;
+                        fileUpload_X5.md5 = "";
+                        fileUpload_X5.uploadCloud = true;
+                        fileUpload_X5.informMqtt = true;
+
+                        //这边有的值不确定,写了的值也再检查下
+                        FileMqttPayload fileMqttPayload = new FileMqttPayload();
+                        fileMqttPayload.factory = GlobalContext.Factory_Code; ;
+                        fileMqttPayload.project_name = "";
+                        fileMqttPayload.product_mode = "";
+                        fileMqttPayload.line_no = "";
+                        fileMqttPayload.work_station_no = "";
+                        fileMqttPayload.equipment_no = MachineId;
+                        fileMqttPayload.station_no = StationId;
+                        fileMqttPayload.file_id = guid.ToString();
+                        fileMqttPayload.file_name = fileName;
+                        fileMqttPayload.sn = sn;
+                        fileMqttPayload.opt_time = "";
+                        fileMqttPayload.file_type = "IMAGE";
+                        fileMqttPayload.file_category = "IMAGE";
+                        fileMqttPayload.tag = "";
+                        fileMqttPayload.pass_station_id = "";
+
+                        var fileresult = XiaomiMESHttp_UpLoadFile.FileUoladToMes(imageFile, fileUpload_X5, fileMqttPayload, toPath);
+                   
+                    }
+                    foreach (string imageFile in imageFiles_R)
+                    {
+                        guid = Guid.NewGuid();
+                        uuidDictionary[guid] = "";
+                        fileName = Path.GetFileName(imageFile);
+                        sql = string.Format("INSERT INTO [dbo].[DataFiles](stationCode,stationName,CarrierBarcode,ProductBarcode,bucket,fileName,fileContext,uuid,fileUrl,status,submitTime,createTime) " +
+                            "VALUES('{0}','{1}','{2}' ,'{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}')"
+                            , stationCode
+                            , stationName
+                            , stPLC_MesData.BarcodeSet.strCarrierBarcode
+                            , stPLC_MesData.BarcodeSet.strProductBarcode
+                            , "/mesCommToPC/pic/right"
+                            , fileName
+                            , ""
+                            , ""
+                            , ""
+                            , 0
+                            , ""
+                            , DateTime.Now
+                            );
+                        string ret = SQLHelper_New.ExecuteNonQuery(sql, null);
+
+                        FileUpload_X5 fileUpload_X5 = new FileUpload_X5();
+                        //这个字段现在随便写写,有几个参数不确认拿什么值
+                        bucket = "IMAGE/IMAGE/N3/debug/online/PASS/M0002PA-0001/P320N000006B/382f55e9-c2bb";
+                        fileUpload_X5.bucket = bucket;
+                        fileUpload_X5.name = imageFile;
+                        fileUpload_X5.md5 = "";
+                        fileUpload_X5.uploadCloud = true;
+                        fileUpload_X5.informMqtt = true;
+
+                        //这边有的值不确定,写了的值也再检查下
+                        FileMqttPayload fileMqttPayload = new FileMqttPayload();
+                        fileMqttPayload.factory = GlobalContext.Factory_Code; ;
+                        fileMqttPayload.project_name = "";
+                        fileMqttPayload.product_mode = "";
+                        fileMqttPayload.line_no = "";
+                        fileMqttPayload.work_station_no = "";
+                        fileMqttPayload.equipment_no = MachineId;
+                        fileMqttPayload.station_no = StationId;
+                        fileMqttPayload.file_id = guid.ToString();
+                        fileMqttPayload.file_name = fileName;
+                        fileMqttPayload.sn = sn;
+                        fileMqttPayload.opt_time = "";
+                        fileMqttPayload.file_type = "IMAGE";
+                        fileMqttPayload.file_category = "IMAGE";
+                        fileMqttPayload.tag = "";
+                        fileMqttPayload.pass_station_id = "";
+
+                        var fileresult = XiaomiMESHttp_UpLoadFile.FileUoladToMes(imageFile, fileUpload_X5, fileMqttPayload, toPath);
+
+                    }
+                }
+                catch (Exception)
+                {
+                    AddMessage_Station(stationName, LogType.Error, $"图片保存失败!载具码:{stPLC_MesData.BarcodeSet.strCarrierBarcode}产品码{stPLC_MesData.BarcodeSet.strProductBarcode}");
+                }
+
+
                 List<TestItem> items = new List<TestItem>();
                 items.Add(new TestItem()
                 {
@@ -3088,7 +3216,7 @@ namespace MainForm
                 });
 
                 int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
-   , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId, "");
+   , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId, "", fileName,bucket, uuidDictionary);
 
                 byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
 
@@ -3377,7 +3505,7 @@ namespace MainForm
                 });
 
                 int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
-   , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId, PartBarcode);
+   , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId, PartBarcode,"", "", null);
 
                 byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
 
@@ -3664,7 +3792,7 @@ namespace MainForm
                 });
 
                 int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
-    , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId, "");
+    , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId, "", "", "", null);
 
                 byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
 
@@ -4041,7 +4169,7 @@ namespace MainForm
                 if (direction == "Right")
                 { 
                     SwitctProcessData(stationNameStr, items, equipmentCode, processItem
-   , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId, "");
+   , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId, "", "", "", null);
                    
                 }
 
@@ -4356,7 +4484,7 @@ namespace MainForm
                 });
 
                 int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
-   , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId, "");
+   , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId, "", "", "", null);
 
                 byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
 
@@ -4636,7 +4764,7 @@ namespace MainForm
                 });
 
                 int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
-   , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId, "");
+   , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId, "", "", "", null);
 
                 byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
 
@@ -5293,142 +5421,7 @@ namespace MainForm
             AddMessage(LogType.Info, stationNameStr + "_上料进站校验;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" + stopwatch2.ElapsedMilliseconds + "ms");
         }
 
-        /// <summary>
-        /// [S1] Tray盘上料装备(板测)- 出站接口
-        /// </summary>
-        /// <param name="plcNo"></param>
-        /// <param name="stationCode"></param>
-        /// <param name="stationName"></param>
-        private void S1出站接口(int plcNo, string stationCode, string stationName)
-        {
-            Stopwatch stopwatch1 = new Stopwatch();
-            Stopwatch stopwatch2 = new Stopwatch();
-
-            string equipmentCode = GlobalContext.LineCode + "-" + stationCode;  // 设备编号
-            string stationNameStr = stationCode + stationName;
-            string processItem = stationName;  // 测试项目
-            try
-            {
-                stopwatch1.Start();
-
-                string workorder_code = GlobalContext.WorkOrderCode;  // 工单号
-                //string batch_num = GlobalContext.BatchNumber;         // 批次号
-                string mtltmrk = GlobalContext.Mtltmrk;               // 产品型号
-                //string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
-
-                string sn = (string)s1PLCData["a1ProductSN"];       // 产品SN(载具SN码)
-                sn = sn.Replace("\0", "");
-                string partNo1 = (string)s1PLCData["a1PartNo1"];    // 物料码1(穴位1)
-                partNo1 = partNo1.Replace("\0", "");
-                string partNo2 = (string)s1PLCData["a1PartNo2"];    // 物料码2(穴位2)
-                partNo2 = partNo2.Replace("\0", "");
-                int a1Result = (int)s1PLCData["a1Result"];          // 产品结果
-                bool pass = a1Result == 1;
-
-                stopwatch2.Start();
-                // 产品1
-                List<TestItem> items = new List<TestItem>();
-                items.Add(new TestItem()
-                {
-                    Parameter_name = "载具码",
-                    Parameter_value = sn,
-                    Parameter_unit = ""
-                });
-                items.Add(new TestItem()
-                {
-                    Parameter_name = "载具穴号",
-                    Parameter_value = "1",
-                    Parameter_unit = ""
-                });
-                items.Add(new TestItem()
-                {
-                    Parameter_name = "产品结果",
-                    Parameter_value = a1Result == 1 ? "OK" : "NG",
-                    Parameter_unit = ""
-                });
-                int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
-                    , workorder_code, mtltmrk, partNo1, pass, sn, "1");
-
-                // 产品2
-                items = new List<TestItem>();
-                items.Add(new TestItem()
-                {
-                    Parameter_name = "载具码",
-                    Parameter_value = sn,
-                    Parameter_unit = ""
-                });
-                items.Add(new TestItem()
-                {
-                    Parameter_name = "载具穴号",
-                    Parameter_value = "2",
-                    Parameter_unit = ""
-                });
-                items.Add(new TestItem()
-                {
-                    Parameter_name = "产品结果",
-                    Parameter_value = a1Result == 1 ? "OK" : "NG",
-                    Parameter_unit = ""
-                });
-                int result2 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
-                    , workorder_code, mtltmrk, partNo2, pass, sn, "2");
-
-                short result = 0;
-                List<int> results = new List<int>() { result1, result2 };
-                if (result1 == 1 && result2 == 1)
-                    result = 1;
-                else if (results.Contains(3))
-                    result = 3;
-                else if (results.Contains(2))
-                    result = 2;
-                else if (results.Contains(4))
-                    result = 4;
-                else
-                    result = 4;
-                stopwatch2.Stop();
-
-                #region 存储绑定数据到 边线MES系统中
-                if (result == 1)
-                {
-                    string data = string.Concat(partNo1, ".", partNo2);
-                    int resultMesR = XiaomiMES_RouteCommunication.SNBindData(sn, data);
-                    if (resultMesR != 0)
-                    {
-                        result = 4;
-                        AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_[{equipmentCode}]{processItem}过站失败!MES边线程序返回:{resultMesR}");
-                    }
-                }
-                #endregion 存储绑定数据到 边线MES系统中
-
-                // MES_Flag 为MES报错
-                // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
-                //Funs[plcNo].WriteMultipleRegisters<short>(2109, result);  // 4代表上位机报警
-                WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
-                writeToPLC_Flag.Name = "a1MES_FLAG";
-                writeToPLC_Flag.Adress = 2109;
-                writeToPLC_Flag.Value = result;
-                SxPLCWriteData_Add(ref s1PLCWriteData, "a1MES_FLAG", writeToPLC_Flag);
-
-                OnMessage(LogType.Debug, $"PLC{plcNo}_[{equipmentCode}]{processItem}-Write" + (result == 1 ? "成功!" : "失败!"));
-            }
-            catch (Exception ex)
-            {
-                stopwatch2.Restart();
-                // MES_Flag 为4上位机报错
-                //Funs[plcNo].WriteMultipleRegisters<short>(2109, (short)4);  // 4代表上位机报警
-                WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
-                writeToPLC_Flag.Name = "a1MES_FLAG";
-                writeToPLC_Flag.Adress = 2109;
-                writeToPLC_Flag.Value = (short)4;
-                SxPLCWriteData_Add(ref s1PLCWriteData, "a1MES_FLAG", writeToPLC_Flag);
-                stopwatch2.Stop();
-
-                string str = ex.StackTrace;
-                AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_[{equipmentCode}]{processItem}上传加工报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
-            }
-
-            stopwatch1.Stop();
-            AddMessage(LogType.Info, stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;上传接口用时" + stopwatch2.ElapsedMilliseconds + "ms");
-        }
+      
         //// 上传点检数据_ [S1] Tray盘上料装备(板测)
         //private void DoOneCheckData_Tray盘上料装备(int plcNo, string stationCode, string stationName)
         //{

+ 9 - 13
MainForm/MainForm.csproj

@@ -101,7 +101,7 @@
   <ItemGroup>
     <Reference Include="AxInterop.ActUtlTypeLib, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>bin\Debug\AxInterop.ActUtlTypeLib.dll</HintPath>
+      <HintPath>..\packages\AxInterop.ActUtlTypeLib.dll</HintPath>
     </Reference>
     <Reference Include="BouncyCastle.Cryptography, Version=2.0.0.0, Culture=neutral, PublicKeyToken=072edcf4a5328938, processorArchitecture=MSIL">
       <HintPath>..\packages\BouncyCastle.Cryptography.2.2.1\lib\net461\BouncyCastle.Cryptography.dll</HintPath>
@@ -120,24 +120,21 @@
     <Reference Include="Enums.NET, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7ea1c1650d506225, processorArchitecture=MSIL">
       <HintPath>..\packages\Enums.NET.4.0.1\lib\net45\Enums.NET.dll</HintPath>
     </Reference>
-    <Reference Include="FaFrameUI, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>bin\Debug\FaFrameUI.dll</HintPath>
+    <Reference Include="FaFrameUI">
+      <HintPath>..\packages\FaFrameUI.dll</HintPath>
     </Reference>
     <Reference Include="HPSocket.Net, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\packages\HPSocket.Net.6.0.3.1\lib\net40\HPSocket.Net.dll</HintPath>
     </Reference>
-    <Reference Include="HslCommunication, Version=6.1.1.0, Culture=neutral, PublicKeyToken=cdb2261fa039ed67, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>bin\EXE\HslCommunication.dll</HintPath>
+    <Reference Include="HslCommunication">
+      <HintPath>..\packages\HslCommunication.dll</HintPath>
     </Reference>
     <Reference Include="ICSharpCode.SharpZipLib, Version=1.3.3.11, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
       <HintPath>..\packages\SharpZipLib.1.3.3\lib\net45\ICSharpCode.SharpZipLib.dll</HintPath>
     </Reference>
-    <Reference Include="Interop.ActUtlTypeLib, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
+    <Reference Include="Interop.ActUtlTypeLib">
+      <HintPath>..\packages\Interop.ActUtlTypeLib.dll</HintPath>
       <EmbedInteropTypes>True</EmbedInteropTypes>
-      <HintPath>bin\Debug\Interop.ActUtlTypeLib.dll</HintPath>
     </Reference>
     <Reference Include="MathNet.Numerics, Version=4.15.0.0, Culture=neutral, PublicKeyToken=cd8b63ad3d691a37, processorArchitecture=MSIL">
       <HintPath>..\packages\MathNet.Numerics.Signed.4.15.0\lib\net461\MathNet.Numerics.dll</HintPath>
@@ -224,9 +221,8 @@
     <Reference Include="System.Net.Http" />
     <Reference Include="System.Windows.Forms" />
     <Reference Include="System.Xml" />
-    <Reference Include="ZedGraph, Version=5.0.9.41461, Culture=neutral, PublicKeyToken=02a83cbd123fcd60, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>bin\Debug\ZedGraph.dll</HintPath>
+    <Reference Include="ZedGraph">
+      <HintPath>..\packages\ZedGraph.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>