diff --git a/HighWayIot.Rfid/HighWayIot.Rfid.csproj b/HighWayIot.Rfid/HighWayIot.Rfid.csproj index 7cab32e..ecf1762 100644 --- a/HighWayIot.Rfid/HighWayIot.Rfid.csproj +++ b/HighWayIot.Rfid/HighWayIot.Rfid.csproj @@ -46,11 +46,11 @@ - - - - + + + + @@ -61,10 +61,12 @@ {deabc30c-ec6f-472e-bd67-d65702fdaf74} HighWayIot.Log4net - - {dd18a634-1f9c-409a-8c32-c3c81b1b55b5} - HighWayIot.TouchSocket - + + + + + + \ No newline at end of file diff --git a/HighWayIot.Rfid/Impl/RFLY_I160ADAPTER.CS b/HighWayIot.Rfid/Impl/RFLY_I160ADAPTER.CS index 72ad2ce..feb5bf3 100644 --- a/HighWayIot.Rfid/Impl/RFLY_I160ADAPTER.CS +++ b/HighWayIot.Rfid/Impl/RFLY_I160ADAPTER.CS @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using System.Threading; +using TagInfo = HighWayIot.Rfid.TagInfo; namespace MaterialTraceability.Rfid.Impl { diff --git a/HighWayIot.Rfid/RecvState.cs b/HighWayIot.Rfid/RecvState.cs new file mode 100644 index 0000000..80de38d --- /dev/null +++ b/HighWayIot.Rfid/RecvState.cs @@ -0,0 +1,21 @@ +namespace HighWayIot.Rfid +{ + public enum RecvState + { + //RFly-I160 返回数据 BB DD 00 01 40 41 0D + WaitingBeginChar1_State = 1, //等待接收帧同步字符1 0xBB + WaitingBeginChar2_State = 2, //等待接收帧同步字符2 0xDD + WaitingForBarcodeLength_State = 3, //等待条码长度不固定 + WaitingForCode_State = 4, //等待指令编号Code 0x02 + WaitingForStus_State = 5, //等待接受状态码 0x00 + WaitingForTagCount_State = 6, //等待接受标签组数不固定 + WaitingForCount_State = 7, //等待接收第一组标签读取次数 0x01 + WaitingForRSSI_State = 8, //等待接收读取信号强度 0xCB + WaitingForAnt_State = 9, //等待接收天线端口 0x01 + WaitingForPC1_State = 10, //等待接收EPC区域 0x00 + WaitingForPC2_State = 11, //等待接收EPC区域 0x00 + WaitingForData_State = 12, //等待接收数据字符 + WaitingForXor_State = 13, //等待比对校验位 + WaitingForEndChar_State = 14, //等待接收尾字符 0x0D + } +} \ No newline at end of file diff --git a/HighWayIot.Rfid/RfidAbsractFactory.cs b/HighWayIot.Rfid/RfidAbsractFactory.cs new file mode 100644 index 0000000..61580ef --- /dev/null +++ b/HighWayIot.Rfid/RfidAbsractFactory.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; + +namespace HighWayIot.Rfid +{ + /// + /// RFID抽象工厂 + /// + public abstract class RfidAbsractFactory + { + + public string ConfigKey { get; set; } + + /// + /// 建立连接 + /// + /// + /// + /// + public abstract bool Connect(string ip, int port); + + /// + /// 按时间段盘点 + /// + /// + /// + public abstract List TimePeriodRead(int timeout = 5000); + } +} \ No newline at end of file diff --git a/HighWayIot.Rfid/RflyFactory.cs b/HighWayIot.Rfid/RflyFactory.cs new file mode 100644 index 0000000..7c611ad --- /dev/null +++ b/HighWayIot.Rfid/RflyFactory.cs @@ -0,0 +1,459 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using HighWayIot.Common; +using HighWayIot.Log4net; +using HighWayIot.Rfid.Dto; +using TouchSocket.Core; +using TouchSocket.Sockets; + + +namespace HighWayIot.Rfid +{ + public class RflyFactory:RfidAbsractFactory + { + private LogHelper log = LogHelper.Instance; + private readonly TcpClient _tcpClient = new TcpClient(); + private readonly StringChange _stringChange; + + public RflyFactory(StringChange stringChange) + { + + _stringChange = stringChange; + } + + /// + /// 建立连接 + /// + /// + /// + /// + /// + public override bool Connect(string ip, int port) + { + try + { + + _tcpClient.Connect(ip,port); + return true; + } + catch (Exception e) + { + throw new InvalidOperationException($"设备连接异常:{e.Message}"); + } + } + + /// + /// 按时间段盘点 + /// + /// + /// + /// + public override List TimePeriodRead(int timeout = 5000) + { + byte[] u16byte = new byte[2]; + byte[] bCRC = new byte[4]; + try + { + #region 指令封装 + MessagePack pMessagePack = new MessagePack(); + pMessagePack.m_pData = new byte[8]; + pMessagePack.m_pData[0] = 0xAA; + pMessagePack.m_pData[1] = 0x55; + pMessagePack.m_pData[2] = 0x02; + pMessagePack.m_pData[3] = 0x02; + u16byte = BitConverter.GetBytes(timeout); //超时时间 + u16byte = _stringChange.Swap16Bytes(u16byte); //协议里为大端在前 + Array.Copy(u16byte, 0, pMessagePack.m_pData, 4, 2); + Array.Copy(pMessagePack.m_pData, 2, bCRC, 0, 4); + pMessagePack.m_pData[6] = _stringChange.CalculateVerify(bCRC, bCRC.Length); + pMessagePack.m_pData[7] = 0x0D; + #endregion + + var waitClient = _tcpClient.CreateWaitingClient(new WaitingOptions() + { + FilterFunc = response => + { + return true; + } + }); + + byte[] reciveBuffer = waitClient.SendThenReturn(pMessagePack.m_pData, timeout); + + log.Info($"接收原始报文:{_stringChange.bytesToHexStr(reciveBuffer,reciveBuffer.Length)}"); + + byte[] resultBuffer = PareReceiveBufferData(reciveBuffer,reciveBuffer.Length); + + List tagInfoList = Device_DealTagInfoList(resultBuffer); + + return tagInfoList; + } + catch (Exception e) + { + throw new InvalidOperationException($"按时间段盘点异常:{e.Message}"); + } + } + + #region 标签解析 + + /// + /// 状态机函数 + /// + /// + /// + /// + /// + private byte[] PareReceiveBufferData(byte[] buffer, int iLen) + { + RecvState enumRecvState = RecvState.WaitingBeginChar1_State; + int m_iPosition = 0; + UInt16 m_iFullMessageLength = 0; + int iBarcodeLength = 0;//条码长度 + ArrayList m_FrecvData = new ArrayList(); + byte m_iVerify = 0; + try + { + var bufferStr = _stringChange.bytesToHexStr(buffer, iLen); + byte[] m_szFullMessage = new byte[iLen]; + for (int i = 0; i < iLen; i++) + { + switch (enumRecvState) + { + case RecvState.WaitingBeginChar1_State: //开始接受数据帧1 0xBB + Array.Clear(m_szFullMessage, 0, iLen);//清空为0 + if (buffer[i] == 0xBB) + { + m_szFullMessage[m_iPosition] = buffer[i]; + m_iPosition++; + enumRecvState = RecvState.WaitingBeginChar2_State; + } + else + { + m_iFullMessageLength = 0; + m_iPosition = 0; + enumRecvState = RecvState.WaitingBeginChar1_State; + } + break; + case RecvState.WaitingBeginChar2_State: //开始接受数据帧1 0xDD + if (buffer[i] == 0xDD) + { + m_szFullMessage[m_iPosition] = buffer[i]; + m_iPosition++; + enumRecvState = RecvState.WaitingForBarcodeLength_State; + } + else + { + m_iFullMessageLength = 0; + m_iPosition = 0; + enumRecvState = RecvState.WaitingBeginChar1_State; + } + break; + case RecvState.WaitingForBarcodeLength_State: //开始接受数据长度(TagCount - EPC) + m_szFullMessage[m_iPosition] = buffer[i]; + iBarcodeLength = buffer[i]; //单组标签:18;两组标签:35 + m_iPosition++; + enumRecvState = RecvState.WaitingForCode_State; + break; + + case RecvState.WaitingForCode_State: //开始接受指令编号 + if (buffer[i] == 0x02) + { + m_szFullMessage[m_iPosition] = buffer[i]; + m_iPosition++; + enumRecvState = RecvState.WaitingForStus_State; + } + else if (buffer[i] == 0x90) // 如果是心跳BB DD 01 90 00 1F 8E 0D + { + m_szFullMessage[m_iPosition] = buffer[i]; + m_iPosition++; + enumRecvState = RecvState.WaitingForEndChar_State; + } + else if (buffer[i] == 0xBF) // 如果是心跳BB DD 04 BF 00 00 00 F9 0B 49 0D + { + m_szFullMessage[m_iPosition] = buffer[i]; + m_iPosition++; + enumRecvState = RecvState.WaitingForEndChar_State; + } + else + { + m_iFullMessageLength = 0; + m_iPosition = 0; + enumRecvState = RecvState.WaitingBeginChar1_State; + } + break; + case RecvState.WaitingForStus_State: //开始接受状态码 + if (buffer[i] == 0x00) + { + m_szFullMessage[m_iPosition] = buffer[i]; + m_iPosition++; + enumRecvState = RecvState.WaitingForTagCount_State; + } + else if (buffer[i] == 0x40) + { + m_szFullMessage[m_iPosition] = buffer[i]; + //LogService.Instance.Debug("RFU620等待接受WaitingForEndChar_State:Noread"); + lock (m_FrecvData) + { + m_FrecvData.Add(m_szFullMessage); + } + m_iPosition = 0; + i = iLen; + enumRecvState = RecvState.WaitingBeginChar1_State; + //LogService.Instance.Debug("RFly-I160状态机结束。"); + } + break; + case RecvState.WaitingForTagCount_State: //开始接受标签组数 + Array.Copy(buffer, i, m_szFullMessage, m_iPosition, iBarcodeLength);//m_iPosition = 5 + byte[] tempData = new byte[iBarcodeLength]; + Array.Clear(tempData, 0, iBarcodeLength); + Array.Copy(buffer, i, tempData, 0, iBarcodeLength); + m_iPosition = m_iPosition + iBarcodeLength; //m_iPosition = 39 + i = i + iBarcodeLength - 1; //i = 39 + enumRecvState = RecvState.WaitingForXor_State; + break; + case RecvState.WaitingForXor_State: //开始比对校验位 Rfly160 + byte[] m_CRCVerify = new byte[1024]; //此数组用于校验位计算 + Array.Clear(m_CRCVerify, 0, m_CRCVerify.Length); + Array.Copy(m_szFullMessage, 2, m_CRCVerify, 0, iBarcodeLength + 3); //校验位计算是从Length - EPC 结束 + m_szFullMessage[m_iPosition] = buffer[i]; + m_iVerify = m_szFullMessage[m_iPosition]; + if (m_iVerify == _stringChange.CalculateVerify(m_CRCVerify, m_CRCVerify.Length)) + { + m_iPosition++; + enumRecvState = RecvState.WaitingForEndChar_State; + } + else //如果校验不成功 + { + m_iFullMessageLength = 0; + m_iPosition = 0; + enumRecvState = RecvState.WaitingBeginChar1_State; + } + break; + case RecvState.WaitingForEndChar_State: + if (buffer[0] == 0xBB && buffer[1] == 0xDD && buffer[2] == 0x00 && buffer[3] != 0x90) //此处为Noread数据显示 + { + m_szFullMessage[0] = 0xBB; + m_szFullMessage[1] = 0xDD; + m_szFullMessage[2] = 0x00; + lock (m_FrecvData) + { + m_FrecvData.Add(m_szFullMessage); + } + m_iPosition = 0; + i = iLen; + enumRecvState = RecvState.WaitingBeginChar1_State; + } + else if (buffer[0] == 0xBB && buffer[1] == 0xDD && buffer[2] == 0x04 && buffer[3] == 0xBF) + { + Array.Copy(buffer, 0, m_szFullMessage, 0, 11); + i = 11; + lock (m_FrecvData) + { + m_FrecvData.Add(m_szFullMessage); + } + i = iLen; + } + else if (buffer[i] == 0x00) //获取温度 + { + Array.Copy(buffer, 0, m_szFullMessage, 0, 8); + i = 8; + lock (m_FrecvData) + { + m_FrecvData.Add(m_szFullMessage); + } + i = iLen; + } + else if (buffer[i] == 0x11) + { + Array.Copy(buffer, 0, m_szFullMessage, 0, 7); + i = 7; + lock (m_FrecvData) + { + m_FrecvData.Add(m_szFullMessage); + } + } + else if (buffer[i] == 0x01) + { + Array.Copy(buffer, 0, m_szFullMessage, 0, 8); + i = 8; + lock (m_FrecvData) + { + m_FrecvData.Add(m_szFullMessage); + } + } + else + { + m_szFullMessage[m_iPosition] = buffer[i]; + m_iPosition++; + if (buffer[i] == 0x0D) + { + lock (m_FrecvData) + { + m_FrecvData.Add(m_szFullMessage); + } + } + } + m_iPosition = 0; + enumRecvState = RecvState.WaitingBeginChar1_State; + break; + } + } + + return m_szFullMessage; + } + catch (Exception e) + { + throw new InvalidOperationException($"状态机逻辑处理异常:{e.Message}"); + } + } + + private Mutex mutauto = new Mutex(); + /// + /// 解析函数 + /// + /// + /// + /// + public List Device_DealTagInfoList(byte[] AutoDealReportData) + { + List tagInfoList = new List(); + byte[] bResultEPC_Data = new byte[14]; + byte[] m_AutoReadEPC = null; + int m_readEPCDataLen = 0; + try + { + mutauto.WaitOne(); + int iFirstCountPos = 6; //第一次读取标签次数位置 + int iFirstRSSIPos = 7; //第一次读取标签强度位置 + int iFirstAnt = 8; + int iFirstPC = 9; //第一次读取标签天线位置 + int iFirstLeftBarcketPos = 11;//EPC数据起始位置 + UInt16 tempDataCount = 0; + int tempDataRSSI = 0; + UInt16 tempDataANT = 0; + int iBarcodeGroupCount = Convert.ToInt32(AutoDealReportData[5].ToString()); //标签组数 + int iBarcodeLength = 16; //标签长度 + int iCommonSecondFlag = 0; + for (int j = 0; j < iBarcodeGroupCount; j++) + { + TagInfo tag = new TagInfo(); + byte[] tempPCByte = new byte[2]; //取出PC + Array.Clear(tempPCByte, 0, 2); + Array.Copy(AutoDealReportData, iFirstPC, tempPCByte, 0, 2); + + int pc = Convert.ToInt32(tempPCByte[0].ToString("X")); + int epcLength = EPCLengthByPC(pc); + iBarcodeLength = epcLength; + + byte[] tempDataByte = new byte[epcLength]; + Array.Clear(tempDataByte, 0, iBarcodeLength); + Array.Copy(AutoDealReportData, iFirstLeftBarcketPos, tempDataByte, 0, iBarcodeLength); + + byte[] tempCountByte = new byte[1]; //取出标签次数 + Array.Clear(tempCountByte, 0, 1); + Array.Copy(AutoDealReportData, iFirstCountPos, tempCountByte, 0, 1); + tempDataCount = tempCountByte[0]; + + byte[] tempRSSIByte = new byte[1]; //取出标签强度 + Array.Clear(tempRSSIByte, 0, 1); + Array.Copy(AutoDealReportData, iFirstRSSIPos, tempRSSIByte, 0, 1); + + tempDataRSSI = _stringChange.HexStringToNegative(_stringChange.bytesToHexStr(tempRSSIByte, 1)); + + #region add by wenjy 20220829 取出天线号 + byte[] tempAntByte = new byte[1]; //取出天线号 + Array.Clear(tempAntByte, 0, 1); + Array.Copy(AutoDealReportData, iFirstAnt, tempAntByte, 0, 1); + tempDataANT = tempAntByte[0]; + #endregion + + tag.Count = tempDataCount; + tag.RSSI = tempDataRSSI; + tag.EPC = tempDataByte; + + if (pc == 24) + { + tag.EPCstring = _stringChange.bytesToHexStr(tempDataByte, tempDataByte.Length).Substring(0, 7); + } + else + { + tag.EPCstring = Encoding.ASCII.GetString(tempDataByte); + } + + tag.PC = tempPCByte; + tag.Antana = tempDataANT; + tagInfoList.Add(tag); + int iBarcodeListLen = tagInfoList.Count; //特别注意,必须这样,要不然会多一条数据 + + iFirstCountPos = iFirstCountPos + iBarcodeLength + 5; //次数 + iFirstRSSIPos = iFirstCountPos + 1; //强度 + iFirstAnt = iFirstRSSIPos + 1; //天线 + iFirstPC = iFirstAnt + 1; + iFirstLeftBarcketPos = iFirstLeftBarcketPos + iBarcodeLength + 5; + + log.Info("----函数调用:Device_DealTagInfoList 第[" + (iCommonSecondFlag + 1) + "]次数据解析为:" + tag.EPCstring + ",读取标签次数:[" + tempDataCount + "],标签信号强度:[" + tempDataRSSI + "],天线号:[" + tempDataANT + "]"); + iCommonSecondFlag++; + if (iCommonSecondFlag == iBarcodeGroupCount) + { + mutauto.ReleaseMutex(); + log.Info("《《《返回标签数据!"); + return tagInfoList; + } + } + return tagInfoList; + } + catch (Exception ex) + { + mutauto.ReleaseMutex(); + throw new InvalidOperationException($"Device_AutoDealContent 自动处理函数异常:{ex.Message}"); + } + } + + /// + /// 根据PC获取EPC长度 + /// + /// + /// + private int EPCLengthByPC(int pcValue) + { + int epcLength = 0; + if (pcValue >= 10 && pcValue < 20) + { + epcLength = 4; + } + else if (pcValue >= 20 && pcValue < 30) + { + epcLength = 8; + } + else if (pcValue >= 30 && pcValue < 40) + { + epcLength = 12; + } + else if (pcValue >= 40 && pcValue < 50) + { + epcLength = 16; + } + else if (pcValue >= 50 && pcValue < 60) + { + epcLength = 20; + } + else if (pcValue >= 60 && pcValue < 70) + { + epcLength = 24; + } + else if (pcValue >= 70 && pcValue < 80) + { + epcLength = 28; + } + else if (pcValue >= 80 && pcValue < 90) + { + epcLength = 30; + } + return epcLength; + } + + #endregion + } +} \ No newline at end of file diff --git a/HighWayIot.Rfid/TagInfo.cs b/HighWayIot.Rfid/TagInfo.cs new file mode 100644 index 0000000..4a06ce4 --- /dev/null +++ b/HighWayIot.Rfid/TagInfo.cs @@ -0,0 +1,17 @@ +using System; + +namespace HighWayIot.Rfid +{ + public class TagInfo + { + public byte[] PC = new byte[2]; + public int Count { get; set; } + public int RSSI{ get; set; } + public int Antana{ get; set; } + public byte[] EPC{ get; set; } + public byte[] Data{ get; set; } + public string PCstring = (string) null; + public string EPCstring = (string) null; + public DateTime Time{ get; set; } + } +} \ No newline at end of file diff --git a/HighWayIot.TouchSocket/Class1.cs b/HighWayIot.TouchSocket/Class1.cs deleted file mode 100644 index 87303d7..0000000 --- a/HighWayIot.TouchSocket/Class1.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace HighWayIot.TouchSocket -{ - public class Class1 - { - } -} diff --git a/HighWayIot.TouchSocket/HighWayIot.TouchSocket.csproj b/HighWayIot.TouchSocket/HighWayIot.TouchSocket.csproj deleted file mode 100644 index d5e47b8..0000000 --- a/HighWayIot.TouchSocket/HighWayIot.TouchSocket.csproj +++ /dev/null @@ -1,52 +0,0 @@ - - - - - Debug - AnyCPU - {DD18A634-1F9C-409A-8C32-C3C81B1B55B5} - Library - Properties - HighWayIot.TouchSocket - HighWayIot.TouchSocket - v4.8 - 512 - true - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - ..\HighWayIot.Library\TouchSocket.dll - - - - - - - - \ No newline at end of file diff --git a/HighWayIot.TouchSocket/Properties/AssemblyInfo.cs b/HighWayIot.TouchSocket/Properties/AssemblyInfo.cs deleted file mode 100644 index b32fba1..0000000 --- a/HighWayIot.TouchSocket/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// 有关程序集的一般信息由以下 -// 控制。更改这些特性值可修改 -// 与程序集关联的信息。 -[assembly: AssemblyTitle("HighWayIot.TouchSocket")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("HighWayIot.TouchSocket")] -[assembly: AssemblyCopyright("Copyright © 2023")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// 将 ComVisible 设置为 false 会使此程序集中的类型 -//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 -//请将此类型的 ComVisible 特性设置为 true。 -[assembly: ComVisible(false)] - -// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID -[assembly: Guid("dd18a634-1f9c-409a-8c32-c3c81b1b55b5")] - -// 程序集的版本信息由下列四个值组成: -// -// 主版本 -// 次版本 -// 生成号 -// 修订号 -// -//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 -//通过使用 "*",如下所示: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/HighWayIot.sln b/HighWayIot.sln index bfc33c2..5ecd2da 100644 --- a/HighWayIot.sln +++ b/HighWayIot.sln @@ -15,8 +15,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HighWayIot.Plc", "HighWayIo EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HighWayIot.Rfid", "HighWayIot.Rfid\HighWayIot.Rfid.csproj", "{29813574-49C0-4979-A5A6-47EB7C4288A0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HighWayIot.TouchSocket", "HighWayIot.TouchSocket\HighWayIot.TouchSocket.csproj", "{DD18A634-1F9C-409A-8C32-C3C81B1B55B5}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HighWayIot.Winform", "HighWayIot.Winform\HighWayIot.Winform.csproj", "{E36F832C-5F90-491C-B3B7-E94C734FD292}" EndProject Global @@ -49,10 +47,6 @@ Global {29813574-49C0-4979-A5A6-47EB7C4288A0}.Debug|Any CPU.Build.0 = Debug|Any CPU {29813574-49C0-4979-A5A6-47EB7C4288A0}.Release|Any CPU.ActiveCfg = Release|Any CPU {29813574-49C0-4979-A5A6-47EB7C4288A0}.Release|Any CPU.Build.0 = Release|Any CPU - {DD18A634-1F9C-409A-8C32-C3C81B1B55B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DD18A634-1F9C-409A-8C32-C3C81B1B55B5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DD18A634-1F9C-409A-8C32-C3C81B1B55B5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DD18A634-1F9C-409A-8C32-C3C81B1B55B5}.Release|Any CPU.Build.0 = Release|Any CPU {E36F832C-5F90-491C-B3B7-E94C734FD292}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E36F832C-5F90-491C-B3B7-E94C734FD292}.Debug|Any CPU.Build.0 = Debug|Any CPU {E36F832C-5F90-491C-B3B7-E94C734FD292}.Release|Any CPU.ActiveCfg = Release|Any CPU