172 lines
4.3 KiB
C++
172 lines
4.3 KiB
C++
#include <filesystem>
|
|
#include <iostream>
|
|
#include <wx/app.h>
|
|
#include <wx/arrstr.h>
|
|
#include <wx/filename.h>
|
|
#include <wx/log.h>
|
|
#include <wx/stdpaths.h>
|
|
#include <wx/utils.h>
|
|
#include <wx/xml/xml.h>
|
|
|
|
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;
|
|
}
|