#include #include #include #include #include #include #include #include #include namespace fs = std::filesystem; struct Configure { wxString name; wxString work_dir; wxArrayString exclude; }; static wxString work_path; static wxString cw_work_path; bool parse_xml(const wxString& filepath, const wxString& name, Configure& config) { wxXmlDocument xmlDoc; if (!xmlDoc.Load(filepath)) { return false; } wxXmlNode* root = xmlDoc.GetRoot(); auto c = root->GetChildren(); if (!c) { wxLogMessage("解析Xml失败。"); return false; } bool find = false; while (c) { if (c->GetName() != "Item") { c = c->GetNext(); continue; } if (c->GetAttribute("Name") != name) { c = c->GetNext(); continue; } find = true; config.name = name; #ifdef _WIN32 config.work_dir = c->GetAttribute("WinWorkPath"); #else config.work_dir = c->GetAttribute("UnixWorkPath"); #endif auto p = c->GetChildren(); while (p) { config.exclude.push_back(p->GetNodeContent()); p = p->GetNext(); } break; } if (!find) { wxLogMessage(wxT("未找到%s的配置。"), name); return false; } else { wxLogMessage(wxT("找到%s的配置。"), name); } return true; } wxString ConvertToCygwinPath(const wxString& path) { #ifdef _WIN32 // 提取驱动器字母 wxString drive = path.BeforeFirst('\\').Upper(); drive.erase(1, 1); wxString restPath = path.AfterFirst('\\'); // 替换为 Cygwin 格式 wxString cygwinPath = "/cygdrive/" + drive.Lower(); if (!restPath.empty()) { cygwinPath.append("/" + restPath); } cygwinPath.Replace("\\", "/"); return cygwinPath; #else return path; #endif } wxString get_cmd(Configure& config, bool to_cur) { wxString cmd_str; #if _WIN32 wxString cmd = work_path + "cwrsync\\bin\\rsync.exe "; cmd_str.append(cmd); #else cmd_str.append("rsync "); #endif cmd_str.append("-av"); wxString dir_str; if (to_cur) { fs::path path(config.work_dir.ToStdString()); path.append(config.name.ToStdString()); dir_str.append(ConvertToCygwinPath(wxString(path.string()))); dir_str.append(" " + cw_work_path); } else { fs::path path(cw_work_path.ToStdString()); path.append(config.name.ToStdString()); dir_str.append(wxString(path.string())); dir_str.append(" " + ConvertToCygwinPath(config.work_dir)); } for (const auto& data : config.exclude) { cmd_str.append(" --exclude=" + data); } cmd_str.append(" "); cmd_str.append(dir_str); wxLogMessage(cmd_str); return cmd_str; } int main(int argc, char* argv[]) { // 确保当前程序能够与所使用的 wxWidgets 库兼容 wxApp::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE, "program"); wxInitializer initializer; if (!initializer) { std::cout << "初始化失败。" << std::endl; return -2; } if (argc < 3) { std::cout << "需要传入文件夹名称[XXX]及方向[From/To]。" << std::endl; return 0; } wxString oper_dir(argv[1]); wxString direct(argv[2]); if (direct != "From" && direct != "To") { std::cout << "方向不合法,必须是[From/To]。"; return -3; } // 读取配置文件 msync.xml const wxStandardPaths& stdpath = wxStandardPaths::Get(); wxString exe_path = stdpath.GetExecutablePath(); wxFileName file_name(exe_path); work_path = file_name.GetPathWithSep(); cw_work_path = ConvertToCygwinPath(work_path); wxString config_path = work_path + "msync.xml"; Configure config; if (!parse_xml(config_path, oper_dir, config)) { return -1; } auto command = get_cmd(config, direct == "From"); wxArrayString output; // 使用 wxExecute 执行命令 long result = wxExecute(command, output, wxEXEC_SYNC); wxLogMessage(wxT("命令执行结果:%ld"), result); wxString out_str; for (const auto& data : output) { out_str.append(data + "\n"); } wxLogMessage(wxT("命令输出:\n%s\n"), out_str); return 0; }