202 lines
6.7 KiB
C++
Raw Normal View History

2026-01-16 01:04:43 +08:00
#include <QCoreApplication>
#include <QCommandLineParser>
#include <QFile>
#include <QFileInfo>
#include <QDir>
#include <QTextStream>
#include <iostream>
#include "ConfigEncryption.h"
// 打印到控制台(支持中文)
void printConsole(const QString& message)
{
#ifdef _WIN32
// Windows 控制台输出
std::wcout << message.toStdWString() << std::endl;
#else
std::cout << message.toStdString() << std::endl;
#endif
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
app.setApplicationName("ConfigDecryptor");
app.setApplicationVersion("1.0.0");
// 设置控制台输出编码Windows
#ifdef _WIN32
system("chcp 65001 > nul");
#endif
// 命令行参数解析
QCommandLineParser parser;
parser.setApplicationDescription("配置文件解密工具 - 用于解密 config.encrypt 文件");
parser.addHelpOption();
parser.addVersionOption();
// 添加位置参数:加密文件路径
parser.addPositionalArgument("file", "要解密的 config.encrypt 文件路径");
// 添加密钥选项
QCommandLineOption keyOption(QStringList() << "k" << "key",
"解密密钥格式AppName + VisionRobot",
"key");
parser.addOption(keyOption);
// 添加输出路径选项(可选)
QCommandLineOption outputOption(QStringList() << "o" << "output",
"输出文件路径(默认:与加密文件同级目录下的 config.xml",
"output");
parser.addOption(outputOption);
// 添加静默模式选项
QCommandLineOption silentOption(QStringList() << "s" << "silent",
"静默模式(不显示详细信息)");
parser.addOption(silentOption);
// 解析命令行参数
parser.process(app);
bool silent = parser.isSet(silentOption);
// 显示欢迎信息
if (!silent) {
printConsole("========================================");
printConsole(" 配置文件解密工具 v1.0.0");
printConsole(" Config Decryptor for VisionRobot");
printConsole("========================================");
printConsole("");
}
// 获取位置参数
QStringList args = parser.positionalArguments();
if (args.isEmpty()) {
printConsole("错误:未指定要解密的文件路径");
printConsole("");
parser.showHelp(1);
return 1;
}
QString encryptedFilePath = args.at(0);
// 检查文件是否存在
QFileInfo fileInfo(encryptedFilePath);
if (!fileInfo.exists()) {
printConsole(QString("错误:文件不存在: %1").arg(encryptedFilePath));
return 1;
}
if (!fileInfo.isFile()) {
printConsole(QString("错误:指定的路径不是文件: %1").arg(encryptedFilePath));
return 1;
}
// 获取密钥
QString key = parser.value(keyOption);
if (key.isEmpty()) {
printConsole("错误:未指定解密密钥");
printConsole("请使用 -k 或 --key 选项指定密钥");
printConsole("密钥格式:应用程序名称 + \"VisionRobot\"");
printConsole("");
printConsole("示例:");
printConsole(" GrabBagApp 的密钥为: GrabBagAppVisionRobot");
printConsole(" LapWeldApp 的密钥为: LapWeldAppVisionRobot");
printConsole("");
parser.showHelp(1);
return 1;
}
// 确定输出路径
QString outputFilePath;
if (parser.isSet(outputOption)) {
outputFilePath = parser.value(outputOption);
} else {
// 默认输出到同级目录下的 config.xml
QDir fileDir = fileInfo.absoluteDir();
outputFilePath = fileDir.absoluteFilePath("config.xml");
}
if (!silent) {
printConsole(QString("加密文件: %1").arg(fileInfo.absoluteFilePath()));
printConsole(QString("输出文件: %1").arg(outputFilePath));
printConsole(QString("解密密钥: %1").arg(key));
printConsole("");
printConsole("开始解密...");
}
// 读取加密文件
QFile encryptedFile(encryptedFilePath);
if (!encryptedFile.open(QIODevice::ReadOnly)) {
printConsole(QString("错误:无法打开加密文件: %1").arg(encryptedFilePath));
return 1;
}
QByteArray encryptedData = encryptedFile.readAll();
encryptedFile.close();
if (encryptedData.isEmpty()) {
printConsole("错误:加密文件为空");
return 1;
}
// 验证文件格式
if (!encryptedData.startsWith("VRENC1.0")) {
printConsole("警告:文件格式不匹配,可能不是有效的加密配置文件");
printConsole("是否继续尝试解密?(Y/N)");
char response;
std::cin >> response;
if (response != 'Y' && response != 'y') {
printConsole("操作已取消");
return 0;
}
}
// 解密数据
QByteArray decryptedData = ConfigEncryption::DecryptConfig(encryptedData, key);
if (decryptedData.isEmpty()) {
printConsole("错误:解密失败!");
printConsole("可能的原因:");
printConsole(" 1. 密钥错误");
printConsole(" 2. 文件已损坏");
printConsole(" 3. 文件格式不正确");
return 1;
}
// 写入解密后的文件
QFile outputFile(outputFilePath);
if (!outputFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
printConsole(QString("错误:无法创建输出文件: %1").arg(outputFilePath));
return 1;
}
qint64 written = outputFile.write(decryptedData);
outputFile.close();
if (written != decryptedData.size()) {
printConsole("错误:写入输出文件失败");
return 1;
}
// 成功
if (!silent) {
printConsole("");
printConsole("========================================");
printConsole(" 解密成功!");
printConsole("========================================");
printConsole(QString("解密后的文件已保存到: %1").arg(outputFilePath));
printConsole(QString("文件大小: %1 字节").arg(decryptedData.size()));
printConsole("");
printConsole("提示:");
printConsole(" 修改配置后,重新启动应用程序将自动重新加密配置文件。");
printConsole(" 原始加密文件将被更新config.xml 将被删除。");
printConsole("");
} else {
printConsole("解密成功");
}
return 0;
}