feat(hardening): 内嵌产品配置 + 系统级状态 + 全量 i18n + 依赖治理 + 资料清理
update-client-hardening 四工作流合入(构建/静态检查已过): - 配置:不可变产品策略经 UpdateClientResources.cmake 归一化校验后 内嵌 qrc(URL/相对路径/主程序必须落 install_root/版本/UUID 格式, CMake override 写入前复验);可变机器状态迁系统级原生存储; 运行目录不再落可编辑 app_config.json。 - i18n:生产源全英文(no-Han 检查 41/41),中文进 translations/ zh_CN 目录;翻译加载收敛 Common/TranslationHelper 唯一入口; Bootstrap 补资源文件。 - 依赖:Qt/OpenSSL/架构/Perl 机器路径改 imported targets + UpdateClientDependencies.cmake,3rdparty 由父工程契约供给。 - 清理:旧 README/SDK README/3 个重复 PowerShell 打包脚本/PDF 提取 文本删除,canonical README + 5 份结构化英文文档替代;Launcher requireAdministrator manifest;统一 MSVC /utf-8 删运行时编码设置。
This commit is contained in:
@@ -1,6 +1,19 @@
|
||||
project(Bootstrap LANGUAGES CXX)
|
||||
set(_bootstrap_sources main.cpp)
|
||||
if(WIN32)
|
||||
file(GLOB _bootstrap_resource_files CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/*.rc")
|
||||
list(APPEND _bootstrap_sources ${_bootstrap_resource_files})
|
||||
endif()
|
||||
|
||||
add_executable(Bootstrap WIN32 main.cpp)
|
||||
add_executable(Bootstrap ${_bootstrap_sources})
|
||||
target_compile_features(Bootstrap PRIVATE cxx_std_17)
|
||||
target_compile_definitions(Bootstrap PRIVATE UNICODE _UNICODE)
|
||||
target_link_libraries(Bootstrap PRIVATE shell32)
|
||||
set_target_properties(Bootstrap PROPERTIES
|
||||
AUTOMOC OFF
|
||||
AUTOUIC OFF
|
||||
AUTORCC OFF
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set_target_properties(Bootstrap PROPERTIES WIN32_EXECUTABLE TRUE)
|
||||
target_compile_definitions(Bootstrap PRIVATE UNICODE _UNICODE)
|
||||
target_link_libraries(Bootstrap PRIVATE shell32)
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma code_page(65001)
|
||||
|
||||
#include <windows.h>
|
||||
#include "resource.h"
|
||||
|
||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_BOOTSTRAP_ERROR_TITLE "Update handoff failed"
|
||||
IDS_BOOTSTRAP_ARGUMENTS_INCOMPLETE "Bootstrap arguments are incomplete."
|
||||
IDS_BOOTSTRAP_INVALID_PLAN_OPERATION "The update plan contains an invalid operation."
|
||||
IDS_BOOTSTRAP_UNSAFE_PLAN_PATH "The update plan contains an unsafe path."
|
||||
IDS_BOOTSTRAP_RESTART_UPDATER_FAILED "Updater.exe could not be restarted."
|
||||
IDS_BOOTSTRAP_FAILED_FILE_PREFIX "Failed file: "
|
||||
END
|
||||
|
||||
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_BOOTSTRAP_ERROR_TITLE "更新接管失败"
|
||||
IDS_BOOTSTRAP_ARGUMENTS_INCOMPLETE "Bootstrap 参数不完整。"
|
||||
IDS_BOOTSTRAP_INVALID_PLAN_OPERATION "更新计划操作格式无效。"
|
||||
IDS_BOOTSTRAP_UNSAFE_PLAN_PATH "更新计划包含不安全路径。"
|
||||
IDS_BOOTSTRAP_RESTART_UPDATER_FAILED "无法重新启动 Updater.exe。"
|
||||
IDS_BOOTSTRAP_FAILED_FILE_PREFIX "失败文件:"
|
||||
END
|
||||
+24
-6
@@ -1,5 +1,6 @@
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
#include "resource.h"
|
||||
#include <filesystem>
|
||||
#include <chrono>
|
||||
#include <cstdlib>
|
||||
@@ -10,6 +11,21 @@
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
static std::wstring loadLocalizedString(unsigned int id)
|
||||
{
|
||||
const wchar_t* value = nullptr;
|
||||
const int length = LoadStringW(GetModuleHandleW(nullptr), id,
|
||||
reinterpret_cast<LPWSTR>(&value), 0);
|
||||
return length > 0 ? std::wstring(value, static_cast<size_t>(length)) : std::wstring();
|
||||
}
|
||||
|
||||
static void showBootstrapError(unsigned int messageId)
|
||||
{
|
||||
const std::wstring message = loadLocalizedString(messageId);
|
||||
const std::wstring title = loadLocalizedString(IDS_BOOTSTRAP_ERROR_TITLE);
|
||||
MessageBoxW(nullptr, message.c_str(), title.c_str(), MB_ICONERROR);
|
||||
}
|
||||
|
||||
static std::wstring quote(const std::wstring& value)
|
||||
{
|
||||
std::wstring result = L"\"";
|
||||
@@ -115,7 +131,7 @@ int WINAPI wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
|
||||
int argc = 0;
|
||||
LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
if (!argv || argc < 11) {
|
||||
MessageBoxW(nullptr, L"Bootstrap 参数不完整。", L"更新接管失败", MB_ICONERROR);
|
||||
showBootstrapError(IDS_BOOTSTRAP_ARGUMENTS_INCOMPLETE);
|
||||
if (argv) LocalFree(argv);
|
||||
return 2;
|
||||
}
|
||||
@@ -142,12 +158,12 @@ int WINAPI wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
|
||||
while (std::getline(input, line)) {
|
||||
if (!line.empty() && line.back() == '\r') line.pop_back();
|
||||
if (line.size() < 3 || line[1] != '\t' || (line[0] != 'C' && line[0] != 'D')) {
|
||||
MessageBoxW(nullptr, L"更新计划操作格式无效。", L"更新接管失败", MB_ICONERROR);
|
||||
showBootstrapError(IDS_BOOTSTRAP_INVALID_PLAN_OPERATION);
|
||||
return 3;
|
||||
}
|
||||
const fs::path relative(fromUtf8(line.substr(2)));
|
||||
if (!safeRelative(relative)) {
|
||||
MessageBoxW(nullptr, L"更新计划包含不安全路径。", L"更新接管失败", MB_ICONERROR);
|
||||
showBootstrapError(IDS_BOOTSTRAP_UNSAFE_PLAN_PATH);
|
||||
return 3;
|
||||
}
|
||||
items.push_back({static_cast<wchar_t>(line[0]), relative});
|
||||
@@ -182,9 +198,11 @@ int WINAPI wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
|
||||
|
||||
const std::wstring result = success ? L"success" : (rolledBack ? L"rolledback" : L"rollback-failed");
|
||||
if (!launchUpdater(updater, updateArgs, result)) {
|
||||
std::wstring message = L"无法重新启动 Updater.exe。";
|
||||
if (!failedPath.empty()) message += L"\n失败文件:" + failedPath.wstring();
|
||||
MessageBoxW(nullptr, message.c_str(), L"更新接管失败", MB_ICONERROR);
|
||||
std::wstring message = loadLocalizedString(IDS_BOOTSTRAP_RESTART_UPDATER_FAILED);
|
||||
if (!failedPath.empty())
|
||||
message += L"\n" + loadLocalizedString(IDS_BOOTSTRAP_FAILED_FILE_PREFIX) + failedPath.wstring();
|
||||
const std::wstring title = loadLocalizedString(IDS_BOOTSTRAP_ERROR_TITLE);
|
||||
MessageBoxW(nullptr, message.c_str(), title.c_str(), MB_ICONERROR);
|
||||
return 4;
|
||||
}
|
||||
return (success || rolledBack) ? 0 : 5;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#define IDS_BOOTSTRAP_ERROR_TITLE 1000
|
||||
#define IDS_BOOTSTRAP_ARGUMENTS_INCOMPLETE 1001
|
||||
#define IDS_BOOTSTRAP_INVALID_PLAN_OPERATION 1002
|
||||
#define IDS_BOOTSTRAP_UNSAFE_PLAN_PATH 1003
|
||||
#define IDS_BOOTSTRAP_RESTART_UPDATER_FAILED 1004
|
||||
#define IDS_BOOTSTRAP_FAILED_FILE_PREFIX 1005
|
||||
Reference in New Issue
Block a user