Explorar el Código

封装成库。

sat23 hace 4 años
padre
commit
e72e120118

+ 29 - 0
TCLCommand/TCLCommand.sln

@@ -0,0 +1,29 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TCLCommand", "TCLCommand\TCLCommand.vcproj", "{27E3466D-67B0-42C4-BAB9-B497D6143C61}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		DebugEXE|Win32 = DebugEXE|Win32
+		ExportClass|Win32 = ExportClass|Win32
+		PYD|Win32 = PYD|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{27E3466D-67B0-42C4-BAB9-B497D6143C61}.Debug|Win32.ActiveCfg = Debug|Win32
+		{27E3466D-67B0-42C4-BAB9-B497D6143C61}.Debug|Win32.Build.0 = Debug|Win32
+		{27E3466D-67B0-42C4-BAB9-B497D6143C61}.DebugEXE|Win32.ActiveCfg = DebugEXE|Win32
+		{27E3466D-67B0-42C4-BAB9-B497D6143C61}.DebugEXE|Win32.Build.0 = DebugEXE|Win32
+		{27E3466D-67B0-42C4-BAB9-B497D6143C61}.ExportClass|Win32.ActiveCfg = ExportClass|Win32
+		{27E3466D-67B0-42C4-BAB9-B497D6143C61}.ExportClass|Win32.Build.0 = ExportClass|Win32
+		{27E3466D-67B0-42C4-BAB9-B497D6143C61}.PYD|Win32.ActiveCfg = PYD|Win32
+		{27E3466D-67B0-42C4-BAB9-B497D6143C61}.PYD|Win32.Build.0 = PYD|Win32
+		{27E3466D-67B0-42C4-BAB9-B497D6143C61}.Release|Win32.ActiveCfg = Release|Win32
+		{27E3466D-67B0-42C4-BAB9-B497D6143C61}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 568 - 0
TCLCommand/TCLCommand/Command.cpp

@@ -0,0 +1,568 @@
+#include "StdAfx.h"
+#include "Command.h"
+
+#define NoneOptLen 5
+#define MINSIZE 128
+#define MIDSIZE 4096
+#define MAXSIZE 10240
+
+byte* TCLCommand::m_pData = NULL;
+TCLCommand::TCLCommand(bool bSync):CBaseSerial(bSync ? 0 : FILE_FLAG_OVERLAPPED)
+{
+    m_pData = new byte[MAXSIZE];
+}
+
+TCLCommand::~TCLCommand(void)
+{
+    if (m_pData)
+        delete []m_pData;
+    m_pData = NULL;
+    m_vtExternalCMDParams.clear();
+    m_vtInternalCMDParams.clear();
+}
+
+int TCLCommand::pares_time_value(std::string strTime)
+{
+    int nTimes = 0;
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+    if (strstr(strTime.c_str(), _T("ms")) || strstr(strTime.c_str(), _T("MS")))
+    {
+        nTimes = atol(strTime.c_str());
+    }
+    else if (strstr(strTime.c_str(), _T("s")) || strstr(strTime.c_str(), _T("S")))
+    {
+        nTimes = atol(strTime.c_str()) * 1000;
+    }
+    else if (strstr(strTime.c_str(), _T("m")) || strstr(strTime.c_str(), _T("M")))
+    {
+        nTimes = atol(strTime.c_str()) * 6000;
+    }
+    else
+    {
+        // 不带单位或其他的,默认ms;
+        nTimes = atol(strTime.c_str());
+    }
+#elif _MSC_VER >= 1500
+    if (_tcsstr(strTime.c_str(), _T("ms")) || _tcsstr(strTime.c_str(), _T("MS")))
+    {
+        nTimes = _tstol(strTime.c_str());
+    }
+    else if (_tcsstr(strTime.c_str(), _T("s")) || _tcsstr(strTime.c_str(), _T("S")))
+    {
+        nTimes = _tstol(strTime.c_str()) * 1000;
+    }
+    else if (_tcsstr(strTime.c_str(), _T("m")) || _tcsstr(strTime.c_str(), _T("M")))
+    {
+        nTimes = _tstol(strTime.c_str()) * 6000;
+    }
+    else
+    {
+        // 不带单位或其他的,默认ms;
+        nTimes = _tstol(strTime.c_str());
+    }
+#endif
+
+    return nTimes;
+}
+
+bool TCLCommand::parse_pair_key(std::string& RetValue, std::string strLine, TCHAR* lpszText)
+{
+    TCHAR szText[MAX_PATH] = { 0 };
+    TCHAR szValue[MAX_PATH] = { 0 };
+    // 去除空格;
+#if _MSC_VER > 1900
+    strLine.erase(std::remove_if(strLine.begin(), strLine.end(), [](unsigned char x) {return std::isspace(x); }), strLine.end()); //C++17
+#else
+    for (std::string::iterator it = strLine.begin(); it != strLine.end();) {
+        !isspace(*it) ? it++ : it = it = strLine.erase(it);
+    }
+#endif
+
+#if _MSC_VER >= 1200 && _MSC_VER < 1500 // VC6.0~8.0
+    if (2 == sscanf(strLine.c_str(), _T("%[^=]=%s"), szText, MAX_PATH, szValue, MAX_PATH))
+#else
+    if (2 == _stscanf_s(strLine.c_str(), _T("%[^=]=%s"), szText, MAX_PATH, szValue, MAX_PATH))
+#endif
+    {
+        if (_tcsstr(szText, lpszText)) {
+            RetValue = szValue;
+            return true;
+        }
+    }
+
+    return false;
+}
+
+int TCLCommand::parse_cmds_from_file(const TCHAR* file_name, std::vector<CommandParam>& vtCommandParams)
+{
+    TCHAR buf[MAX_PATH] = { 0 };
+    TCHAR name[MAX_PATH] = { 0 };
+    TCHAR option[MAX_PATH] = { 0 };
+    TCHAR head[MAX_PATH] = { 0 };
+    TCHAR code[MAX_PATH] = { 0 };
+    TCHAR param[MAX_PATH] = { 0 };
+    TCHAR multicode[MAX_PATH] = { 0 };
+    TCHAR cmd_wait_time[MAX_PATH] = { 0 };
+    TCHAR read_wait_time[MAX_PATH] = { 0 };
+
+    int ret = -1;
+    FILE* fp = NULL;
+
+    if (!file_name || file_name[0] == '\0')
+        return ret;
+
+    fp = fopen(file_name, "r");
+    if (!fp)
+        goto EXIT;
+
+    while ((fgets((char*)buf, MAX_PATH, fp) != NULL)) {
+        int tmp_len = 0;
+        tmp_len = _tcslen(buf);
+        if (tmp_len >= 1) {
+            if (buf[tmp_len - 1] == '\r' || buf[tmp_len - 1] == '\n')
+                buf[tmp_len - 1] = 0;
+            if (tmp_len >= 2) {
+                if (buf[tmp_len - 2] == '\r' || buf[tmp_len - 2] == '\n')
+                    buf[tmp_len - 2] = 0;
+            }
+        }
+
+#if _MSC_VER >= 1200 && _MSC_VER < 1500 // VC6.0~8.0 
+        if (sscanf(buf, "%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;]", name, option, head, code, param, multicode, read_wait_time, cmd_wait_time) == 8)
+#elif _MSC_VER >= 1500 
+        //if ( _stscanf_s(buf, "%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;]", name, MAX_PATH, option, MAX_PATH, head, MAX_PATH, code, MAX_PATH, param, MAX_PATH, multicode, MAX_PATH, read_wait_time, MAX_PATH, cmd_wait_time, MAX_PATH) == 8) // 等价下面;
+        if (_stscanf_s(buf, "%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%s", name, MAX_PATH, option, MAX_PATH, head, MAX_PATH, code, MAX_PATH, param, MAX_PATH, multicode, MAX_PATH, read_wait_time, MAX_PATH, cmd_wait_time, MAX_PATH) == 8)
+#endif
+        {
+            CommandParam cp;
+            parse_pair_key(cp.name, name, _T("Name"));
+            parse_pair_key(cp.head, head, _T("HeadCode"));
+            parse_pair_key(cp.code, code, _T("Command"));
+            parse_pair_key(cp.param, param, _T("CMDParam"));
+
+            std::string value;
+            parse_pair_key(value, option, _T("Option"));
+            if (!_tcsicmp(value.c_str(), _T("None")))
+                cp.nOption = CMDOPT_None;
+            else if (!_tcsicmp(value.c_str(), _T("Get")))
+                cp.nOption = CMDOPT_Get;
+            else if (!_tcsicmp(value.c_str(), _T("Set")))
+                cp.nOption = CMDOPT_Set;
+
+            parse_pair_key(value, multicode, _T("MultiParams"));
+            cp.bMulticode = !_tcsicmp(value.c_str(), _T("true")) ? true : false;
+
+            parse_pair_key(value, read_wait_time, _T("ReadWaitTime"));
+            cp.read_wait_time = pares_time_value(value.c_str());
+
+            parse_pair_key(value, cmd_wait_time, _T("CMDWaitTime"));
+            cp.cmd_wait_time = pares_time_value(value.c_str());
+            cp.UpdateRtnCode();
+
+            vtCommandParams.push_back(cp);
+        }
+    }
+
+    ret = 0;
+EXIT:
+    if (fp)
+        fclose(fp);
+    return ret;
+}
+
+void TCLCommand::parse_cmds_from_string(std::string str, std::vector<CommandParam>& vtCommandParams)
+{
+    int nPos(0);
+    TCHAR buf[MAX_PATH] = { 0 };
+    TCHAR name[MAX_PATH] = { 0 };
+    TCHAR option[MAX_PATH] = { 0 };
+    TCHAR head[MAX_PATH] = { 0 };
+    TCHAR code[MAX_PATH] = { 0 };
+    TCHAR param[MAX_PATH] = { 0 };
+    TCHAR multicode[MAX_PATH] = { 0 };
+    TCHAR cmd_wait_time[MAX_PATH] = { 0 };
+    TCHAR read_wait_time[MAX_PATH] = { 0 };
+
+    do 
+    {
+        memset(buf, 0, MAX_PATH);
+        int nPos1 = str.find_first_of('\r');
+        int nPos2 = str.find_first_of('\n');
+        if ( std::string::npos != nPos1 && std::string::npos != nPos2 ) {
+            nPos = nPos1 > nPos2 ? nPos1 : nPos2;
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+			sprintf(buf, _T("%s"), str.substr(0, nPos - 1).c_str());
+#elif _MSC_VER >= 1500
+            _stprintf_s(buf, _T("%s"), str.substr(0, nPos - 1).c_str());
+#endif
+            str = str.substr(nPos+1);
+        } 
+        else if ( std::string::npos != nPos1 ) {
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+			sprintf(buf, _T("%s"), str.substr(0, nPos1 - 1).c_str());
+#elif _MSC_VER >= 1500
+            _stprintf_s(buf, _T("%s"), str.substr(0, nPos1 - 1).c_str());
+#endif
+            str = str.substr(nPos + 1);
+        }
+        else if ( std::string::npos != nPos2 ) {
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+			sprintf(buf, _T("%s"), str.substr(0, nPos2 - 1).c_str());
+#elif _MSC_VER >= 1500
+            _stprintf_s(buf, _T("%s"), str.substr(0, nPos2 - 1).c_str());
+#endif
+            str = str.substr(nPos + 1);
+        }
+        else {
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+			sprintf(buf, _T("%s"), str.c_str());
+#elif _MSC_VER >= 1500
+            _stprintf_s(buf, _T("%s"), str.c_str());
+#endif
+            str = "";
+        }
+
+#if _MSC_VER >= 1200 && _MSC_VER < 1500 // VC6.0~8.0 
+        if (sscanf(buf, "%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;]", name, option, head, code, param, multicode, read_wait_time, cmd_wait_time) == 8)
+#elif _MSC_VER >= 1500 
+        //if ( _stscanf_s(buf, "%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;]", name, MAX_PATH, option, MAX_PATH, head, MAX_PATH, code, MAX_PATH, param, MAX_PATH, multicode, MAX_PATH, read_wait_time, MAX_PATH, cmd_wait_time, MAX_PATH) == 8) // 等价下面;
+        if (_stscanf_s(buf, "%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%s", name, MAX_PATH, option, MAX_PATH, head, MAX_PATH, code, MAX_PATH, param, MAX_PATH, multicode, MAX_PATH, read_wait_time, MAX_PATH, cmd_wait_time, MAX_PATH) == 8)
+#endif
+        {
+            CommandParam cp;
+            parse_pair_key(cp.name, name, _T("Name"));
+            parse_pair_key(cp.head, head, _T("HeadCode"));
+            parse_pair_key(cp.code, code, _T("Command"));
+            parse_pair_key(cp.param, param, _T("CMDParam"));
+
+            std::string value;
+            parse_pair_key(value, option, _T("Option"));
+            if (!_tcsicmp(value.c_str(), _T("None")))
+                cp.nOption = CMDOPT_None;
+            else if (!_tcsicmp(value.c_str(), _T("Get")))
+                cp.nOption = CMDOPT_Get;
+            else if (!_tcsicmp(value.c_str(), _T("Set")))
+                cp.nOption = CMDOPT_Set;
+
+            parse_pair_key(value, multicode, _T("MultiParams"));
+            cp.bMulticode = !_tcsicmp(value.c_str(), _T("true")) ? true : false;
+
+            parse_pair_key(value, read_wait_time, _T("ReadWaitTime"));
+            cp.read_wait_time = pares_time_value(value.c_str());
+
+            parse_pair_key(value, cmd_wait_time, _T("CMDWaitTime"));
+            cp.cmd_wait_time = pares_time_value(value.c_str());
+            cp.UpdateRtnCode();
+
+            vtCommandParams.push_back(cp);
+        }
+    } while (str.size());
+}
+
+bool TCLCommand::GetCommandParams(std::string name, CommandParam& cmdPara)
+{
+    bool bget = false;
+    // 外部优先;
+    for (std::vector<CommandParam>::iterator it = m_vtExternalCMDParams.begin(); it != m_vtExternalCMDParams.end(); it++ )
+    {
+        if ( !_tcsicmp(name.c_str(), it->name.c_str()) ) {
+            bget = true;
+            cmdPara = *it;
+            break;
+        }
+    }
+    
+    if ( !bget )
+    {
+        for (std::vector<CommandParam>::iterator it = m_vtInternalCMDParams.begin(); it != m_vtInternalCMDParams.end(); it++ )
+        {
+            if ( !_tcsicmp(name.c_str(), it->name.c_str()) ) {
+                bget = true;
+                cmdPara = *it;
+                break;
+            }
+        }
+    }
+
+    // 清除状态;
+    cmdPara.Clean();
+
+    return bget;
+}
+
+bool TCLCommand::TheFirstPart(CommandParam& cmdPara, std::string data)
+{
+    if (data.size() == NoneOptLen) {
+        if ((byte)data[0] == cmdPara._rtnCode) {
+            // 长度;
+            int nPacketLen = (byte)data[1];
+            if (nPacketLen != NoneOptLen) {
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+				cmdPara._rtnError = utils::_dprintf("[%s] 返回数据长度错误:%ld", (byte)data[1]);
+#elif _MSC_VER >= 1500
+                cmdPara._rtnError = utils::_dprintf("[%s] 返回数据长度错误:%ld", __FUNCTION__, (byte)data[1]);
+#endif
+                return false;
+            }
+
+            // 执行状态;
+            cmdPara._rtnStatus = (byte)data[2];
+            //utils::_dprintf(_T("[%s] rtnStatus=%02X"), __FUNCTION__, cmdPara._rtnStatus);
+
+            // 校验crc;
+            unsigned short usCRCValue = utils::CRC16Calculate((byte*)data.data(), nPacketLen - 2);
+            if (((usCRCValue >> 8) & 0xFF) != (byte)data[nPacketLen - 2] || (usCRCValue & 0xFF) != (byte)data[nPacketLen - 1]) {
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+				cmdPara._rtnError = utils::_dprintf("CRC校验错误:计算[%02% %02X] != 接收[%02X %02X]", (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, (byte)data[nPacketLen - 2], (byte)data[nPacketLen - 1]);
+#elif _MSC_VER >= 1500
+                cmdPara._rtnError = utils::_dprintf("[%s] CRC校验错误:计算[%02% %02X] != 接收[%02X %02X]", __FUNCTION__, (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, (byte)data[nPacketLen - 2], (byte)data[nPacketLen - 1]);
+#endif
+				return false;
+            }
+        }
+        else {
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+			cmdPara._rtnError = utils::_dprintf("返回码错误:%02X", (byte)data[0]);
+#elif _MSC_VER >= 1500
+            cmdPara._rtnError = utils::_dprintf("[%s] 返回码错误:%02X", __FUNCTION__, (byte)data[0]);
+#endif
+            return false;
+        }
+    }
+    else {
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+		cmdPara._rtnError = utils::_dprintf("返回数据长度错误", (byte)data[0]);
+#elif _MSC_VER >= 1500
+        cmdPara._rtnError = utils::_dprintf("[%s] 返回数据长度错误", __FUNCTION__);
+#endif
+        return false;
+    }
+
+    return true;
+}
+
+bool TCLCommand::TheSecondPart(CommandParam& cmdPara, std::string data)
+{
+    // 数据起始位;
+    int nDataPos = 0;
+    // 数据包长度;
+    int nPacketLen = 0;
+    if ((byte)data[0] == cmdPara._rtnCode) {
+        // 获取长度;
+        if ((byte)data[1] == 0xFE) {
+            nDataPos = 4;
+            nPacketLen = (byte)data[2] << 8 | (byte)data[3];
+            if (data.size() < 255 && data[2] != 0) {
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+				cmdPara._rtnError = utils::_dprintf(_T("返回数据长度异常"));
+#elif _MSC_VER >= 1500
+                cmdPara._rtnError = utils::_dprintf(_T("[%s] 返回数据长度异常"), __FUNCTION__);
+#endif
+                return false;
+            }
+        }
+        else
+        {
+            nDataPos = 2;
+            nPacketLen = (byte)data[1];
+#if 0 // 如果数据包含有非协议包内的数据,会判断异常;
+            if (data.size() > 255) {
+                //nPackageLen = data[1] << 8 | data[2];
+                cmdPara._rtnError = _dprintf(_T("长度异常"));
+                return false;
+            }
+#endif
+        }
+
+#if 0
+        // 计算出的长度,必等于包长;// 如果包含有其他非包数据,会判断异常;
+        if (nPackageLen != data.size())
+            return false;
+#endif
+
+        if (_tcsicmp(cmdPara.code.c_str(), utils::ByteToChars((byte)data[nDataPos] - 1).c_str()) != 0) {
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+			cmdPara._rtnError = utils::_dprintf(_T("返回的指令错误, %s, %02X"), cmdPara.head.c_str(), (byte)data[nDataPos]);
+#elif _MSC_VER >= 1500
+            cmdPara._rtnError = utils::_dprintf(_T("[%s] 返回的指令错误, %s, %02X"), __FUNCTION__, cmdPara.head.c_str(), (byte)data[nDataPos]);
+#endif
+            return false;
+        }
+
+        // 返回的数据;
+        ++nDataPos;// 返回码占一字节;
+        if (cmdPara.bMulticode) {
+            if (_tcsicmp(cmdPara.param.c_str(), utils::ByteToChars((byte)data[nDataPos]).c_str()) != 0) {
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+				cmdPara._rtnError = utils::_dprintf(_T("返回的指令参数错误, %s, %02X"), cmdPara.param.c_str(), (byte)data[nDataPos]);
+#elif _MSC_VER >= 1500
+                cmdPara._rtnError = utils::_dprintf(_T("[%s] 返回的指令参数错误, %s, %02X"), __FUNCTION__, cmdPara.param.c_str(), (byte)data[nDataPos]);
+#endif
+				return false;
+            }
+
+            ++nDataPos;// 指令参数码占一字节;
+        }
+
+        cmdPara._rtnData = data.substr(nDataPos, nPacketLen - nDataPos - 2); //2 = crc;
+        utils::_dprintf(_T("rtnData=%s"), utils::BytesToHexString((byte*)cmdPara._rtnData.c_str(), cmdPara._rtnData.size(), ' ').c_str());
+
+        // 校验crc;
+        unsigned short usCRCValue = utils::CRC16Calculate((byte*)data.data(), nPacketLen - 2);
+        if (((usCRCValue >> 8) & 0xFF) != (byte)data[nPacketLen - 2] || (usCRCValue & 0xFF) != (byte)data[nPacketLen - 1])
+        {
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+			cmdPara._rtnError = utils::_dprintf("CRC校验错误:计算[%02X %02X] != 接收[%02X %02X]", (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, (byte)data[nPacketLen - 2], (byte)data[nPacketLen - 1]);
+#elif _MSC_VER >= 1500
+            cmdPara._rtnError = utils::_dprintf("[%s] CRC校验错误:计算[%02X %02X] != 接收[%02X %02X]", __FUNCTION__, (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, (byte)data[nPacketLen - 2], (byte)data[nPacketLen - 1]);
+#endif
+			return false;
+        }
+
+        if (data.size() > nPacketLen)
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+			utils::_dprintf(_T("带有脏数据:%s"), data.substr(nPacketLen));
+#elif _MSC_VER >= 1500
+            utils::_dprintf("[%s] 带有脏数据:%s", __FUNCTION__, data.substr(nPacketLen));
+#endif
+    }
+    else {
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+        cmdPara._rtnError = utils::_dprintf("返回码错误:%02X", (byte)data[0]);
+#elif _MSC_VER >= 1500
+		cmdPara._rtnError = utils::_dprintf("[%s] 返回码错误:%02X", __FUNCTION__, (byte)data[0]);
+#endif
+        return false;
+    }
+
+    return true;
+}
+
+void TCLCommand::PackingCommand(CommandParam& cmdPara, std::string data, const int& dataLen)
+{
+    // Tag:[命令头][全命令长度][命令码]<命令码参数><附加数据>[crc1][crc2]
+    std::string command;
+    // 命令头标识位;
+    command.append(utils::HexStringToBytes(cmdPara.head, 2).c_str(), cmdPara.head.size() / 2);
+    // 命令码;
+    command.append(utils::HexStringToBytes(cmdPara.code, 2).c_str(), cmdPara.code.size() / 2);
+    // 命令码参数;
+    command.append(utils::HexStringToBytes(cmdPara.param, 2).c_str(), cmdPara.param.size() / 2);
+    // 附加的数据;
+    if (dataLen > 0)
+        command.append(data.c_str(), dataLen);
+
+    int len(0);
+    // 长度:可能1字节表示,超过255用2字节表示;
+    byte szlen[2] = { 0 };
+    //if ((byte)command[1] == 0xFE)
+    //if ( cmdPara.head.size() >= 4 && cmdPara.head.find("FE", 2, 2) != std::string::npos )
+    if (_tcsicmp(_T("AAFE"), cmdPara.head.c_str()) == 0)
+    {// 长度超过255,需要2字节表示;
+        len = command.size() + 4;    // 2位crc + 2位长度;
+        szlen[0] = (len >> 8) & 0xFF;
+        szlen[1] = len & 0xFF;
+        command.insert(2, (char*)szlen, 2);
+    }
+    else {
+        // 2位crc + 1位长度;
+        len = command.size() + 3;
+        //if ( _tcsicmp(cmdPara.code.c_str(), "99 00") == 0 )
+        //    len -= 2;
+
+        if (len > 255) {// 长度超过255,多一个占位符;
+            ++len;
+            szlen[0] = (len >> 8) & 0xFF;
+            szlen[1] = len & 0xFF;
+            command.insert(1, (char*)szlen, 2);
+        }
+        else {
+            szlen[0] = len & 0xFF;
+            command.insert(1, (char*)szlen, 1);
+        }
+    }
+
+    // crc校验;
+    byte szcrc[2] = { 0 };
+    WORD usCRCValue = utils::CRC16Calculate((byte*)command.c_str(), command.size()); // 如果有0断开有危险;
+    //WORD usCRCValue = CRC16Calculate((byte *)command.c_str(), len - 2);
+    szcrc[0] = (usCRCValue >> 8) & 0xFF;
+    szcrc[1] = usCRCValue & 0xFF;
+    command.append((char*)szcrc, 2);
+
+    cmdPara._cmdContext = command;
+    utils::_dprintf(_T("指令:%s = %s"), cmdPara.name.c_str(), utils::BytesToHexString((byte*)command.c_str(), command.size(), ' ').c_str());
+}
+
+bool TCLCommand::ParseResultString(CommandParam& cmdPara, std::string data, const int& dataLen)
+{
+    // Tag:[返回头][全数据长度][返回码]<返回码子项><附加数据>[crc16]
+    if (!TheFirstPart(cmdPara, data.substr(0, 5)))
+        return false;
+
+    if (cmdPara._rtnStatus != 0x0A) {
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+        utils::_dprintf("执行结果错误:%02X", cmdPara._rtnStatus);
+#elif _MSC_VER >= 1500
+        utils::_dprintf("[%s] 执行结果错误:%02X", __FUNCTION__, cmdPara._rtnStatus);
+#endif
+        return false;
+    }
+
+    switch (cmdPara.nOption)
+    {
+    case CMDOPT_None:
+        break;
+    case CMDOPT_Get:
+    case CMDOPT_Set:
+        return TheSecondPart(cmdPara, data.substr(5));
+        break;
+    default:
+        break;
+    }
+
+    return false;
+}
+
+bool TCLCommand::SendCommand(CommandParam& cmdPara)
+{
+    memset(m_pData, 0, MAXSIZE);
+    if (_dwIOMode == FILE_FLAG_OVERLAPPED)
+    {
+        if (!Write((void*)cmdPara._cmdContext.c_str(), cmdPara._cmdContext.size()))
+            return false;
+
+        Sleep(cmdPara.read_wait_time);     
+		int nReadCount = Read(m_pData, MAXSIZE);
+		cmdPara._rtnContext.append((char*)m_pData, nReadCount);
+    }
+    else 
+    {
+        if (!WriteSync((void*)cmdPara._cmdContext.c_str(), cmdPara._cmdContext.size()))
+            return false;
+
+        Sleep(cmdPara.read_wait_time);
+        int nReadCount = ReadSync(m_pData, MAXSIZE);
+		cmdPara._rtnContext.append((char*)m_pData, nReadCount);
+    }
+
+	utils::_dprintf("结果:%s = %s", cmdPara.name.c_str(), utils::BytesToHexString((byte*)cmdPara._rtnContext.c_str(), cmdPara._rtnContext.size(), ' ').c_str());
+	ParseResultString(cmdPara, cmdPara._rtnContext, cmdPara._rtnContext.size());
+    Sleep(cmdPara.cmd_wait_time);
+
+    return cmdPara._rtnStatus == 0x0A ? true : false;
+}
+
+void TCLCommand::SetInternalCMDParams(DWORD dwResouceID)
+{
+    std::string data;
+    if ( utils::GetResourceData(dwResouceID, _T("BIN"), data) )
+    {
+        parse_cmds_from_string(data, m_vtInternalCMDParams);
+    }
+}
+
+void TCLCommand::SetExternalCMDParams(LPCTSTR lpFileName)
+{
+    parse_cmds_from_file(lpFileName, m_vtExternalCMDParams);
+}

+ 31 - 0
TCLCommand/TCLCommand/Command.h

@@ -0,0 +1,31 @@
+#pragma once
+#include "serial.h"
+#include "CommandParam.h"
+
+class TCLCommand :public CBaseSerial
+{
+    static byte* m_pData;
+    // 内部-低优先查找;
+    std::vector<CommandParam> m_vtInternalCMDParams;
+    // 外部-高优先查找;
+    std::vector<CommandParam> m_vtExternalCMDParams;
+public:
+    TCLCommand(bool bSync = true);
+    ~TCLCommand(void);
+
+private:
+    int pares_time_value(std::string strTime);
+    bool parse_pair_key(std::string& RetValue, std::string strLine, TCHAR* lpszText);
+    int parse_cmds_from_file(const TCHAR* file_name, std::vector<CommandParam>& vtCommandParams);
+    void parse_cmds_from_string(std::string str, std::vector<CommandParam>& vtCommandParams);
+
+    bool TheFirstPart(CommandParam& cmdPara, std::string data);
+    bool TheSecondPart(CommandParam& cmdPara, std::string data);    
+    bool ParseResultString(CommandParam& cmdPara, std::string data, const int& dataLen);
+public:
+    void SetInternalCMDParams(DWORD dwResouceID);
+    void SetExternalCMDParams(LPCTSTR lpFileName);
+    bool GetCommandParams(std::string name, CommandParam& cmdPara);
+    bool SendCommand(CommandParam& cmdPara);
+    void PackingCommand(CommandParam& cmdPara, std::string data = "", const int& dataLen = 0);
+};

+ 86 - 0
TCLCommand/TCLCommand/CommandParam.h

@@ -0,0 +1,86 @@
+#pragma once
+
+enum CMDOPT {
+    CMDOPT_None = 0,
+    CMDOPT_Get = 1,
+    CMDOPT_Set = 2
+};
+
+typedef struct __CMDPARAM__ {
+    std::string name;        // 命令描述;
+    std::string head;        // 命令头;
+    std::string code;        // 命令码;
+    std::string param;        // 命令码参数;
+    // 命令属性类型:
+    // 0=None,只返回一段数据包;
+    // 1=Get,返回一段或两段数据包(成功时返回2段,失败时返回1段);
+    // 2=Set,返回一段或两段数据包(成功时返回1段,失败时返回1段);
+    int nOption;
+    bool bMulticode;        // 命令码是否多参数;
+    int cmd_wait_time;        // 两条串口指令间隔时间;
+    int read_wait_time;        // 写完串口后,等待多久读;
+    byte _rtnCode;
+    byte _rtnStatus;
+    std::string _rtnData;
+    std::string _rtnError;
+    std::string _rtnContext;
+    std::string _cmdContext;
+
+    void UpdateRtnCode() {
+        if (!_tcsicmp(_T("AA"), head.c_str())) { // 调试用命令代码引导码;
+            _rtnCode = 0xAB;
+        }
+        else if (!_tcsicmp(_T("AC"), head.c_str())) { // 软件配屏参数调整命令代码引导码;
+            _rtnCode = 0xAD;
+        }
+        else if (!_tcsicmp(_T("AE"), head.c_str())) { // 保留命令发送类型引导码;
+            _rtnCode = 0xAF;
+        }
+    }
+
+    __CMDPARAM__& operator=(const __CMDPARAM__& cls) {
+        if (this != &cls) {
+            name = cls.name;
+            head = cls.head;
+            code = cls.code;
+            param = cls.param;
+            nOption = cls.nOption;
+            bMulticode = cls.bMulticode;
+            cmd_wait_time = cls.cmd_wait_time;
+            read_wait_time = cls.read_wait_time;
+            _rtnCode = cls._rtnCode;
+            _rtnStatus = cls._rtnStatus;
+            _rtnData = cls._rtnData;
+            _rtnError = cls._rtnError;
+            _rtnContext = cls._rtnContext;
+            _cmdContext = cls._cmdContext;
+        }
+
+        return *this;
+    }
+
+    void Clean() {
+        //_rtnCode = 0;
+        _rtnStatus = 0x0E;
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+        _rtnData = "";
+        _rtnError = "";
+        _rtnContext = "";
+        _cmdContext = "";
+#elif _MSC_VER >= 1500
+        _rtnData.clear();
+        _rtnError.clear();
+        _rtnContext.clear();
+        _cmdContext.clear();
+#endif
+    }
+
+    __CMDPARAM__() {
+        _rtnCode = 0;
+        _rtnStatus = 0;
+        nOption = 0;
+        bMulticode = false;
+        cmd_wait_time = 100;
+        read_wait_time = 100;
+    }
+} CommandParam, * pCommandParam;

+ 48 - 0
TCLCommand/TCLCommand/ReadMe.txt

@@ -0,0 +1,48 @@
+========================================================================
+    动态链接库:TCLCommand 项目概述
+========================================================================
+
+应用程序向导已为您创建了此 TCLCommand DLL。
+
+本文件概要介绍组成 TCLCommand 应用程序的
+的每个文件的内容。
+
+
+TCLCommand.vcproj
+    这是使用应用程序向导生成的 VC++ 项目的主项目文件,
+    其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
+
+TCLCommand.cpp
+    这是主 DLL 源文件。
+
+	此 DLL 在创建时不导出任何符号。因此,在生成此 DLL 时
+	将不会产生 .lib 文件。如果希望此项目
+	成为其他某个项目的项目依赖项,则需要
+	添加代码以从 DLL 导出某些符号,
+	以便产生一个导出库,或者,也可以在项目“属性页”对话框中的
+	“链接器”文件夹中,将“常规”属性页上的
+	“忽略输入库”属性设置为“是”。
+
+/////////////////////////////////////////////////////////////////////////////
+应用程序向导创建了下列资源:
+
+TCLCommand.rc
+这是程序使用的所有 Microsoft Windows 资源的列表。它包括 RES 子目录中存储的图标、位图和光标。
+此文件可以直接在 Microsoft Visual C++ 中进行编辑。
+
+Resource.h
+    这是标准头文件,可用于定义新的资源 ID。
+    Microsoft Visual C++ 将读取并更新此文件。
+
+/////////////////////////////////////////////////////////////////////////////
+其他标准文件:
+
+StdAfx.h, StdAfx.cpp
+    这些文件用于生成名为 TCLCommand.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。
+
+/////////////////////////////////////////////////////////////////////////////
+其他注释:
+
+应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。
+
+/////////////////////////////////////////////////////////////////////////////

+ 420 - 0
TCLCommand/TCLCommand/Serial.cpp

@@ -0,0 +1,420 @@
+#include "stdafx.h"
+#include "Serial.h"
+
+
+DCB *CBaseSerial::GetState()
+{
+    return IsOpen() && ::GetCommState(_hCommHandle, &_DCB) == TRUE ? &_DCB : NULL;
+}
+
+bool CBaseSerial::SetState(DCB *pdcb /*= NULL*/)
+{
+    return IsOpen() ? ::SetCommState(_hCommHandle, pdcb == NULL ? &_DCB : pdcb) == TRUE : false;
+}
+
+bool CBaseSerial::SetState(TCHAR *lpszSetStr /* = _T("baud=115200 parity=N data=8 stop=1") */)
+{
+    if (lpszSetStr && lpszSetStr[0] != '\0' && IsOpen())
+    {
+        if (::GetCommState(_hCommHandle, &_DCB) != TRUE)
+            return false;
+        // COMx[:][baud=b][parity=p][data=d][stop=s][to={on|off}][xon={on|off}][odsr={on|off}][octs={on|off}][dtr={on|off|hs}][rts={on|off|hs|tg}][idsr={on|off}]
+        if (::BuildCommDCB(lpszSetStr, &_DCB) != TRUE)
+            return false;
+        return ::SetCommState(_hCommHandle, &_DCB) == TRUE;
+    }
+
+    return false;
+}
+
+bool CBaseSerial::SetState(DWORD dwBaudRate, DWORD dwByteSize /* = 8 */, DWORD dwParity /* = NOPARITY */, DWORD dwStopBits /* = ONESTOPBIT */)
+{
+    if (!IsOpen()) return false;
+
+    if (::GetCommState(_hCommHandle, &_DCB) != TRUE)
+        return false;
+
+    _DCB.BaudRate = dwBaudRate;
+    _DCB.ByteSize = (BYTE)dwByteSize;
+    _DCB.Parity = (BYTE)dwParity;
+    _DCB.StopBits = (BYTE)dwStopBits;
+    return ::SetCommState(_hCommHandle, &_DCB) == TRUE;
+}
+
+LPCOMMTIMEOUTS CBaseSerial::GetTimeouts()
+{
+    return IsOpen() && ::GetCommTimeouts(_hCommHandle, &_CO) == TRUE ? &_CO : NULL;
+}
+
+bool CBaseSerial::SetTimeouts(DWORD ReadIntervalTimeout /* = 0 */, DWORD ReadTotalTimeoutMultiplier /* = 10 */, DWORD ReadTotalTimeoutConstant /* = 1500 */, DWORD WriteTotalTimeoutMultiplier /* = 10 */, DWORD WriteTotalTimeoutConstant /* = 1500 */)
+{
+    COMMTIMEOUTS CO = {
+        ReadIntervalTimeout, 
+        ReadTotalTimeoutMultiplier, 
+        ReadTotalTimeoutConstant, 
+        WriteTotalTimeoutMultiplier, 
+        WriteTotalTimeoutConstant
+    };
+    return IsOpen() ? ::SetCommTimeouts(_hCommHandle, &CO) == TRUE : false;
+}
+
+bool CBaseSerial::SetTimeouts(LPCOMMTIMEOUTS lpCO)
+{
+    return IsOpen() ? ::SetCommTimeouts(_hCommHandle, lpCO) == TRUE : false;
+}
+
+bool CBaseSerial::SetBufferSize(DWORD dwInputSize, DWORD dwOutputSize)
+{
+    // SetupComm设置输入输出缓冲区大小;
+    return IsOpen() ? ::SetupComm(_hCommHandle, dwInputSize, dwOutputSize) == TRUE : false;
+}
+
+void CBaseSerial::SetMaskEvent(DWORD dwEvent /* = DEFAULT_COM_MASK_EVENT */)
+{
+    _dwMaskEvent = dwEvent;
+}
+
+int CBaseSerial::GetInputSize()
+{
+    COMSTAT Stat;
+    DWORD dwError;
+    return ::ClearCommError(_hCommHandle, &dwError, &Stat) == TRUE ? Stat.cbInQue : (DWORD)-1L;
+}
+
+bool CBaseSerial::Open(DWORD dwPort)
+{
+    return Open(dwPort, 19200);
+}
+
+bool CBaseSerial::Open(DWORD dwPort, DWORD dwBaudRate)
+{
+    if (dwPort < 1 || dwPort > 1024)
+        return false;
+
+    BindCommPort(dwPort);
+    if (!OpenCommPort())
+        return false;
+    if (!SetupPort())
+        return false;
+
+    return SetState(dwBaudRate);
+}
+
+bool CBaseSerial::Open(DWORD dwPort, TCHAR *lpszSetStr /* = _T("baud/* =115200 parity/* =N data/* =8 stop/* =1") */ )
+{
+    if (dwPort < 1 || dwPort > 1024)
+        return false;
+
+    BindCommPort(dwPort);
+    if (!OpenCommPort())
+        return false;
+    if (!SetupPort())
+        return false;
+
+    return SetState(lpszSetStr);
+}
+
+DWORD CBaseSerial::Read(LPVOID Buffer, DWORD dwBufferLength, DWORD dwWaitTime /* = 100 */)
+{
+    if (!IsOpen())
+        return 0;
+
+    COMSTAT Stat;
+    DWORD dwError;
+    if (::ClearCommError(_hCommHandle, &dwError, &Stat) && dwError > 0) {
+        ::PurgeComm(_hCommHandle, PURGE_RXABORT | PURGE_RXCLEAR);    // 清空输入缓冲区(PURGE_RXCLEAR)
+        return 0;
+    }
+
+#if 0 
+    // 暂时保留:要视机器情况而定,有些响应慢缓冲区会暂时性无数据;
+    if (!Stat.cbInQue)
+        return 0; // 缓冲区无数据
+#endif
+    utils::_dprintf("缓冲区数据量:%ld", Stat.cbInQue);
+
+    unsigned long uReadLength = 0;
+    // dwBufferLength = dwBufferLength > Stat.cbInQue ? Stat.cbInQue : dwBufferLength;//会越界;
+    if (!::ReadFile(_hCommHandle, Buffer, dwBufferLength, &uReadLength, &_ReadOverlapped))  { // 可能Buffer不够大,装不完;
+        WaitForSingleObject(_ReadOverlapped.hEvent, dwWaitTime); // 等待异步操作完成;
+        if (::GetLastError() == ERROR_IO_PENDING) {
+            while (!::GetOverlappedResult(_hCommHandle, &_ReadOverlapped, &uReadLength, false)) {
+                dwError = ::GetLastError();
+                if ( dwError == ERROR_IO_PENDING ) {
+                    Sleep(50);
+                    utils::_dprintf("读等待:%ld", dwError);
+                } else if ( dwError == ERROR_SUCCESS || dwError == ERROR_IO_INCOMPLETE ) {
+                    utils::_dprintf("读完成:%ld,%ld,%ld", dwError, uReadLength,_ReadOverlapped.InternalHigh);
+                    // 奇葩:_ReadOverlapped并不能马上出长度,在超时后才会刷新出来(不知是否与Win平台有关);
+                    if ( _ReadOverlapped.InternalHigh )
+                        uReadLength = _ReadOverlapped.InternalHigh;
+                    else
+                        uReadLength = Stat.cbInQue;
+                    break;
+                } else {
+                    utils::_dprintf("读错误:%ld", dwError);
+                    uReadLength = 0;
+                    break;
+                }
+            }
+        }
+    }
+
+    return uReadLength;
+}
+
+char* CBaseSerial::ReadString(char *szBuffer, DWORD dwBufferLength, DWORD dwWaitTime /* = 20 */)
+{
+    unsigned long uReadLength = Read(szBuffer, dwBufferLength - 1, dwWaitTime);
+    szBuffer[uReadLength] = '\0';
+    return szBuffer;
+}
+
+DWORD CBaseSerial::Write(LPVOID Buffer, DWORD dwBufferLength)
+{
+    if (!IsOpen())
+        return 0;
+
+    DWORD dwError;
+    if (::ClearCommError(_hCommHandle, &dwError, NULL) && dwError > 0)
+        ::PurgeComm(_hCommHandle, PURGE_TXABORT | PURGE_TXCLEAR);    // 清空输出缓冲区(PURGE_TXCLEAR)
+    
+    unsigned long uWriteLength = 0;
+    if (!::WriteFile(_hCommHandle, Buffer, dwBufferLength, &uWriteLength, &_WriteOverlapped)) {
+        if (ERROR_IO_PENDING == GetLastError()) {
+            while (!GetOverlappedResult(_hCommHandle, &_WriteOverlapped, &uWriteLength, FALSE)) {
+                dwError = GetLastError();
+                if (ERROR_IO_PENDING == dwError) {
+                    utils::_dprintf("写等待");
+                    continue;
+                } else if (dwError == ERROR_SUCCESS || dwError == ERROR_IO_INCOMPLETE){
+                    uWriteLength = _WriteOverlapped.InternalHigh;
+                    utils::_dprintf("写完成:%ld", dwError);
+                    break;
+                } else {
+                    utils::_dprintf("写出错:%ld",dwError);
+                    uWriteLength = 0;
+                    ClearCommError(_hCommHandle, &dwError, NULL);
+                    break;
+                }
+            }
+        }
+    }
+
+    return uWriteLength;
+}
+
+DWORD CBaseSerial::Write(const TCHAR *szBuffer)
+{
+    assert(szBuffer);
+    return Write((void *)szBuffer, _tclen(szBuffer));
+}
+
+DWORD CBaseSerial::ReadSync(LPVOID Buffer, DWORD dwBufferLength)
+{
+    if (!IsOpen())
+        return 0;
+    
+    COMSTAT Stat;
+    DWORD dwError;
+
+    DWORD dwLastLen = 0;
+    ULONGLONG ulTick = GetTickCount();    
+    // 直到有数据为止,超时3秒;
+    while (true) {// cbInQue表示输入缓冲区的字节数; 
+        if (GetTickCount() - ulTick > 3000) {
+            utils::_dprintf("读出错: 超过3秒仍未读完");
+            break;
+        }
+
+        if ( ::ClearCommError(_hCommHandle, &dwError, &Stat) && dwError > 0 ) {
+            ::PurgeComm(_hCommHandle, PURGE_RXABORT | PURGE_RXCLEAR);    // 清空输入缓冲区(PURGE_RXCLEAR)
+            utils::_dprintf("读出错: ClearCommError出错");
+            break;
+        }
+
+        // 防止读一次没读完,再读一次;二次长度一样表示读完;
+        if (Stat.cbInQue != 0 && dwLastLen == Stat.cbInQue)
+            break;
+        dwLastLen = Stat.cbInQue;
+        Sleep(100);
+    }
+
+    if (Stat.cbInQue == 0) {
+        // 串口超时,无数据返回;
+        return 0;
+    }
+
+    if (dwBufferLength < Stat.cbInQue) {
+        utils::_dprintf("读出错: 缓冲数据过大 %ld > %ld", dwBufferLength, Stat.cbInQue);
+    }
+
+    DWORD uReadLength = 0;
+    if ( !::ReadFile(_hCommHandle, Buffer, dwBufferLength, &uReadLength, NULL) )
+    {
+        DWORD dwError = GetLastError();
+        utils::_dprintf("读出错:%ld", dwError);
+    }
+
+    return uReadLength;
+}
+
+DWORD CBaseSerial::WriteSync(LPVOID Buffer, DWORD dwBufferLength)
+{
+    if (!IsOpen())
+        return 0;
+    
+    DWORD dwError;
+    if (::ClearCommError(_hCommHandle, &dwError, NULL) && dwError > 0)
+        ::PurgeComm(_hCommHandle, PURGE_TXABORT | PURGE_TXCLEAR);    // 清空输出缓冲区(PURGE_TXCLEAR)
+    
+    unsigned long uWriteLength = 0;
+    if ( !::WriteFile(_hCommHandle, Buffer, dwBufferLength, &uWriteLength, NULL) )
+    {
+        DWORD dwError = GetLastError();
+        utils::_dprintf("写出错:%ld", dwError);
+    }
+
+    return uWriteLength;
+}
+
+DWORD CBaseSerial::Write(TCHAR *szBuffer, DWORD dwBufferLength, TCHAR *szFormat, ...)
+{
+    if (!IsOpen())
+        return 0;
+    
+    va_list va;
+    va_start(va, szFormat);
+#if _MSC_VER < 1500
+    _vsnprintf(szBuffer, dwBufferLength, szFormat, va);
+#elif _MSC_VER >=1500 // VC9.0以上版本;
+    //_vsntprintf(szBuffer, dwBufferLength, szFormat, va);
+    _vsntprintf_s(szBuffer, dwBufferLength, _TRUNCATE, szFormat, va);
+#endif
+    va_end(va);
+
+    return Write(szBuffer);
+}
+
+DWORD CBaseSerial::Write(TCHAR *szBuffer, TCHAR *szFormat, ...)
+{
+    if (!IsOpen()) 
+        return 0;
+    
+    va_list va;
+    va_start(va, szFormat);
+#if _MSC_VER < 1500       
+    vsprintf(szBuffer, szFormat, va);
+#elif _MSC_VER >=1500 // VC9.0以上版本;    
+    _vstprintf(szBuffer, szFormat, va);
+#endif
+    va_end(va);
+
+    return Write(szBuffer);
+}
+
+void CBaseSerial::Close()
+{
+    if (!IsOpen()) return;
+
+    PurgeComm(_hCommHandle, PURGE_TXABORT | PURGE_TXCLEAR);    // 清空输出缓冲区(PURGE_TXCLEAR)
+    ::CloseHandle(_hCommHandle);
+    _hCommHandle = INVALID_HANDLE_VALUE;
+}
+
+bool CBaseSerial::SetDTR(bool OnOrOff)
+{
+    return IsOpen() ? EscapeCommFunction(_hCommHandle, OnOrOff ? SETDTR : CLRDTR) : false;
+}
+
+bool CBaseSerial::SetRTS(bool OnOrOff)
+{
+    return IsOpen() ? EscapeCommFunction(_hCommHandle, OnOrOff ? SETRTS : CLRRTS) : false;
+}
+
+bool CBaseSerial::SetBreak(bool OnOrOff)
+{
+    return IsOpen() ? EscapeCommFunction(_hCommHandle, OnOrOff ? SETBREAK : CLRBREAK) : false;
+}
+
+void CBaseSerial::Init()
+{
+    memset(_szCommStr, 0, 20*sizeof(TCHAR));
+    memset(&_DCB, 0, sizeof(_DCB));
+    _DCB.DCBlength = sizeof(_DCB);
+    _hCommHandle = INVALID_HANDLE_VALUE;
+
+    memset(&_ReadOverlapped, 0, sizeof(_ReadOverlapped));
+    memset(&_WriteOverlapped, 0, sizeof(_WriteOverlapped));
+    _ReadOverlapped.hEvent = ::CreateEvent(NULL, true, false, NULL);
+    assert(_ReadOverlapped.hEvent != INVALID_HANDLE_VALUE);
+    _WriteOverlapped.hEvent = ::CreateEvent(NULL, true, false, NULL);
+    assert(_WriteOverlapped.hEvent != INVALID_HANDLE_VALUE);
+
+    _hNotifyWnd = NULL;
+    _dwNotifyNum = 0;
+    _dwMaskEvent = DEFAULT_COM_MASK_EVENT;
+
+    memset(&_WaitOverlapped, 0, sizeof(_WaitOverlapped));
+    _WaitOverlapped.hEvent = ::CreateEvent(NULL, true, false, NULL);
+    assert(_WaitOverlapped.hEvent != INVALID_HANDLE_VALUE);
+}
+
+void CBaseSerial::UnInit()
+{
+    if (_ReadOverlapped.hEvent != INVALID_HANDLE_VALUE)
+        CloseHandle(_ReadOverlapped.hEvent);
+    if (_WriteOverlapped.hEvent != INVALID_HANDLE_VALUE)
+        CloseHandle(_WriteOverlapped.hEvent);
+    if (_WaitOverlapped.hEvent != INVALID_HANDLE_VALUE)
+        CloseHandle(_WaitOverlapped.hEvent);
+}
+
+void CBaseSerial::BindCommPort(DWORD dwPort)
+{
+    assert(dwPort >= 1 && dwPort <= 1024);
+    TCHAR p[5] = {0};
+    _dwPort = dwPort;
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+    strcpy(_szCommStr, _T("\\\\.\\COM"));
+    ltoa(_dwPort, p, 10);
+    strcat(_szCommStr, p);
+#elif _MSC_VER >= 1500
+    _tcscpy_s(_szCommStr, _T("\\\\.\\COM"));
+    _ltot_s(_dwPort, p, 10);
+    _tcscat_s(_szCommStr, p);
+#endif
+}
+
+bool CBaseSerial::OpenCommPort()
+{
+    if (IsOpen())
+        Close();
+    _hCommHandle = ::CreateFile(_szCommStr, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | _dwIOMode, NULL);
+    return IsOpen();
+}
+
+bool CBaseSerial::SetupPort()
+{
+    if (!IsOpen())
+        return false;
+    // SetupComm设置输入输出缓冲区大小;
+    if (!::SetupComm(_hCommHandle, 8192, 8192))
+        return false;
+    if (!::GetCommTimeouts(_hCommHandle, &_CO))
+        return false;
+
+    _CO.ReadIntervalTimeout = 5;
+    _CO.ReadTotalTimeoutMultiplier = 10;
+    _CO.ReadTotalTimeoutConstant = 1500;
+    _CO.WriteTotalTimeoutMultiplier = 10;
+    _CO.WriteTotalTimeoutConstant = 1500;
+    if (!::SetCommTimeouts(_hCommHandle, &_CO))
+        return false;
+
+    // 清空输入输出缓冲区;
+    if (!::PurgeComm(_hCommHandle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR))
+        return false;
+
+    return true;
+}

+ 150 - 0
TCLCommand/TCLCommand/Serial.h

@@ -0,0 +1,150 @@
+#pragma once
+
+#pragma warning(disable : 4530)
+#pragma warning(disable : 4786)
+#pragma warning(disable : 4800)
+#pragma warning(disable:  4996)
+
+#include <assert.h>
+#include <stdio.h>
+#include <windows.h>
+
+//送到窗口的消息 WPARAM 端口号
+#define ON_COM_RECEIVE WM_USER + 618
+#define ON_COM_CTS WM_USER + 619 //LPARAM 1 valid
+#define ON_COM_DSR WM_USER + 621 //LPARAM 1 valid
+#define ON_COM_RING WM_USER + 623
+#define ON_COM_RLSD WM_USER + 624
+#define ON_COM_BREAK WM_USER + 625
+#define ON_COM_TXEMPTY WM_USER + 626
+#define ON_COM_ERROR WM_USER + 627 //LPARAM save Error ID
+#define DEFAULT_COM_MASK_EVENT EV_RXCHAR | EV_ERR | EV_CTS | EV_DSR | EV_BREAK | EV_TXEMPTY | EV_RING | EV_RLSD
+
+class CBaseSerial
+{
+public:
+    // 参数为IO方式 阻塞方式(0)/ 异步重叠方式(默认)
+    CBaseSerial(DWORD dwIOMode = FILE_FLAG_OVERLAPPED) : _dwIOMode(dwIOMode)
+    {
+        Init();
+    }
+    
+    virtual ~CBaseSerial()
+    {
+        Close();
+        UnInit();
+    }
+    
+public:
+    // 判断串口是否打开
+    inline bool IsOpen() { return _hCommHandle != INVALID_HANDLE_VALUE; }
+    // 判断串口是否打开
+    operator bool() { return _hCommHandle != INVALID_HANDLE_VALUE; }
+    // 获得串口句炳
+    inline HANDLE GetHandle() { return _hCommHandle; }
+    // 获得串口句炳
+    operator HANDLE() { return _hCommHandle; }
+    
+    // 获得串口参数 DCB
+    DCB *GetState();    
+    // 设置串口参数 DCB
+    bool SetState(DCB *pdcb = NULL);      
+    // 设置串口参数:波特率,停止位,等 支持设置字符串 "9600, 8, n, 1"
+    bool SetState(TCHAR *lpszSetStr = _T("baud=115200 parity=N data=8 stop=1"));
+    // 设置串口参数:波特率,停止位,等
+    bool SetState(DWORD dwBaudRate, DWORD dwByteSize = 8, DWORD dwParity = NOPARITY, DWORD dwStopBits = ONESTOPBIT);
+    
+    // 获得超时结构
+    LPCOMMTIMEOUTS GetTimeouts(void);    
+    // 设置超时
+    bool SetTimeouts(
+        DWORD ReadIntervalTimeout = 5, 
+        DWORD ReadTotalTimeoutMultiplier = 10, 
+        DWORD ReadTotalTimeoutConstant = 1500, 
+        DWORD WriteTotalTimeoutMultiplier = 10, 
+        DWORD WriteTotalTimeoutConstant = 1500);
+    bool SetTimeouts(LPCOMMTIMEOUTS lpCO);
+    // 设置串口的I/O缓冲区大小
+    bool SetBufferSize(DWORD dwInputSize, DWORD dwOutputSize);
+
+    // 关联消息的窗口句柄
+    inline void SetWnd(HWND hWnd)
+    {
+        assert(::IsWindow(hWnd));
+        _hNotifyWnd = hWnd;
+    }
+    
+    // 设定发送通知, 接受字符最小值
+    inline void SetNotifyNum(DWORD dwNum) { _dwNotifyNum = dwNum; }
+    
+    // 设置要监视的事件, 打开前设置有效
+    void SetMaskEvent(DWORD dwEvent = DEFAULT_COM_MASK_EVENT);
+    // 获得读缓冲区的字符数
+    int GetInputSize();
+    
+    // 打开串口 缺省 9600, 8, n, 1
+    bool Open(DWORD dwPort);
+    // 打开串口 缺省 baud_rate, 8, n, 1
+    bool Open(DWORD dwPort, DWORD dwBaudRate);    
+    // 打开串口, 使用类似"9600, 8, n, 1"的设置字符串设置串口
+    bool Open(DWORD dwPort, TCHAR *lpszSetStr = _T("baud=115200 parity=N data=8 stop=1") );
+    
+    // 读取串口 dwBufferLength个字符到 Buffer 返回实际读到的字符数 可读任意数据
+    DWORD Read(LPVOID Buffer, DWORD dwBufferLength, DWORD dwWaitTime = 100);    
+    // 读取串口 dwBufferLength - 1 个字符到 szBuffer 返回ANSI C 模式字符串指针 适合一般字符通讯
+    char *ReadString(char *szBuffer, DWORD dwBufferLength, DWORD dwWaitTime = 20);    
+    // 写串口 可写任意数据 "abcd" or "\x0\x1\x2"
+    DWORD Write(LPVOID Buffer, DWORD dwBufferLength);
+    // 写串口 写ANSI C 模式字符串指针
+    DWORD Write(const TCHAR *szBuffer);
+    // 读串口 同步应用
+    DWORD ReadSync(LPVOID Buffer, DWORD dwBufferLength);
+    // 写串口 同步应用
+    DWORD WriteSync(LPVOID Buffer, DWORD dwBufferLength);
+    // 写串口 szBuffer 可以输出格式字符串 包含缓冲区长度
+    DWORD Write(TCHAR *szBuffer, DWORD dwBufferLength, TCHAR *szFormat, ...);
+    // 写串口 szBuffer 可以输出格式字符串 不检查缓冲区长度 小心溢出
+    DWORD Write(TCHAR *szBuffer, TCHAR *szFormat, ...);
+    // 关闭串口 同时也关闭关联线程
+    virtual void Close();
+    // DTR 电平控制
+    bool SetDTR(bool OnOrOff);
+    // RTS 电平控制
+    bool SetRTS(bool OnOrOff);
+    // 设置信号状态为中断;
+    bool SetBreak(bool OnOrOff);
+    // 清除缓存;
+    void ClearCommBuffer() { 
+        ClearCommError(_hCommHandle, NULL, NULL);
+        ::PurgeComm(_hCommHandle, PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR); 
+    }
+
+protected:
+    volatile DWORD _dwPort;                             // 串口号
+    volatile HANDLE _hCommHandle;                       // 串口句柄
+    TCHAR _szCommStr[20];                               // 保存COM1类似的字符串
+    DCB _DCB;                                           // 波特率,停止位,等
+    COMMTIMEOUTS _CO;                                   // 超时结构
+    DWORD _dwIOMode;                                    // 0 同步 默认 FILE_FLAG_OVERLAPPED重叠I/O异步
+    OVERLAPPED _ReadOverlapped, _WriteOverlapped;       // 重叠I/O
+    volatile HWND _hNotifyWnd;                          // 通知窗口
+    volatile DWORD _dwNotifyNum;                        // 接受多少字节(>=_dwNotifyNum)发送通知消息
+    volatile DWORD _dwMaskEvent;                        // 监视的事件
+    OVERLAPPED _WaitOverlapped;                         // WaitCommEvent use
+
+    // 初始化
+    void Init();
+    // 析构
+    void UnInit();
+    // 绑定串口
+    void BindCommPort(DWORD dwPort);
+    // 打开串口
+    virtual bool OpenCommPort();
+    // 设置串口
+    virtual bool SetupPort();
+
+private:
+    CBaseSerial(const CBaseSerial &);
+    CBaseSerial &operator=(const CBaseSerial &);
+};
+

+ 1281 - 0
TCLCommand/TCLCommand/TCLCommand.cpp

@@ -0,0 +1,1281 @@
+// TCLCommand.cpp : 定义 DLL 应用程序的导出函数。
+//
+
+#include "stdafx.h"
+#include "TCLCommand.h"
+#include "Command.h"
+#include "resource.h"
+#ifdef __MAKE_PYD__
+#include "Python.h"
+#endif
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// 唯一的应用程序对象
+
+CWinApp theApp;
+TCLCommand g_TCLCommand;
+
+// 宏函数;
+#define OPEN_CHECK if (!g_TCLCommand.IsOpen()) return false
+
+#define GET_CMDS(cmdName)  CommandParam cmdpara;\
+if ( !g_TCLCommand.GetCommandParams(cmdName, cmdpara) )return false;\
+g_TCLCommand.PackingCommand(cmdpara);
+
+#define SET_CMDS(cmdName, data, len) CommandParam cmdpara;\
+if ( !g_TCLCommand.GetCommandParams(cmdName, cmdpara) )return false;\
+g_TCLCommand.PackingCommand(cmdpara, data, len);
+
+using namespace std;
+
+#ifdef __CONSOLE__
+int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
+{
+	int nRetCode = 0;
+
+	// 初始化 MFC 并在失败时显示错误
+	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
+	{
+		// TODO: 更改错误代码以符合您的需要
+		_tprintf(_T("错误: MFC 初始化失败\n"));
+		nRetCode = 1;
+	}
+	else
+	{
+		// TODO: 在此处为应用程序的行为编写代码。
+        if ( Open(21, 115200, 8, 0, 1) )
+        {
+            EnterFactory();
+           
+            int pid;
+            GetProjectId(pid);
+
+            std::string value;
+            GetSoftVersion(value);
+            GetDeviceId(value);
+            GetClientType(value);
+            GetMAC(value);
+            GetHDCPKey(value);
+
+            GetHDCPKey22(value);
+            GetWidi(value);
+            GetNetflixESN(value);
+            GetWidevine(value);
+            GetCiKey(value);
+            GetOSDLanguage(value);
+            GetShopLanguage(value);
+            GetChannel(value);
+
+            LeaveFactory();
+        }
+	}
+
+	return nRetCode;
+}
+#endif
+
+#ifdef EXPORTS_CLASS
+CTCLCommand::CTCLCommand()
+{
+
+}
+
+bool CTCLCommand::Open(int nPort, DWORD dwBaudrate, BYTE ByteSize, BYTE Parity, BYTE StopBits)
+{
+    TCHAR szSet[MAX_PATH] = {0};
+    _stprintf_s(szSet, _T("baud=%ld parity=%s data=%d stop=%d"), dwBaudrate, Parity == 0 ? "N" : "O", ByteSize, StopBits);
+    g_TCLCommand.SetInternalCMDParams(BIN_CMD);
+    return g_TCLCommand.Open(nPort, szSet);
+}
+
+void CTCLCommand::Close()
+{
+    g_TCLCommand.Close();
+}
+
+bool CTCLCommand::IsOpen()
+{
+    return g_TCLCommand.IsOpen();
+}
+
+void CTCLCommand::SetExternalCMDParams(LPCTSTR lpFileName)
+{
+    g_TCLCommand.SetExternalCMDParams(lpFileName);
+}
+
+bool CTCLCommand::GetCommandParams(std::string name, CommandParam& cmdPara)
+{
+    return g_TCLCommand.GetCommandParams(name, cmdPara);
+}
+
+void CTCLCommand::PackingCommand(CommandParam& cmdPara, std::string data, const int& dataLen)
+{
+    g_TCLCommand.PackingCommand(cmdPara, data, dataLen);
+}
+
+bool CTCLCommand::SendCommand(CommandParam& cmdPara)
+{
+    return g_TCLCommand.SendCommand(cmdPara);
+}
+
+#else
+bool Open(int nPort, DWORD dwBaudrate, BYTE ByteSize, BYTE Parity, BYTE StopBits)
+{
+    TCHAR szSet[MAX_PATH] = {0};
+    _stprintf_s(szSet, _T("baud=%ld parity=%s data=%d stop=%d"), dwBaudrate, Parity == 0 ? "N" : "O", ByteSize, StopBits);
+    g_TCLCommand.SetInternalCMDParams(BIN_CMD);
+    return g_TCLCommand.Open(nPort, szSet);
+}
+
+void Close()
+{
+    g_TCLCommand.Close();
+}
+
+bool IsOpen()
+{
+    return g_TCLCommand.IsOpen();
+}
+
+void SetExternalCMDParams(LPCTSTR lpFileName)
+{
+    g_TCLCommand.SetExternalCMDParams(lpFileName);
+}
+
+bool EnterFactory()
+{
+    OPEN_CHECK;
+    GET_CMDS(__FUNCTION__);
+    return g_TCLCommand.SendCommand(cmdpara);
+}
+
+bool LeaveFactory()
+{
+    OPEN_CHECK;
+    GET_CMDS(__FUNCTION__);
+    return g_TCLCommand.SendCommand(cmdpara);
+}
+
+bool GetProjectId(int& pid)
+{
+    OPEN_CHECK;
+    GET_CMDS(__FUNCTION__);
+    if (g_TCLCommand.SendCommand(cmdpara))
+    {
+        if (cmdpara._rtnData.size() == 2)
+            pid = (byte)cmdpara._rtnData[0] << 8 | (byte)cmdpara._rtnData[1];
+        else
+            pid = (byte)cmdpara._rtnData[0];
+
+        return true;
+    }
+
+    return false;
+}
+
+bool GetSoftVersion(std::string& strValue)
+{
+    OPEN_CHECK;
+    GET_CMDS(__FUNCTION__);
+    if (g_TCLCommand.SendCommand(cmdpara))
+    {
+        strValue = cmdpara._rtnData;
+        return true;
+    }
+
+    return false;
+}
+
+bool GetDeviceId(std::string& strValue)
+{
+    OPEN_CHECK;
+    GET_CMDS(__FUNCTION__);
+    if (g_TCLCommand.SendCommand(cmdpara))
+    {
+        strValue = cmdpara._rtnData;
+        return true;
+    }
+
+    return false;
+}
+
+bool GetClientType(std::string& strValue)
+{
+    OPEN_CHECK;
+    GET_CMDS(__FUNCTION__);
+    if (g_TCLCommand.SendCommand(cmdpara))
+    {
+        strValue = cmdpara._rtnData;
+        return true;
+    }
+
+    return false;
+}
+
+bool GetMAC(std::string& strValue)
+{
+    OPEN_CHECK;
+    GET_CMDS(__FUNCTION__);
+    if (g_TCLCommand.SendCommand(cmdpara))
+    {
+        strValue = cmdpara._rtnData;
+        return true;
+    }
+
+    return false;
+}
+
+bool GetHDCPKey(std::string& strValue)
+{
+    OPEN_CHECK;
+    GET_CMDS(__FUNCTION__);
+    if (g_TCLCommand.SendCommand(cmdpara))
+    {
+        strValue = cmdpara._rtnData;
+        return true;
+    }
+
+    return false;
+}
+
+bool GetHDCPKey22(std::string& strValue)
+{
+    OPEN_CHECK;
+    GET_CMDS(__FUNCTION__);
+    if (g_TCLCommand.SendCommand(cmdpara))
+    {
+        strValue = cmdpara._rtnData;
+        return true;
+    }
+
+    return false;
+}
+
+bool GetWidi(std::string& strValue)
+{
+    OPEN_CHECK;
+    GET_CMDS(__FUNCTION__);
+    if (g_TCLCommand.SendCommand(cmdpara))
+    {
+        strValue = cmdpara._rtnData;
+        return true;
+    }
+
+    return false;
+}
+
+bool GetNetflixESN(std::string& strValue)
+{
+    OPEN_CHECK;
+    GET_CMDS(__FUNCTION__);
+    if (g_TCLCommand.SendCommand(cmdpara))
+    {
+        strValue = cmdpara._rtnData;
+        return true;
+    }
+
+    return false;
+}
+
+bool GetWidevine(std::string& strValue)
+{
+    OPEN_CHECK;
+    GET_CMDS(__FUNCTION__);
+    if (g_TCLCommand.SendCommand(cmdpara))
+    {
+        strValue = cmdpara._rtnData;
+        return true;
+    }
+
+    return false;
+}
+
+bool GetCiKey(std::string& strValue)
+{
+    OPEN_CHECK;
+    GET_CMDS(__FUNCTION__);
+    if (g_TCLCommand.SendCommand(cmdpara))
+    {
+        strValue = cmdpara._rtnData;
+        return true;
+    }
+
+    return false;
+}
+
+bool GetOSDLanguage(std::string& strValue)
+{
+    OPEN_CHECK;
+    GET_CMDS(__FUNCTION__);
+    if (g_TCLCommand.SendCommand(cmdpara))
+    {
+        strValue = cmdpara._rtnData;
+        return true;
+    }
+
+    return false;
+}
+
+bool GetShopLanguage(std::string& strValue)
+{
+    OPEN_CHECK;
+    GET_CMDS(__FUNCTION__);
+    if (g_TCLCommand.SendCommand(cmdpara))
+    {
+        strValue = cmdpara._rtnData;
+        return true;
+    }
+
+    return false;
+}
+
+bool GetChannel(std::string& strValue)
+{
+    OPEN_CHECK;
+    GET_CMDS(__FUNCTION__);
+    if (g_TCLCommand.SendCommand(cmdpara))
+    {
+        strValue = cmdpara._rtnData;
+        return true;
+    }
+
+    return false;
+}
+
+bool SetProjectId(const byte* pBuffer, const int& nLen)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetDeviceId(LPCTSTR lpDeviceId)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetDeviceId(const byte* pBuffer, const int& nLen)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetMAC(LPCTSTR lpMac)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetMAC(const byte* pBuffer, const int& nLen)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetHDCPKey(LPCTSTR lpHDCP, bool bHasSpace)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetHDCPKey(const byte* pBuffer, const int& nLen)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetHDCPKey22(LPCTSTR lpHDCP22, bool bHasSpace)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetHDCPKey22(const byte* pBuffer, const int& nLen)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetNetflixESN(LPCTSTR lpESN, bool bHasSpace)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetNetflixESN(const byte* pBuffer, const int& nLen)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetWidi(LPCTSTR lpWidi, bool bHasSpace)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetWidi(const byte* pBuffer, const int& nLen)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetWidevine(LPCTSTR lpWidevine, bool bHasSpace)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetWidevine(const byte* pBuffer, const int& nLen)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetCiKey(LPCTSTR lpCiKey, bool bHasSpace)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetCiKey(const byte* pBuffer, const int& nLen)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetOSDLanguage(LPCTSTR lan, bool bHasSpace)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetOSDLanguage(const byte* pBuffer, const int& nLen)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetShopLanguage(LPCTSTR lan, bool bHasSpace)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetShopLanguage(const byte* pBuffer, const int& nLen)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetChannel(LPCTSTR channel, bool bHasSpace)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetChannel(const byte* pBuffer, const int& nLen)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetWBNormal(LPCTSTR data)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetWBNormal(const byte* pBuffer, const int& nLen)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetWBCool(LPCTSTR data)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetWBCool(const byte* pBuffer, const int& nLen)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetWBWarm(LPCTSTR data)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetWBWarm(const byte* pBuffer, const int& nLen)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool CheckDeviceId()
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool CheckMAC()
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool CheckHDCP()
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool CheckHDCP22()
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool CheckNetflixESN()
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool CheckWidi()
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool CheckWidevine()
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool CheckCikey()
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool StarWarmUpMode()
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool StopWarmUpMode()
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetProjectId(int pid)
+{
+    OPEN_CHECK;
+    return false;
+}
+
+bool SetProjectId(LPCTSTR lpPid)
+{
+    OPEN_CHECK;
+    return false;
+}
+#endif
+
+#ifdef __MAKE_PYD__
+static PyObject* Open(PyObject* self, PyObject* args)
+{
+    int nPort;
+    int Baudrate;
+    int ByteSize, Parity, StopBits;
+    if (!PyArg_ParseTuple(args, "iiiii", &nPort, &Baudrate, &ByteSize, &Parity, &StopBits ))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.OpenComm(nPort, Baudrate));
+}
+
+static PyObject* Close(PyObject* self, PyObject* args)
+{
+    g_objSiacp.CloseComm();
+    return Py_None;
+}
+
+static PyObject* IsOpen(PyObject* self, PyObject* args)
+{
+    return Py_BuildValue("b", (bool)g_objSiacp.IsOpen());
+}
+
+static PyObject* EnterFactory(PyObject* self, PyObject* args)
+{
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_EnterFactory());
+}
+
+static PyObject* LeaveFactory(PyObject* self, PyObject* args)
+{
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_LeaveFactory());
+}
+
+//////////////////////////////////////////////////////////////////////////
+// 读取;
+static PyObject* GetProjectId(PyObject* self, PyObject* args)
+{
+    int pid = -1;
+    g_objSiacp.SCBC_GetProjectId(pid);
+    // 获取失败返回-1;
+    return Py_BuildValue("i", pid);
+}
+
+static PyObject* GetSoftVersion(PyObject* self, PyObject* args)
+{
+    g_strData.clear();
+    g_objSiacp.SCBC_GetSoftVersion(g_strData);
+    // 获取失败返回"";
+    return Py_BuildValue("s", g_strData.c_str());
+}
+
+static PyObject* GetDeviceId(PyObject* self, PyObject* args)
+{
+    g_strData.clear();
+    g_objSiacp.SCBC_GetDeviceId(g_strData);
+    // 获取失败返回"";
+    return Py_BuildValue("s", g_strData.c_str());
+}
+
+static PyObject* GetClientType(PyObject* self, PyObject* args)
+{
+    g_strData.clear();
+    g_objSiacp.SCBC_GetClientType(g_strData);
+    // 获取失败返回"";
+    return Py_BuildValue("s", g_strData.c_str());
+}
+
+static PyObject* GetMAC(PyObject* self, PyObject* args)
+{
+    g_strData.clear();
+    g_objSiacp.SCBC_GetMAC(g_strData);
+    // 获取失败返回"";
+    return Py_BuildValue("s", g_strData.c_str());
+}
+
+static PyObject* GetHDCPKey(PyObject* self, PyObject* args)
+{
+    g_strData.clear();
+    g_objSiacp.SCBC_GetHDCPKey(g_strData);
+    // 获取失败返回"";
+    return Py_BuildValue("s", g_strData.c_str());
+}
+
+static PyObject* GetHDCPKey22(PyObject* self, PyObject* args)
+{
+    g_strData.clear();
+    g_objSiacp.SCBC_GetHDCPKey22(g_strData);
+    // 获取失败返回"";
+    return Py_BuildValue("s", g_strData.c_str());
+}
+
+static PyObject* GetWidi(PyObject* self, PyObject* args)
+{
+    g_strData.clear();
+    g_objSiacp.SCBC_GetWidi(g_strData);
+    // 获取失败返回"";
+    return Py_BuildValue("s", g_strData.c_str());
+}
+
+static PyObject* GetNetflixESN(PyObject* self, PyObject* args)
+{
+    g_strData.clear();
+    g_objSiacp.SCBC_GetNetflixESN(g_strData);
+    // 获取失败返回"";
+    return Py_BuildValue("s", g_strData.c_str());
+}
+
+static PyObject* GetWidevine(PyObject* self, PyObject* args)
+{
+    g_strData.clear();
+    g_objSiacp.SCBC_GetWidevine(g_strData);
+    // 获取失败返回"";
+    return Py_BuildValue("s", g_strData.c_str());
+}
+
+static PyObject* GetCiKey(PyObject* self, PyObject* args)
+{
+    g_strData.clear();
+    g_objSiacp.SCBC_GetCiKey(g_strData);
+    // 获取失败返回"";
+    return Py_BuildValue("s", g_strData.c_str());
+}
+
+static PyObject* GetOSDLanguage(PyObject* self, PyObject* args)
+{
+    g_strData.clear();
+    g_objSiacp.SCBC_GetOSDLanguage(g_strData);
+    // 获取失败返回"";
+    return Py_BuildValue("s", g_strData.c_str());
+}
+
+static PyObject* GetShopLanguage(PyObject* self, PyObject* args)
+{
+    g_strData.clear();
+    g_objSiacp.SCBC_GetShopLanguage(g_strData);
+    // 获取失败返回"";
+    return Py_BuildValue("s", g_strData.c_str());
+}
+
+static PyObject* GetChannel(PyObject* self, PyObject* args)
+{
+    g_strData.clear();
+    g_objSiacp.SCBC_GetChannel(g_strData);
+    // 获取失败返回"";
+    return Py_BuildValue("s", g_strData.c_str());
+}
+
+//////////////////////////////////////////////////////////////////////////
+// 设置;
+static PyObject* SetProjectId(PyObject* self, PyObject* args)
+{
+    int pid = 0;
+    if (!PyArg_ParseTuple(args, "i", &pid))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetProjectId(pid));
+}
+
+static PyObject* SetDeviceId(PyObject* self, PyObject* args)
+{
+    const char* pszdata= 0;
+    if (!PyArg_ParseTuple(args, "s", &pszdata))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetDeviceId(pszdata));
+}
+
+static PyObject* SetDeviceIdBF(PyObject* self, PyObject* args)
+{
+    const char* pszfile = 0;
+    if (!PyArg_ParseTuple(args, "s", &pszfile))
+        return NULL;
+
+    // 打开文件;
+    std::string data;
+    if ( ReadKeyFile(pszfile, data) )
+    {
+        return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetDeviceId((BYTE*)data.c_str(), data.size()));
+    }
+
+    return Py_BuildValue("b", false);
+}
+
+static PyObject* SetMAC(PyObject* self, PyObject* args)
+{
+    const char* pszdata = 0;
+    if (!PyArg_ParseTuple(args, "s", &pszdata))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetMAC(pszdata));
+}
+
+static PyObject* SetMACBF(PyObject* self, PyObject* args)
+{
+    const char* pszfile = 0;
+    if (!PyArg_ParseTuple(args, "s", &pszfile))
+        return NULL;
+
+    // 打开文件;
+    std::string data;
+    if ( ReadKeyFile(pszfile, data) )
+    {
+        return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetMAC((BYTE*)data.c_str(), data.size()));
+    }
+
+    return Py_BuildValue("b", false);
+}
+
+static PyObject* SetHDCPKey(PyObject* self, PyObject* args)
+{
+    BOOL bHasSpace; 
+    const char* pszdata = 0;
+    if (!PyArg_ParseTuple(args, "sb", &pszdata, &bHasSpace))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetHDCPKey(pszdata, bHasSpace));
+}
+
+static PyObject* SetHDCPKeyBF(PyObject* self, PyObject* args)
+{
+    const char* pszfile = 0;
+    if (!PyArg_ParseTuple(args, "s", &pszfile))
+        return NULL;
+
+    // 打开文件;
+    std::string data;
+    if ( ReadKeyFile(pszfile, data) )
+    {
+        return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetHDCPKey((BYTE*)data.c_str(), data.size()));
+    }
+
+    return Py_BuildValue("b", false);
+}
+
+static PyObject* SetHDCPKey22(PyObject* self, PyObject* args)
+{
+    BOOL bHasSpace; 
+    const char* pszdata = 0;
+    if (!PyArg_ParseTuple(args, "sb", &pszdata, &bHasSpace))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetHDCPKey22(pszdata, bHasSpace));
+}
+
+static PyObject* SetHDCPKey22BF(PyObject* self, PyObject* args)
+{
+    const char* pszfile = 0;
+    if (!PyArg_ParseTuple(args, "s", &pszfile))
+        return NULL;
+
+    // 打开文件;
+    std::string data;
+    if ( ReadKeyFile(pszfile, data) )
+    {
+        return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetHDCPKey22((BYTE*)data.c_str(), data.size()));
+    }
+
+    return Py_BuildValue("b", false);
+}
+
+static PyObject* SetNetflixESN(PyObject* self, PyObject* args)
+{
+    BOOL bHasSpace; 
+    const char* pszdata = 0;
+    if (!PyArg_ParseTuple(args, "sb", &pszdata, &bHasSpace))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetNetflixESN(pszdata, bHasSpace));
+}
+
+static PyObject* SetNetflixESNBF(PyObject* self, PyObject* args)
+{
+    const char* pszfile = 0;
+    if (!PyArg_ParseTuple(args, "s", &pszfile))
+        return NULL;
+
+    // 打开文件;
+    std::string data;
+    if ( ReadKeyFile(pszfile, data) )
+    {
+        return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetNetflixESN((BYTE*)data.c_str(), data.size()));
+    }
+
+    return Py_BuildValue("b", false);
+}
+
+static PyObject* SetWidi(PyObject* self, PyObject* args)
+{
+    BOOL bHasSpace; 
+    const char* pszdata = 0;
+    if (!PyArg_ParseTuple(args, "sb", &pszdata, &bHasSpace))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetWidi(pszdata, bHasSpace));
+}
+
+static PyObject* SetWidiBF(PyObject* self, PyObject* args)
+{
+    const char* pszfile = 0;
+    if (!PyArg_ParseTuple(args, "s", &pszfile))
+        return NULL;
+
+    // 打开文件;
+    std::string data;
+    if ( ReadKeyFile(pszfile, data) )
+    {
+        return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetWidi((BYTE*)data.c_str(), data.size()));
+    }
+
+    return Py_BuildValue("b", false);
+}
+
+static PyObject* SetWidevine(PyObject* self, PyObject* args)
+{
+    BOOL bHasSpace; 
+    const char* pszdata = 0;
+    if (!PyArg_ParseTuple(args, "sb", &pszdata, &bHasSpace))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetWidevine(pszdata, bHasSpace));
+}
+
+static PyObject* SetWidevineBF(PyObject* self, PyObject* args)
+{
+    const char* pszfile = 0;
+    if (!PyArg_ParseTuple(args, "s", &pszfile))
+        return NULL;
+
+    // 打开文件;
+    std::string data;
+    if ( ReadKeyFile(pszfile, data) )
+    {
+        return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetWidevine((BYTE*)data.c_str(), data.size()));
+    }
+
+    return Py_BuildValue("b", false);
+}
+
+static PyObject* SetCiKey(PyObject* self, PyObject* args)
+{
+    BOOL bHasSpace; 
+    const char* pszdata = 0;
+    if (!PyArg_ParseTuple(args, "sb", &pszdata, &bHasSpace))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetCiKey(pszdata, bHasSpace));
+}
+
+static PyObject* SetCiKeyBF(PyObject* self, PyObject* args)
+{
+    const char* pszfile = 0;
+    if (!PyArg_ParseTuple(args, "s", &pszfile))
+        return NULL;
+
+    // 打开文件;
+    std::string data;
+    if ( ReadKeyFile(pszfile, data) )
+    {
+        return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetCiKey((BYTE*)data.c_str(), data.size()));
+    }
+
+    return Py_BuildValue("b", false);
+}
+
+static PyObject* SetOSDLanguage(PyObject* self, PyObject* args)
+{
+    BOOL bHasSpace; 
+    const char* pszdata = 0;
+    if (!PyArg_ParseTuple(args, "sb", &pszdata, &bHasSpace))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetOSDLanguage(pszdata, bHasSpace));
+}
+
+static PyObject* SetShopLanguage(PyObject* self, PyObject* args)
+{
+    BOOL bHasSpace; 
+    const char* pszdata = 0;
+    if (!PyArg_ParseTuple(args, "sb", &pszdata, &bHasSpace))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetShopLanguage(pszdata, bHasSpace));
+}
+
+static PyObject* SetChannel(PyObject* self, PyObject* args)
+{
+    int value = 0;
+    if (!PyArg_ParseTuple(args, "i", &value))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetChannel(value));
+}
+
+static PyObject* SetWBNormal(PyObject* self, PyObject* args)
+{
+    const char* pszdata = 0;
+    if (!PyArg_ParseTuple(args, "s", &pszdata))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetWBNormal(pszdata));
+}
+
+static PyObject* SetWBCool(PyObject* self, PyObject* args)
+{
+    const char* pszdata = 0;
+    if (!PyArg_ParseTuple(args, "s", &pszdata))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetWBCool(pszdata));
+}
+
+static PyObject* SetWBWarm(PyObject* self, PyObject* args)
+{
+    const char* pszdata = 0;
+    if (!PyArg_ParseTuple(args, "s", &pszdata))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetWBWarm(pszdata));
+}
+//////////////////////////////////////////////////////////////////////////
+// 校验;
+static PyObject* CheckDeviceId(PyObject* self, PyObject* args)
+{
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_CheckDeviceId());
+}
+
+static PyObject* CheckMAC(PyObject* self, PyObject* args)
+{
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_CheckMAC());
+}
+
+static PyObject* CheckHDCP(PyObject* self, PyObject* args)
+{
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_CheckHDCP());
+}
+
+static PyObject* CheckHDCP22(PyObject* self, PyObject* args)
+{
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_CheckHDCP22());
+}
+
+static PyObject* CheckNetflixESN(PyObject* self, PyObject* args)
+{
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_CheckNetflixESN());
+}
+
+static PyObject* CheckWidi(PyObject* self, PyObject* args)
+{
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_CheckWidi());
+}
+
+static PyObject* CheckWidevine(PyObject* self, PyObject* args)
+{
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_CheckWidevine());
+}
+
+static PyObject* CheckCikey(PyObject* self, PyObject* args)
+{
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_CheckCikey());
+}
+
+static PyObject* StarWarmUpMode(PyObject* self, PyObject* args)
+{
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_StarWarmUpMode());
+}
+
+static PyObject* StopWarmUpMode(PyObject* self, PyObject* args)
+{
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_StopWarmUpMode());
+}
+
+//
+static PyObject* ShowFactoryMenu(PyObject* self, PyObject* args)
+{
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_ShowFactoryMenu());
+}
+
+static PyObject* HideFactoryMenu(PyObject* self, PyObject* args)
+{
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_HideFactoryMenu());
+}
+
+static PyObject* ShowFactoryInformation(PyObject* self, PyObject* args)
+{
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_ShowFactoryInformation());
+}
+
+static PyObject* HideFactoryInformation(PyObject* self, PyObject* args)
+{
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_HideFactoryInformation());
+}
+
+static PyObject* EnterAgingModel(PyObject* self, PyObject* args)
+{
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_EnterAgingModel());
+}
+
+static PyObject* LeaveAgingModel(PyObject* self, PyObject* args)
+{
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_LeaveAgingModel());
+}
+
+static PyObject* ReadAgingTime(PyObject* self, PyObject* args)
+{
+    int min = 0;
+    if ( !g_objSiacp.SCBC_ReadAgingTime(min) )
+        return Py_BuildValue("i", -1);
+    return Py_BuildValue("i", min);
+}
+
+static PyObject* SetRedGainRegister(PyObject* self, PyObject* args)
+{
+    int value = 0;
+    if (!PyArg_ParseTuple(args, "i", &value))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetRedGainRegister(value));
+}
+
+static PyObject* SetGreenGainRegister(PyObject* self, PyObject* args)
+{
+    int value = 0;
+    if (!PyArg_ParseTuple(args, "i", &value))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetGreenGainRegister(value));
+}
+
+static PyObject* SetBlueGainRegister(PyObject* self, PyObject* args)
+{
+    int value = 0;
+    if (!PyArg_ParseTuple(args, "i", &value))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetBlueGainRegister(value));
+}
+
+static PyObject* SetRedOffsetRegister(PyObject* self, PyObject* args)
+{
+    int value = 0;
+    if (!PyArg_ParseTuple(args, "i", &value))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetRedOffsetRegister(value));
+}
+
+static PyObject* SetGreenOffsetRegister(PyObject* self, PyObject* args)
+{
+    int value = 0;
+    if (!PyArg_ParseTuple(args, "i", &value))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetGreenOffsetRegister(value));
+}
+
+static PyObject* SetBlueOffsetRegister(PyObject* self, PyObject* args)
+{
+    int value = 0;
+    if (!PyArg_ParseTuple(args, "i", &value))
+        return NULL;
+
+    return Py_BuildValue("b", (bool)g_objSiacp.SCBC_SetBlueOffsetRegister(value));
+}
+
+static PyObject* HTTPLogin(PyObject* self, PyObject* args)
+{
+    int rememberMe = 0;
+    const char* pszhost = NULL;
+    const char* pszUserName = NULL;
+    const char* pszPassword = NULL;
+
+    if (!PyArg_ParseTuple(args, "sssb", &pszhost, &pszUserName, &pszPassword, &rememberMe))
+        return NULL;
+
+    HTTP_Login(pszhost, pszUserName, pszPassword, rememberMe); 
+
+    return Py_BuildValue("s", g_httpData.c_str());
+}
+
+static PyObject* HTTPGetUserId(PyObject* self, PyObject* args)
+{
+    const char* pszhost = NULL;
+    const char* pszToken = NULL;
+    const char* pszClientType = NULL;
+    const char* pszDeviceId = NULL;
+    const char* pszMAC = NULL;
+    if (!PyArg_ParseTuple(args, "sssss", &pszhost, &pszToken, &pszClientType, &pszDeviceId, &pszMAC))
+        return NULL;
+
+    int userId = HTTP_GetUserId(pszhost, pszToken, pszClientType, pszDeviceId, pszMAC); 
+
+    return Py_BuildValue("i", userId);
+}
+
+
+
+// 描述方法,暴露给python的函数;
+static PyMethodDef ScbcCopyKey_Methods[] = {
+    {"Open",Open,METH_VARARGS,"打开串口"},
+    {"Close", Close, METH_VARARGS, "关闭串口"},
+    {"IsOpen", IsOpen, METH_VARARGS, "串口是否打开"},
+    {"EnterFactory", EnterFactory, METH_VARARGS, "进入工厂模式"},
+    {"LeaveFactory", LeaveFactory, METH_VARARGS, "离开工厂模式"},
+    //////////////////////////////////////////////////////////////////////////
+    // 读取;
+    {"GetProjectId", GetProjectId, METH_VARARGS, "获取pid"},
+    {"GetSoftVersion", GetSoftVersion, METH_VARARGS, "获取版本号"},
+    {"GetDeviceId", GetDeviceId, METH_VARARGS, "获取DeviceID"},
+    {"GetClientType", GetClientType, METH_VARARGS, "获取ClientType"},
+    {"GetMAC", GetMAC, METH_VARARGS, "获取MAC"},
+    {"GetHDCPKey", GetHDCPKey, METH_VARARGS, "获取HDCP"},
+    {"GetHDCPKey22", GetHDCPKey22, METH_VARARGS, "获取HDCP22"},
+    {"GetWidi", GetWidi, METH_VARARGS, "获取WIDI"},
+    {"GetNetflixESN", GetNetflixESN, METH_VARARGS, "获取ESN"},
+    {"GetWidevine", GetWidevine, METH_VARARGS, "获取WIDEVINE"},
+    {"GetCiKey", GetCiKey, METH_VARARGS, "获取CIKEY"},
+    {"GetOSDLanguage", GetOSDLanguage, METH_VARARGS, "获取OSDLAN"},
+    {"GetShopLanguage", GetShopLanguage, METH_VARARGS, "获取SHOPLAN"},
+    {"GetChannel", GetChannel, METH_VARARGS, "获取频道号"},
+    //////////////////////////////////////////////////////////////////////////
+    // 设置;
+    {"SetProjectId", SetProjectId, METH_VARARGS, "设置pid"},
+    {"SetDeviceId", SetDeviceId, METH_VARARGS, "设置DeviceId"},
+    {"SetDeviceIdBF", SetDeviceIdBF, METH_VARARGS, "设置DeviceId"},
+    {"SetMAC", SetMAC, METH_VARARGS, "设置MAC"},
+    {"SetMACBF", SetMACBF, METH_VARARGS, "设置MAC"},
+    {"SetHDCPKey", SetHDCPKey, METH_VARARGS, "设置HDCP"},
+    {"SetHDCPKeyBF", SetHDCPKeyBF, METH_VARARGS, "设置HDCP"},
+    {"SetHDCPKey22", SetHDCPKey22, METH_VARARGS, "设置HDCP22"},
+    {"SetHDCPKey22BF", SetHDCPKey22BF, METH_VARARGS, "设置HDCP22"},
+    {"SetWidi", SetWidi, METH_VARARGS, "设置WIDI"},
+    {"SetWidiBF", SetWidiBF, METH_VARARGS, "设置WIDI"},
+    {"SetNetflixESN", SetNetflixESN, METH_VARARGS, "设置ESN"},
+    {"SetNetflixESNBF", SetNetflixESNBF, METH_VARARGS, "设置ESN"},
+    {"SetWidevine", SetWidevine, METH_VARARGS, "设置WIDEVINE"},
+    {"SetWidevineBF", SetWidevineBF, METH_VARARGS, "设置WIDEVINE"},
+    {"SetCiKey", SetCiKey, METH_VARARGS, "设置CIKEY"},
+    {"SetCiKeyBF", SetCiKeyBF, METH_VARARGS, "设置CIKEY"},
+    {"SetOSDLanguage", SetOSDLanguage, METH_VARARGS, "设置OSDLAN"},
+    {"SetShopLanguage", SetShopLanguage, METH_VARARGS, "设置SHOPLAN"},
+    {"SetChannel", SetChannel, METH_VARARGS, "设置频道号"},
+
+    {"SetWBNormal", SetWBNormal, METH_VARARGS, "设置OSDLAN"},
+    {"SetWBCool", SetWBCool, METH_VARARGS, "设置SHOPLAN"},
+    {"SetWBWarm", SetWBWarm, METH_VARARGS, "设置频道号"},
+    //////////////////////////////////////////////////////////////////////////
+    // 校验;
+    {"CheckDeviceId", CheckDeviceId, METH_VARARGS, "检验pid"},
+    {"CheckMAC", CheckMAC, METH_VARARGS, "检验MAC"},
+    {"CheckHDCP", CheckHDCP, METH_VARARGS, "检验HDCP"},
+    {"CheckHDCP22", CheckHDCP22, METH_VARARGS, "检验HDCP22"},
+    {"CheckWidi", CheckWidi, METH_VARARGS, "检验WIDI"},
+    {"CheckNetflixESN", CheckNetflixESN, METH_VARARGS, "检验ESN"},
+    {"CheckWidevine", CheckWidevine, METH_VARARGS, "检验WIDEVINE"},
+    {"CheckCikey", CheckCikey, METH_VARARGS, "检验CIKEY"},
+    {"StarWarmUpMode", StarWarmUpMode, METH_VARARGS, "检验OSDLAN"},
+    {"StopWarmUpMode", StopWarmUpMode, METH_VARARGS, "检验SHOPLAN"},
+    // others;
+    {"ShowFactoryMenu", ShowFactoryMenu, METH_VARARGS, "显示工厂菜单"},
+    {"HideFactoryMenu", HideFactoryMenu, METH_VARARGS, "隐藏工厂菜单"},
+    {"ShowFactoryInformation", ShowFactoryInformation, METH_VARARGS, "工厂信息内容显示"},
+    {"HideFactoryInformation", HideFactoryInformation, METH_VARARGS, "工厂信息内容隐藏"},
+    {"EnterAgingModel", EnterAgingModel, METH_VARARGS, "老化模式开"},
+    {"LeaveAgingModel", LeaveAgingModel, METH_VARARGS, "老化模式关"},
+    {"ReadAgingTime", ReadAgingTime, METH_VARARGS, "老化时间读取"},
+    {"SetRedGainRegister", SetRedGainRegister, METH_VARARGS, "红增益"},
+    {"SetGreenGainRegister", SetGreenGainRegister, METH_VARARGS, "绿增益"},
+    {"SetBlueGainRegister", SetBlueGainRegister, METH_VARARGS, "蓝增益"},
+    {"SetRedOffsetRegister", SetRedOffsetRegister, METH_VARARGS, "红偏移"},
+    {"SetGreenOffsetRegister", SetGreenOffsetRegister, METH_VARARGS, "绿偏移"},
+    {"SetBlueOffsetRegister", SetBlueOffsetRegister, METH_VARARGS, "蓝偏移"},
+    // HTTP
+    {"HTTPLogin", HTTPLogin, METH_VARARGS, "登录服务器"},
+    {"HTTPGetUserId", HTTPGetUserId, METH_VARARGS, "获取UserId"},
+    {NULL,NULL}
+};
+
+// 初始模块;//格式:init<模块名称>
+PyMODINIT_FUNC initScbcCopyKey()
+{
+    // 初始化pyd函数列表;
+    PyObject* m, * d;
+    m = Py_InitModule("ScbcCopyKey", ScbcCopyKey_Methods);
+    d = PyModule_GetDict(m);
+}
+#endif

+ 126 - 0
TCLCommand/TCLCommand/TCLCommand.h

@@ -0,0 +1,126 @@
+// 下列 ifdef 块是创建使从 DLL 导出更简单的
+// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 TCLCOMMAND_EXPORTS
+// 符号编译的。在使用此 DLL 的
+// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
+// TCLCOMMAND_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
+// 符号视为是被导出的。
+#ifdef TCLCOMMAND_EXPORTS
+#define TCLCOMMAND_API __declspec(dllexport)
+#else
+#define TCLCOMMAND_API __declspec(dllimport)
+#endif
+
+#ifdef EXPORTS_CLASS
+
+//class TCLCommand;
+#include "CommandParam.h"
+
+// 此类是从 TCLCommand.dll 导出的
+class TCLCOMMAND_API CTCLCommand {
+public:
+	CTCLCommand(void);
+	// TODO: 在此添加您的方法。
+    bool Open(int nPort, DWORD dwBaudrate, BYTE ByteSize, BYTE Parity, BYTE StopBits);
+    void Close();
+    bool IsOpen();
+    void SetExternalCMDParams(LPCTSTR lpFileName);
+    bool GetCommandParams(std::string name, CommandParam& cmdPara);
+    void PackingCommand(CommandParam& cmdPara, std::string data, const int& dataLen);
+    bool SendCommand(CommandParam& cmdPara);
+};
+
+extern TCLCOMMAND_API int nTCLCommand;
+
+TCLCOMMAND_API int fnTCLCommand(void);
+
+#else
+// 打开串口;
+TCLCOMMAND_API bool Open(int nPort, DWORD dwBaudrate, BYTE ByteSize, BYTE Parity, BYTE StopBits);
+// 关闭串口;
+TCLCOMMAND_API void Close();
+// 串口是否打开;
+TCLCOMMAND_API bool IsOpen();
+TCLCOMMAND_API void SetExternalCMDParams(LPCTSTR lpFileName);
+
+// 指令接口;
+TCLCOMMAND_API bool EnterFactory();
+TCLCOMMAND_API bool LeaveFactory();
+TCLCOMMAND_API bool GetProjectId(int &pid);
+TCLCOMMAND_API bool GetSoftVersion(std::string &strValue);
+TCLCOMMAND_API bool GetDeviceId(std::string &strValue);
+TCLCOMMAND_API bool GetClientType(std::string &strValue);
+TCLCOMMAND_API bool GetMAC(std::string &strValue);
+TCLCOMMAND_API bool GetHDCPKey(std::string &strValue);
+TCLCOMMAND_API bool GetHDCPKey22(std::string &strValue);
+TCLCOMMAND_API bool GetWidi(std::string &strValue);
+TCLCOMMAND_API bool GetNetflixESN(std::string &strValue);
+TCLCOMMAND_API bool GetWidevine(std::string &strValue);
+TCLCOMMAND_API bool GetCiKey(std::string &strValue);
+TCLCOMMAND_API bool GetOSDLanguage(std::string &strValue);
+TCLCOMMAND_API bool GetShopLanguage(std::string &strValue);
+TCLCOMMAND_API bool GetChannel(std::string &strValueTCLCOMMAND_API );
+
+TCLCOMMAND_API bool SetProjectId(int pid);
+TCLCOMMAND_API bool SetProjectId(LPCTSTR lpPid);
+TCLCOMMAND_API bool SetProjectId(const byte* pBuffer, const int& nLen);
+TCLCOMMAND_API bool SetDeviceId(LPCTSTR lpDeviceId);
+TCLCOMMAND_API bool SetDeviceId(const byte* pBuffer, const int &nLen);
+TCLCOMMAND_API bool SetMAC(LPCTSTR lpMac);
+TCLCOMMAND_API bool SetMAC(const byte* pBuffer, const int& nLen);
+TCLCOMMAND_API bool SetHDCPKey(LPCTSTR lpHDCP, bool bHasSpace = FALSE);
+TCLCOMMAND_API bool SetHDCPKey(const byte* pBuffer, const int& nLen);
+TCLCOMMAND_API bool SetHDCPKey22(LPCTSTR lpHDCP22, bool bHasSpace = FALSE);
+TCLCOMMAND_API bool SetHDCPKey22(const byte* pBuffer, const int& nLen);
+TCLCOMMAND_API bool SetNetflixESN(LPCTSTR lpESN, bool bHasSpace = FALSE);
+TCLCOMMAND_API bool SetNetflixESN(const byte* pBuffer, const int& nLen);
+TCLCOMMAND_API bool SetWidi(LPCTSTR lpWidi, bool bHasSpace = FALSE);
+TCLCOMMAND_API bool SetWidi(const byte* pBuffer, const int& nLen);
+TCLCOMMAND_API bool SetWidevine(LPCTSTR lpWidevine, bool bHasSpace = FALSE);
+TCLCOMMAND_API bool SetWidevine(const byte* pBuffer, const int& nLen);
+TCLCOMMAND_API bool SetCiKey(LPCTSTR lpCiKey, bool bHasSpace = FALSE);
+TCLCOMMAND_API bool SetCiKey(const byte* pBuffer, const int& nLen);
+TCLCOMMAND_API bool SetOSDLanguage(LPCTSTR lan, bool bHasSpace = TRUE);
+TCLCOMMAND_API bool SetOSDLanguage(const byte* pBuffer, const int& nLen);
+TCLCOMMAND_API bool SetShopLanguage(LPCTSTR lan, bool bHasSpace = TRUE);
+TCLCOMMAND_API bool SetShopLanguage(const byte* pBuffer, const int& nLen);
+TCLCOMMAND_API bool SetChannel(LPCTSTR channel, bool bHasSpace = TRUE);
+TCLCOMMAND_API bool SetChannel(const byte* pBuffer, const int& nLen);
+TCLCOMMAND_API bool SetWBNormal(LPCTSTR data);
+TCLCOMMAND_API bool SetWBNormal(const byte* pBuffer, const int& nLen);
+TCLCOMMAND_API bool SetWBCool(LPCTSTR data);
+TCLCOMMAND_API bool SetWBCool(const byte* pBuffer, const int& nLen);
+TCLCOMMAND_API bool SetWBWarm(LPCTSTR data);
+TCLCOMMAND_API bool SetWBWarm(const byte* pBuffer, const int& nLenTCLCOMMAND_API );
+
+TCLCOMMAND_API bool CheckDeviceId();
+TCLCOMMAND_API bool CheckMAC();
+TCLCOMMAND_API bool CheckHDCP();
+TCLCOMMAND_API bool CheckHDCP22();
+TCLCOMMAND_API bool CheckNetflixESN();
+TCLCOMMAND_API bool CheckWidi();
+TCLCOMMAND_API bool CheckWidevine();
+TCLCOMMAND_API bool CheckCikeyTCLCOMMAND_API ();
+
+TCLCOMMAND_API bool StarWarmUpMode();
+TCLCOMMAND_API bool StopWarmUpModeTCLCOMMAND_API ();
+
+// 工厂菜单显示与隐藏;
+TCLCOMMAND_API bool ShowFactoryMenu();
+TCLCOMMAND_API bool HideFactoryMenu();
+// 工厂信息内容显示与隐藏;
+TCLCOMMAND_API bool ShowFactoryInformation();
+TCLCOMMAND_API bool HideFactoryInformation();
+// 老化模式的开与关、老化时间读取;
+TCLCOMMAND_API bool EnterAgingModel();
+TCLCOMMAND_API bool LeaveAgingModel();
+TCLCOMMAND_API bool ReadAgingTime(int &min);
+// 红绿蓝增益;
+TCLCOMMAND_API bool SetRedGainRegister(int value);
+TCLCOMMAND_API bool SetGreenGainRegister(int value);
+TCLCOMMAND_API bool SetBlueGainRegister(int value);
+// 红绿蓝偏移;
+TCLCOMMAND_API bool SetRedOffsetRegister(int value);
+TCLCOMMAND_API bool SetGreenOffsetRegister(int value);
+TCLCOMMAND_API bool SetBlueOffsetRegister(int value);
+
+#endif

+ 81 - 0
TCLCommand/TCLCommand/TCLCommand.rc

@@ -0,0 +1,81 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// 中文(中华人民共和国) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
+#ifdef _WIN32
+LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
+#pragma code_page(936)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// BIN
+//
+
+BIN_CMD                 BIN                     "command.data"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE 
+BEGIN
+    IDS_APP_TITLE           "TCLCommand"
+END
+
+#endif    // 中文(中华人民共和国) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+

+ 519 - 0
TCLCommand/TCLCommand/TCLCommand.vcproj

@@ -0,0 +1,519 @@
+<?xml version="1.0" encoding="gb2312"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="TCLCommand"
+	ProjectGUID="{27E3466D-67B0-42C4-BAB9-B497D6143C61}"
+	RootNamespace="TCLCommand"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="..\..\..\..\bin\$(SolutionName)"
+			IntermediateDirectory="$(OutDir)\$(ProjectName)\$(ConfigurationName)"
+			ConfigurationType="2"
+			UseOfMFC="2"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;TCLCOMMAND_EXPORTS"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="..\..\..\..\bin\$(SolutionName)"
+			IntermediateDirectory="$(OutDir)\$(ProjectName)\$(ConfigurationName)"
+			ConfigurationType="2"
+			UseOfMFC="2"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TCLCOMMAND_EXPORTS"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="DebugEXE|Win32"
+			OutputDirectory="..\..\..\..\bin\$(SolutionName)"
+			IntermediateDirectory="$(OutDir)\$(ProjectName)\$(ConfigurationName)"
+			ConfigurationType="1"
+			UseOfMFC="2"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;__CONSOLE__;TCLCOMMAND_EXPORTS"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PYD|Win32"
+			OutputDirectory="..\..\..\..\bin\$(SolutionName)"
+			IntermediateDirectory="$(OutDir)\$(ProjectName)\$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				AdditionalIncludeDirectories="C:\Python27\include;"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TCLCOMMAND_EXPORTS;__MAKE_PYD__"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName).pyd"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="C:\Python27\libs;"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ExportClass|Win32"
+			OutputDirectory="$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			UseOfMFC="2"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TCLCOMMAND_EXPORTS;EXPORTS_CLASS"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Ô´Îļþ"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\Command.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\Serial.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="DebugEXE|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="PYD|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="ExportClass|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\TCLCommand.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\utils.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Í·Îļþ"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\Command.h"
+				>
+			</File>
+			<File
+				RelativePath=".\CommandParam.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Resource.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Serial.h"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.h"
+				>
+			</File>
+			<File
+				RelativePath=".\targetver.h"
+				>
+			</File>
+			<File
+				RelativePath=".\TCLCommand.h"
+				>
+			</File>
+			<File
+				RelativePath=".\utils.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="×ÊÔ´Îļþ"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+			<File
+				RelativePath=".\command.data"
+				>
+			</File>
+			<File
+				RelativePath=".\TCLCommand.rc"
+				>
+			</File>
+		</Filter>
+		<File
+			RelativePath=".\ReadMe.txt"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

+ 45 - 0
TCLCommand/TCLCommand/command.data

@@ -0,0 +1,45 @@
+# Get Info;
+Name=EnterFactory; Option=None; HeadCode=AA; Command=10; CMDParam=01; MultiParams=false; ReadWaitTime=150ms; CMDWaitTime=100ms
+Name=GetSoftVersion; Option=Get; HeadCode=AA; Command=57; CMDParam=00; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=GetProjectID; Option=Get; HeadCode=AA; Command=84; CMDParam=00; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=GetDeviceId; Option=Get; HeadCode=AA; Command=BE; CMDParam=01; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=GetClientType; Option=Get; HeadCode=AA; Command=8C; CMDParam=00; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=GetMAC; Option=Get; HeadCode=AA; Command=BE; CMDParam=00; MultiParams=true; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=GetHDCPKey; Option=Get; HeadCode=AA; Command=EE; CMDParam=00; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=GetHDCPKey22; Option=Get; HeadCode=AA; Command=E7; CMDParam=00; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=GetWidi; Option=Get; HeadCode=AA; Command=E7; CMDParam=00; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=GetNetflixESN; Option=Get; HeadCode=AA; Command=BE; CMDParam=06; MultiParams=true; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=GetWidevine; Option=Get; HeadCode=AA; Command=EC; CMDParam=00; MultiParams=true; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=GetCiKey; Option=Get; HeadCode=AA; Command=EC; CMDParam=01; MultiParams=true; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=GetOSDLanguage; Option=Get; HeadCode=AA; Command=97; CMDParam=00; MultiParams=true; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=GetShopLanguage; Option=Get; HeadCode=AA; Command=97; CMDParam=01; MultiParams=true; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=GetChannel; Option=Get; HeadCode=AA; Command=97; CMDParam=13; MultiParams=true; ReadWaitTime=100ms; CMDWaitTime=100ms
+# Check is Get-Option
+Name=CheckMAC; Option=Get; HeadCode=AA; Command=B4; CMDParam=00; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=CheckDeviceId; Option=Get; HeadCode=AA; Command=B4; CMDParam=00; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=CheckHDCP; Option=Get; HeadCode=AA; Command=87; CMDParam=00; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=CheckNetflixESN; Option=Get; HeadCode=AA; Command=9A; CMDParam=00; MultiParams=true; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=CheckWidi; Option=Get; HeadCode=AA; Command=E5; CMDParam=00; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=CheckWidevine; Option=Get; HeadCode=AA; Command=EA; CMDParam=00; MultiParams=true; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=CheckCikey; Option=Get; HeadCode=AA; Command=EA; CMDParam=01; MultiParams=true; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=CheckHDCP22; Option=Get; HeadCode=AA; Command=E5; CMDParam=00; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=LeaveFactory; Option=None; HeadCode=AA; Command=10; CMDParam=00; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=WBInit; Option=Get; HeadCode=AA; Command=16; CMDParam=02; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+# Set Info;
+Name=SetProjectId; Option=Set; HeadCode=AA; Command=70; CMDParam=/; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=SetDeviceID; Option=Set; HeadCode=AA; Command=B2; CMDParam=/; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=SetMAC; Option=Set; HeadCode=AA; Command=B3; CMDParam=/; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=SetHDCPKey; Option=Set; HeadCode=AA FE; Command=86; CMDParam=/; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=SetHDCPKey22; Option=Set; HeadCode=AA FE; Command=E4; CMDParam=/; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=SetNetflixESN; Option=Set; HeadCode=AA; Command=99 00; CMDParam=/; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=SetWidi; Option=Set; HeadCode=AA FE; Command=E4; CMDParam=/; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=SetWidevine; Option=Set; HeadCode=AA FE; Command=E9 00; CMDParam=/; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=SetCiKey; Option=Set; HeadCode=AA FE; Command=E9 01; CMDParam=/; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=SetOSDLanguage; Option=Set; HeadCode=AA; Command=99 00; CMDParam=/; MultiParams=true; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=SetShopLanguage; Option=Set; HeadCode=AA; Command=96 01; CMDParam=/; MultiParams=true; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=SetChannel; Option=Set; HeadCode=AA; Command=15; CMDParam=/; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=SetWBNormal; Option=Set; HeadCode=AA; Command=4D 04 01 01; CMDParam=/; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=SetWBCool; Option=Set; HeadCode=AA; Command=4D 04 02 01; CMDParam=/; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=SetWBWarm; Option=Set; HeadCode=AA; Command=4D 04 03 01; CMDParam=/; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=StarWarmUpMode; Option=None; HeadCode=AA; Command=13; CMDParam=01; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=StopWarmUpMode; Option=None; HeadCode=AA; Command=13; CMDParam=00; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms

+ 18 - 0
TCLCommand/TCLCommand/resource.h

@@ -0,0 +1,18 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by TCLCommand.rc
+//
+#define IDR_BIN1                        101
+#define BIN_CMD                         101
+#define IDS_APP_TITLE                   103
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        102
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1000
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif

+ 8 - 0
TCLCommand/TCLCommand/stdafx.cpp

@@ -0,0 +1,8 @@
+// stdafx.cpp : 只包括标准包含文件的源文件
+// TCLCommand.pch 将作为预编译头
+// stdafx.obj 将包含预编译类型信息
+
+#include "stdafx.h"
+
+// TODO: 在 STDAFX.H 中
+// 引用任何所需的附加头文件,而不是在此文件中引用

+ 35 - 0
TCLCommand/TCLCommand/stdafx.h

@@ -0,0 +1,35 @@
+// stdafx.h : 标准系统包含文件的包含文件,
+// 或是经常使用但不常更改的
+// 特定于项目的包含文件
+//
+
+#pragma once
+
+#include "targetver.h"
+
+#define WIN32_LEAN_AND_MEAN             // 从 Windows 头中排除极少使用的资料
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // 某些 CString 构造函数将是显式的
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN            // 从 Windows 头中排除极少使用的资料
+#endif
+
+#include <afx.h>
+#include <afxwin.h>         // MFC 核心组件和标准组件
+#include <afxext.h>         // MFC 扩展
+#ifndef _AFX_NO_OLE_SUPPORT
+#include <afxdtctl.h>           // MFC 对 Internet Explorer 4 公共控件的支持
+#endif
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h>                     // MFC 对 Windows 公共控件的支持
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+#include <iostream>
+// Windows 头文件:
+#include <windows.h>
+#include <string>
+#include <vector>
+#include "utils.h"
+
+
+// TODO: 在此处引用程序需要的其他头文件

+ 24 - 0
TCLCommand/TCLCommand/targetver.h

@@ -0,0 +1,24 @@
+#pragma once
+
+// 以下宏定义要求的最低平台。要求的最低平台
+// 是具有运行应用程序所需功能的 Windows、Internet Explorer 等产品的
+// 最早版本。通过在指定版本及更低版本的平台上启用所有可用的功能,宏可以
+// 正常工作。
+
+// 如果必须要针对低于以下指定版本的平台,请修改下列定义。
+// 有关不同平台对应值的最新信息,请参考 MSDN。
+#ifndef WINVER                          // 指定要求的最低平台是 Windows Vista。
+#define WINVER 0x0600           // 将此值更改为相应的值,以适用于 Windows 的其他版本。
+#endif
+
+#ifndef _WIN32_WINNT            // 指定要求的最低平台是 Windows Vista。
+#define _WIN32_WINNT 0x0600     // 将此值更改为相应的值,以适用于 Windows 的其他版本。
+#endif
+
+#ifndef _WIN32_WINDOWS          // 指定要求的最低平台是 Windows 98。
+#define _WIN32_WINDOWS 0x0410 // 将此值更改为适当的值,以适用于 Windows Me 或更高版本。
+#endif
+
+#ifndef _WIN32_IE                       // 指定要求的最低平台是 Internet Explorer 7.0。
+#define _WIN32_IE 0x0700        // 将此值更改为相应的值,以适用于 IE 的其他版本。
+#endif

+ 212 - 0
TCLCommand/TCLCommand/utils.cpp

@@ -0,0 +1,212 @@
+#include "stdafx.h"
+#include "utils.h"
+
+namespace utils
+{
+    const unsigned short CRC16_TABLE[16] = {
+    0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+    0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF
+    };
+
+    std::string& trim(std::string& str)
+    {
+#if _MSC_VER >= 1200 && _MSC_VER < 1600
+        for (std::string::iterator it = str.begin(); it != str.end();) {
+            !isspace(*it) ? it++ : it = it = str.erase(it);
+        }
+#elif _MSC_VER >= 1600
+        str.erase(std::remove_if(str.begin(), str.end(), [](unsigned char x) {return std::isspace(x); }), str.end()); //C++17
+#endif
+        return str;
+    }
+
+    std::string _dprintf(CHAR* pszStr, ...)
+    {
+        const int LOGLEN = 8912;
+        char szData[LOGLEN] = { 0 };
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+        sprintf(szData, _T("[%s %s]\n\t"), _T("Db"), CTime::GetCurrentTime().Format(_T("%H:%M:%S")));
+#elif _MSC_VER >= 1500
+        _stprintf_s(szData, _T("[%s %s]\n\t"), _T("Db"), CTime::GetCurrentTime().Format(_T("%H:%M:%S")).GetString());
+#endif
+        int len = strlen(szData);
+        va_list args;
+        va_start(args, pszStr);
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+        _vsnprintf(szData + len, LOGLEN - len, pszStr, args);
+#elif _MSC_VER >= 1500
+        _vsntprintf_s(szData + len, LOGLEN - len, _TRUNCATE, pszStr, args);
+#endif
+        va_end(args);
+        if (szData[strlen(szData) - 1] != '\n')
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+            strcat(szData, "\n");
+#elif _MSC_VER >= 1500
+            strcat_s(szData, "\n");
+#endif
+        OutputDebugStringA(szData);
+
+        return std::string(szData);
+    }
+
+    std::string ByteToChars(byte b)
+    {
+        char szhex[3] = { 0 };
+
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+        sprintf(szhex, "%02X", b);
+#elif _MSC_VER >= 1500
+        _stprintf_s(szhex, "%02X", b);
+#endif
+
+        return std::string(szhex);
+    }
+
+    BOOL IsValidString(LPCTSTR lpszString)
+    {
+        if (lpszString == NULL)
+            return FALSE;
+
+        do {
+            // ASCII可显示的字符;
+            if (*lpszString < 32 || *lpszString > 126) {
+                return FALSE;
+            }
+        } while (*++lpszString);
+
+        return TRUE;
+    }
+
+    unsigned char TwoHexCharToInteger(char high, char low)
+    {
+        std::string str = "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz";
+        if (str.find_first_of(high) == std::string::npos || str.find_first_of(low) == std::string::npos)
+        {
+            return 0;
+        }
+
+        char Numb1 = high >= 'A' ? (toupper(high) - '0' - 7) * 16 : (high - '0') * 16;
+        char Numb2 = low >= 'A' ? (toupper(low) - '0' - 7) : (low - '0');
+
+        return (Numb1 + Numb2);
+    }
+
+    std::string BytesToHexString(const unsigned char* pbuffer, int nLen)
+    {
+        std::string hex;
+        char szhex[5] = { 0 };
+        for (int i = 0; i < nLen; i++)
+        {
+            memset(szhex, 0, 5);
+
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+            sprintf(szhex, "%02X", pbuffer[i]);
+#elif _MSC_VER >= 1500
+            _stprintf_s(szhex, "%02X", pbuffer[i]);
+#endif
+            hex.append(szhex);
+        }
+
+        return hex;
+    }
+
+    std::string BytesToHexString(const unsigned char* pbuffer, int nLen, char chSpace)
+    {
+        std::string hex;
+        char szhex[5] = { 0 };
+        for (int i = 0; i < nLen; i++)
+        {
+            memset(szhex, 0, 5);
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+            sprintf(szhex, "%02X%c", pbuffer[i], chSpace);
+#elif _MSC_VER >= 1500
+            _stprintf_s(szhex, "%02X%c", pbuffer[i], chSpace);
+#endif
+            hex.append(szhex);
+        }
+
+        return hex.substr(0, hex.size() - 1);
+    }
+
+    std::string HexStringToBytes(std::string strHex, const int& len)
+    {
+        byte value = 0;
+        std::string strBytes;
+        int nSize = strHex.size();
+        for (int i = 0; i < nSize; i += len)
+        {
+#if _MSC_VER >=1200 && _MSC_VER < 1500
+            strBytes.append((char)TwoHexCharToInteger(strHex[i], strHex[i + 1]), 1);
+#elif _MSC_VER >=1500
+            strBytes.push_back((char)TwoHexCharToInteger(strHex[i], strHex[i + 1]));
+#endif
+        }
+
+        return strBytes;
+    }
+
+    unsigned short CRC16Calculate(byte* pBuffer, unsigned int wordLength)
+    {
+        byte byteTemp(0);
+        unsigned short wordCRC(0);
+
+        wordCRC = 0xFFFF;
+        while (wordLength--) {
+            byteTemp = (byte)(wordCRC >> 0x0C);
+            wordCRC <<= 4;
+            wordCRC ^= CRC16_TABLE[byteTemp ^ ((*pBuffer) >> 0x04)];
+            byteTemp = (byte)(wordCRC >> 0x0C);
+            wordCRC <<= 4;
+            wordCRC ^= CRC16_TABLE[byteTemp ^ ((*pBuffer) & 0x0F)];
+            pBuffer++;
+        }
+
+        return wordCRC;
+    }
+
+    bool GetResourceData(DWORD dwResourceID, LPCTSTR lpExt, std::string &rtnData)
+    {
+        HGLOBAL hGlobal = NULL;
+        HRSRC   hSource = NULL;
+        LPVOID  lpBuffer = NULL;
+        DWORD   dwSize = 0;
+        BOOL    bResult = FALSE;
+
+        // 1.查找资源,如果没找到返回Null
+        hSource = FindResource(NULL, MAKEINTRESOURCE(dwResourceID), lpExt);
+        if (hSource == NULL) {
+            _dprintf(_T("查找资源失败:%s,ID=%d"), lpExt, dwResourceID);
+            return false;
+        }
+
+        // 2.获取资源大小;
+        dwSize = (UINT)SizeofResource(NULL, hSource);
+
+        // 3.加载资源;
+        hGlobal = LoadResource(NULL, hSource);
+        if (hGlobal == NULL) {
+            _dprintf(_T("加载资源失败:%s,ID=%d"), lpExt, dwResourceID);
+            return false;
+        }
+
+        // 4.提取到buffer中;
+        lpBuffer = LockResource(hGlobal);
+        if (lpBuffer == NULL) {
+            _dprintf(_T("锁定资源失败:%s,ID=%d"), lpExt, dwResourceID);
+            return false;
+        }
+
+#if _MSC_VER >=1200 && _MSC_VER < 1500
+		rtnData = "";
+#elif _MSC_VER >= 1500
+        rtnData.clear();
+#endif
+        rtnData.append((char*)lpBuffer, dwSize);
+
+        // 释放资源;
+        UnlockResource(hGlobal);
+        FreeResource(hGlobal);
+
+        return true;
+    }
+}

+ 17 - 0
TCLCommand/TCLCommand/utils.h

@@ -0,0 +1,17 @@
+#pragma once
+namespace utils
+{
+    std::string& trim(std::string& str);
+    std::string _dprintf(CHAR* pszStr, ...);
+    std::string ByteToChars(byte b);
+    BOOL IsValidString(LPCTSTR lpszString);
+    unsigned char TwoHexCharToInteger(char high, char low);
+    std::string BytesToHexString(const unsigned char* pbuffer, int nLen);
+    std::string BytesToHexString(const unsigned char* pbuffer, int nLen, char chSpace);
+
+    std::string HexStringToBytes(std::string strHex, const int& len /* = 3 */);
+    unsigned short CRC16Calculate(byte* pBuffer, unsigned int wordLength);
+
+	bool GetResourceData(DWORD dwResourceID, LPCTSTR lpExt, std::string &rtnData);
+};
+