mirror of
https://git.citron-emu.org/citron/emulator
synced 2025-12-19 10:43:33 +00:00
Fix Windows auto updater with deferred update helper and TLS support
Windows auto updater failed due to: 1. File locking - can't overwrite running .exe files 2. Missing Qt 6 TLS plugins - can't connect via HTTPS Solution: - Implement helper batch script that applies updates after app exits - Automate TLS plugin copying in CMake (qschannelbackend.dll, qopensslbackend.dll) - Add enhanced SSL debugging and error messages Windows updates now work. Linux continues to work as before. Signed-off-by: Zephyron <zephyron@citron-emu.org>
This commit is contained in:
@@ -512,6 +512,38 @@ if (WIN32 AND QT_VERSION VERSION_GREATER_EQUAL 6)
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${CITRON_EXE_DIR}/user"
|
||||
COMMENT "Creating portable user directory"
|
||||
)
|
||||
|
||||
# Copy Qt TLS plugins for SSL/TLS support (required for auto updater and HTTPS)
|
||||
# Qt 6 uses a plugin architecture for TLS backends
|
||||
if (CITRON_USE_AUTO_UPDATER OR ENABLE_OPENSSL)
|
||||
set(Qt6_TLS_PLUGINS_DIR "${Qt6_DIR}/../../../plugins/tls")
|
||||
|
||||
# Create tls directory
|
||||
add_custom_command(TARGET citron POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${CITRON_EXE_DIR}/tls"
|
||||
COMMENT "Creating TLS plugin directory for SSL support"
|
||||
)
|
||||
|
||||
# Copy Windows native Schannel backend (no external dependencies)
|
||||
if (EXISTS "${Qt6_TLS_PLUGINS_DIR}/qschannelbackend.dll")
|
||||
add_custom_command(TARGET citron POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${Qt6_TLS_PLUGINS_DIR}/qschannelbackend.dll"
|
||||
"${CITRON_EXE_DIR}/tls/qschannelbackend.dll"
|
||||
COMMENT "Copying Qt Schannel TLS plugin (Windows native SSL)"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Copy OpenSSL backend as fallback (requires OpenSSL DLLs)
|
||||
if (EXISTS "${Qt6_TLS_PLUGINS_DIR}/qopensslbackend.dll")
|
||||
add_custom_command(TARGET citron POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${Qt6_TLS_PLUGINS_DIR}/qopensslbackend.dll"
|
||||
"${CITRON_EXE_DIR}/tls/qopensslbackend.dll"
|
||||
COMMENT "Copying Qt OpenSSL TLS plugin (fallback)"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (CITRON_USE_BUNDLED_QT)
|
||||
|
||||
@@ -83,10 +83,27 @@ UpdaterService::~UpdaterService() {
|
||||
|
||||
void UpdaterService::InitializeSSL() {
|
||||
LOG_INFO(Frontend, "Attempting to initialize SSL support...");
|
||||
|
||||
// Check if SSL is supported
|
||||
if (!QSslSocket::supportsSsl()) {
|
||||
LOG_WARNING(Frontend, "SSL support not available");
|
||||
LOG_WARNING(Frontend, "Build-time SSL version: {}", QSslSocket::sslLibraryBuildVersionString().toStdString());
|
||||
LOG_WARNING(Frontend, "Runtime SSL version: {}", QSslSocket::sslLibraryVersionString().toStdString());
|
||||
|
||||
#ifdef _WIN32
|
||||
// Try to provide helpful information about missing DLLs
|
||||
std::filesystem::path app_dir = std::filesystem::path(QCoreApplication::applicationDirPath().toStdString());
|
||||
std::filesystem::path crypto_dll = app_dir / "libcrypto-3-x64.dll";
|
||||
std::filesystem::path ssl_dll = app_dir / "libssl-3-x64.dll";
|
||||
|
||||
LOG_WARNING(Frontend, "libcrypto-3-x64.dll exists: {}", std::filesystem::exists(crypto_dll));
|
||||
LOG_WARNING(Frontend, "libssl-3-x64.dll exists: {}", std::filesystem::exists(ssl_dll));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(Frontend, "SSL library version: {}", QSslSocket::sslLibraryVersionString().toStdString());
|
||||
|
||||
QSslConfiguration sslConfig = QSslConfiguration::defaultConfiguration();
|
||||
auto certs = QSslConfiguration::systemCaCertificates();
|
||||
if (!certs.isEmpty()) {
|
||||
@@ -612,9 +629,11 @@ bool UpdaterService::LaunchUpdateHelper() {
|
||||
// Launch the batch script as a detached process
|
||||
QString script_path_str = QString::fromStdString(script_path.string());
|
||||
QStringList arguments;
|
||||
arguments << QStringLiteral("/C");
|
||||
arguments << script_path_str;
|
||||
|
||||
// Use cmd.exe to run the batch file in a hidden window
|
||||
bool launched = QProcess::startDetached("cmd.exe", QStringList() << "/C" << script_path_str);
|
||||
bool launched = QProcess::startDetached(QStringLiteral("cmd.exe"), arguments);
|
||||
|
||||
if (launched) {
|
||||
LOG_INFO(Frontend, "Update helper script launched successfully");
|
||||
|
||||
@@ -53,6 +53,10 @@ public:
|
||||
static bool HasStagedUpdate(const std::filesystem::path& app_directory);
|
||||
static bool ApplyStagedUpdate(const std::filesystem::path& app_directory);
|
||||
|
||||
#ifdef _WIN32
|
||||
bool LaunchUpdateHelper();
|
||||
#endif
|
||||
|
||||
signals:
|
||||
void UpdateCheckCompleted(bool has_update, const UpdateInfo& update_info);
|
||||
void UpdateDownloadProgress(int percentage, qint64 bytes_received, qint64 bytes_total);
|
||||
@@ -80,7 +84,6 @@ private:
|
||||
bool CreateBackup();
|
||||
bool RestoreBackup();
|
||||
bool CreateUpdateHelperScript(const std::filesystem::path& staging_path);
|
||||
bool LaunchUpdateHelper();
|
||||
#endif
|
||||
bool CleanupFiles();
|
||||
std::filesystem::path GetTempDirectory() const;
|
||||
|
||||
@@ -49,8 +49,14 @@ add_library(core STATIC
|
||||
file_sys/common_funcs.h
|
||||
file_sys/content_archive.cpp
|
||||
file_sys/content_archive.h
|
||||
file_sys/content_exporter.cpp
|
||||
file_sys/content_exporter.h
|
||||
file_sys/control_metadata.cpp
|
||||
file_sys/control_metadata.h
|
||||
file_sys/decrypted_nsp.cpp
|
||||
file_sys/decrypted_nsp.h
|
||||
file_sys/decrypted_xci.cpp
|
||||
file_sys/decrypted_xci.h
|
||||
file_sys/errors.h
|
||||
file_sys/fs_directory.h
|
||||
file_sys/fs_file.h
|
||||
@@ -1183,10 +1189,14 @@ add_library(core STATIC
|
||||
loader/nca.h
|
||||
loader/nro.cpp
|
||||
loader/nro.h
|
||||
loader/nsd.cpp
|
||||
loader/nsd.h
|
||||
loader/nso.cpp
|
||||
loader/nso.h
|
||||
loader/nsp.cpp
|
||||
loader/nsp.h
|
||||
loader/xcd.cpp
|
||||
loader/xcd.h
|
||||
loader/xci.cpp
|
||||
loader/xci.h
|
||||
memory.cpp
|
||||
|
||||
Reference in New Issue
Block a user