修正使用绝对路径时的问题

This commit is contained in:
2026-03-31 10:21:24 +08:00
parent 86034c71e0
commit d2dbcd5465
5 changed files with 309 additions and 19 deletions

View File

@@ -15,6 +15,8 @@
#include <vector>
#include <zoost/zoost.h>
#include "SimMd5.hpp"
#ifdef _WIN32
#include <windows.h>
#endif
@@ -33,27 +35,30 @@ struct FileMapping {
// 操作记录结构
struct OperationRecord {
fs::path source; // 源文件绝对路径
fs::path target; // 目标文件绝对路径
fs::path backup; // 备份路径
bool exists; // 目标文件是否存在
bool isNew; // 是否是新增文件
std::string backupRelative; // 相对备份路径
fs::path source; // 文件绝对路径
fs::path target; // 目标文件绝对路径
fs::path backup; // 备份路径
bool exists; // 目标文件是否存在
bool isNew; // 是否是新增文件
};
class AutoUpdateTool
{
private:
std::string configFile;
fs::path workDir; // 工作目录(新文件所在)
fs::path updateDir; // 更新目录(目标目录)
fs::path backupDir; // 备份目录
std::string fromType; // 源类型:"m" 或 "n"
std::string toType; // 目标类型:"m" 或 "n"
fs::path workDir; // 工作目录(新文件所在)
fs::path updateDir{"."}; // 更新目录(目标目录)
fs::path backupDir; // 备份目录
std::string fromType; // 源类型:"m" 或 "n"
std::string toType; // 目标类型:"m" 或 "n"
std::vector<FileMapping> mappings;
std::shared_ptr<spdlog::logger> logger;
std::string markerDir; // 标记目录名
std::string logPath_;
std::string logName_{"fileUpdater.log"};
bool verify_{true};
SimpleMD5 md5_;
public:
AutoUpdateTool()
@@ -94,7 +99,7 @@ public:
app.add_option("-w,--work-dir", workDir, "工作目录(新文件所在)")->default_val(fs::current_path());
app.add_option("-u,--update-dir", updateDir, "更新目录(目标目录)")->required();
app.add_option("-u,--update-dir", updateDir, "更新目录(目标目录)");
app.add_option("-b,--backup-dir", backupDir, "备份目录")->required();
@@ -102,6 +107,8 @@ public:
app.add_option("-t,--to", toType, "目标类型 (m 或 n)")->required()->check(CLI::IsMember({"m", "n"}));
app.add_flag("-v,--verify", verify_, "是否进行备份校验(默认是)。");
try {
app.parse(argc, argv);
@@ -223,6 +230,8 @@ public:
for (const auto& mapping : mappings) {
// 确定源路径和目标路径
std::string fromPath, toPath;
std::string backupRelativePath;
if (fromType == "m") {
fromPath = mapping.m;
} else {
@@ -235,9 +244,20 @@ public:
toPath = mapping.n;
}
// 构建绝对路径
fs::path sourceAbs = workDir / fromPath;
fs::path targetAbs = updateDir / toPath;
fs::path sourceAbs;
fs::path targetAbs;
if (fs::path(fromPath).is_absolute()) {
sourceAbs = fs::path(fromPath);
} else {
sourceAbs = workDir / fromPath;
backupRelativePath = fromPath;
}
if (fs::path(toPath).is_absolute()) {
targetAbs = fs::path(toPath);
} else {
targetAbs = updateDir / toPath;
}
// 步骤1:检查源路径是否存在
if (!checkPath(sourceAbs, mapping.isFile)) {
@@ -262,6 +282,7 @@ public:
record.target = targetAbs;
record.exists = fs::exists(targetAbs);
record.isNew = !record.exists;
record.backupRelative = backupRelativePath;
if (mapping.isFile) {
// 文件处理
@@ -288,6 +309,7 @@ public:
dirRecord.target = targetAbs / relPath;
dirRecord.exists = fs::exists(dirRecord.target);
dirRecord.isNew = !dirRecord.exists;
dirRecord.backupRelative = backupRelativePath;
records.push_back(dirRecord);
}
}
@@ -327,9 +349,10 @@ public:
// 获取用户输入的标记目录
bool getMarkerDirectory()
{
std::cout << "\n请输入标记目录名称(留空使用时间戳): ";
std::cout << "\n请输入此次备份标记名称(留空使用时间戳): ";
std::getline(boost::nowide::cin, markerDir);
boost::trim(markerDir);
if (markerDir.empty()) {
markerDir = getCurrentTimestamp();
}
@@ -350,8 +373,8 @@ public:
{
try {
// 计算相对更新目录的路径
fs::path relPath = fs::relative(record.target, updateDir);
fs::path backupPath = backupDir / markerDir / relPath;
// fs::path relPath = fs::relative(record.target, updateDir);
fs::path backupPath = backupDir / markerDir / record.backupRelative;
// 创建目标目录
fs::create_directories(backupPath.parent_path());
@@ -360,8 +383,30 @@ public:
fs::copy(record.target, backupPath, fs::copy_options::overwrite_existing);
logger->debug("已备份: {} -> {}", record.target.string(), backupPath.string());
if (!verify_) {
return true;
}
// 校验MD5
auto hashSrc = md5_.hash_file(record.target.string());
std::string hashBk;
if (fs::is_directory(backupPath)) {
hashBk = md5_.hash_file(fs::path(backupPath).append(fs::path(record.target).filename().string()).string());
} else {
hashBk = md5_.hash_file(backupPath.string());
}
if (hashBk == hashSrc) {
logger->info("==> Hash验证已通过。[{}]", hashSrc);
} else {
logger->error("==> Hash验证未通过。[{}][{}]", hashSrc, hashBk);
return false;
}
return true;
} catch (const fs::filesystem_error& e) {
// logger->error("备份失败: {} - {}", record.target.string(), zoostCommon::ToU8Copy(e.what()));
logger->error("备份失败: {} - {}", record.target.string(), e.what());
return false;
}
@@ -403,7 +448,8 @@ public:
if (backupFile(record)) {
backupCount++;
} else {
logger->warn("备份失败,但继续执行更新");
logger->warn("备份失败...,请检查,停止更新动作...");
return false;
}
}
}