问题根源在于:JSON字符串作为命令行参数传递时,双引号和特殊字符没有正确转义,导致JSON格式被破坏。
你的分析完全正确。观察这个调用:
"C:\...\BaiduNetdisk.exe" -imgviewimgtopdf "{"actionType":14,"height":1680,...}"
JSON部分 {"actionType":14,...} 虽然外层有双引号包裹,但内部的JSON双引号没有转义。系统会错误地将第一个 " 视为参数结束,导致传递的JSON变成不完整的 {actionType:14,...。
🔧 解决方案
方案1:发送方进行转义(推荐)
在构造命令行的发送方,需要对JSON字符串进行转义:
// 原始JSON字符串 CString strJson = L"{\"actionType\":14,\"height\":1680,...}"; // 转义:将双引号转义为\",反斜杠转义为\\ CString strJsonEscaped = strJson; strJsonEscaped.Replace(L"\\", L"\\\\"); // 先转义反斜杠 strJsonEscaped.Replace(L"\"", L"\\\""); // 再转义双引号 // 构造命令 strExe.Format(L"\"%s\" -%s \"%s\"", bsExePath, strCommand, strJsonEscaped); // 结果:-imgviewimgtopdf "{\"actionType\":14,\"height\":1680,...}"
方案2:接收方进行修复
如果无法修改发送方,可以在接收方尝试修复:
// 接收方获取参数后,尝试修复常见问题 CString FixJsonString(const CString& strInput) { CString strResult = strInput; // 情况1:参数可能丢失了外层引号 if (strResult.GetLength() > 0 && strResult[0] == L'{' && strResult[strResult.GetLength()-1] == L'}') { // 已经是完整JSON,直接返回 return strResult; } // 情况2:尝试查找实际的JSON开始和结束 int nStart = strResult.Find(L'{'); int nEnd = strResult.ReverseFind(L'}'); if (nStart >= 0 && nEnd > nStart) { return strResult.Mid(nStart, nEnd - nStart + 1); } return strResult; } // 使用 CString strFixedJson = FixJsonString(bsJsonData); if (CString(strFixedJson).IsEmpty()) { XLogDebug(L"JsonLib::Parse Input String Is Empty"); return E_FAIL; }
方案3:使用Base64编码(最可靠)
最彻底的方法是使用Base64编码传递JSON:
发送方:
// 对JSON进行Base64编码 CStringA strJsonUtf8 = CT2A(strJson, CP_UTF8); CString strBase64 = Base64Encode(strJsonUtf8); // 实现Base64编码 // 发送编码后的数据 strExe.Format(L"\"%s\" -%s %s", bsExePath, strCommand, strBase64);
接收方:
// 解码Base64 CStringA strUtf8Json = Base64Decode(bsJsonData); // 实现Base64解码 CStringW strJson = CA2W(strUtf8Json, CP_UTF8); // 继续原有解析流程 CStringA utf8JsonContactData; AppUtil::Misc::TransformWStringToUtf8String(strJson, utf8JsonContactData);
📋 调试建议
添加详细日志来确定问题:
// 在解析前输出原始参数 XLogDebug(L"JsonLib::Parse Raw Input: %s", bsJsonData); XLogDebug(L"JsonLib::Parse Input Length: %d", CString(bsJsonData).GetLength()); // 输出转换后的UTF8字符串 CStringA utf8JsonContactData; AppUtil::Misc::TransformWStringToUtf8String(bsJsonData, utf8JsonContactData); XLogDebug(L"JsonLib::Parse UTF8 Length: %d", utf8JsonContactData.GetLength()); 核心理解:
1、调式技能 : 同时起来一个exe和另外一个exe时,可以通过 childProcess插件处理;
2、起来命令行的方式,改为我们软件内部的这个output下面的exe,保证模拟一摸一样的启动方式;
3、理解字符串转义是Windows系统编程和跨进程通信中的重要基础。在调试时,可以添加日志来验证每个阶段的字符串内容,这会帮助你更直观地理解转义过程。
(1)一定要理解 在c++中书写的代码(字面量写法),和实际代表(实际内存含义)的含义这两个层面。
(2)顺序要求 : 核心最先把里带有转移字符的给替换,后面给特殊字符再增加一个转义字符,避免多增加一份转义字符的问题;
🎯 核心要点总结
-
C++编译器的转义:在代码中写
"\\"会创建一个包含单个\的字符串 -
Windows命令行的转义:命令行解析器也需要转义字符来识别特殊字符
-
双重转义的必要性:
-
第一层:为了JSON格式本身(JSON中的
\) -
第二层:为了命令行解析(不被命令行误解析)
-
-
转义顺序很重要:先转义
\,再转义",否则会出错
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。


评论(0)