From ec5a481d85a6b903807cc8451b4744cd89c087fc Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Sat, 27 May 2023 22:34:26 +0200 Subject: [PATCH 1/3] New config & data defaults + migration impl --- include/general_config_file.h | 2 + src/bottle_manager.cc | 391 ++++++++++++++++++---------------- src/general_config_file.cc | 151 ++++++++++++- src/helper.cc | 25 ++- 4 files changed, 365 insertions(+), 204 deletions(-) diff --git a/include/general_config_file.h b/include/general_config_file.h index b29196b..896cc30 100644 --- a/include/general_config_file.h +++ b/include/general_config_file.h @@ -40,4 +40,6 @@ private: ~GeneralConfigFile(); GeneralConfigFile(const GeneralConfigFile&) = delete; GeneralConfigFile& operator=(const GeneralConfigFile&) = delete; + + static std::string config_and_folder_migration(const std::string& config_file_path_new, const std::string& default_prefix_folder_new); }; diff --git a/src/bottle_manager.cc b/src/bottle_manager.cc index de35b48..a68c56c 100644 --- a/src/bottle_manager.cc +++ b/src/bottle_manager.cc @@ -585,21 +585,23 @@ void BottleManager::run_executable(string filename, bool is_msi_file = false) string program_prefix = is_msi_file ? "msiexec /i" : "start /unix"; // Be-sure to execute the filename also between quotes (due to spaces) string program = program_prefix + " \"" + filename + "\""; - std::thread t([wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), - debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), - logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), - write_log_dispatcher = &write_log_dispatcher_] { - string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, program, true, logging_stderr); - if (debug_logging && !output.empty()) - { + std::thread t( + [wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), + debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), + logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), + write_log_dispatcher = &write_log_dispatcher_] { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - }); + string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, program, true, logging_stderr); + if (debug_logging && !output.empty()) + { + { + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + }); t.detach(); } } @@ -620,41 +622,44 @@ void BottleManager::run_program(string program) { // Between quotes (due to spaces) program = "\"" + program + "\""; - std::thread t([wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), - debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), - logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), - write_log_dispatcher = &write_log_dispatcher_] { - string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, program, true, logging_stderr); - if (debug_logging && !output.empty()) - { + std::thread t( + [wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), + debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), + logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), + write_log_dispatcher = &write_log_dispatcher_] { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - }); + string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, program, true, logging_stderr); + if (debug_logging && !output.empty()) + { + { + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + }); t.detach(); } else { // We have an exception for winetricks, since that doesn't need the wine command - std::thread t([wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), - debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), - logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), - write_log_dispatcher = &write_log_dispatcher_] { - string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); - if (debug_logging && !output.empty()) - { + std::thread t( + [wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), + output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), + output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_] { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - }); + string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); + if (debug_logging && !output.empty()) + { + { + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + }); t.detach(); } } @@ -684,21 +689,23 @@ void BottleManager::reboot() string wine_prefix = active_bottle_->wine_location(); bool is_debug_logging = active_bottle_->is_debug_logging(); int debug_log_level = active_bottle_->debug_log_level(); - std::thread t([wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, logging_stderr = std::move(is_logging_stderr_), - debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), - logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), - write_log_dispatcher = &write_log_dispatcher_] { - string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, "wineboot -r", true, logging_stderr); - if (debug_logging && !output.empty()) - { + std::thread t( + [wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, logging_stderr = std::move(is_logging_stderr_), + debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), + logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), + write_log_dispatcher = &write_log_dispatcher_] { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - }); + string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, "wineboot -r", true, logging_stderr); + if (debug_logging && !output.empty()) + { + { + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + }); t.detach(); main_window_.show_info_message("Machine emulate reboot requested."); } @@ -714,24 +721,26 @@ void BottleManager::update() string wine_prefix = active_bottle_->wine_location(); bool is_debug_logging = active_bottle_->is_debug_logging(); int debug_log_level = active_bottle_->debug_log_level(); - std::thread t([wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, update_bottles_dispatcher = &update_bottles_dispatcher_, - logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), - output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), - output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_] { - string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, "wineboot -u", true, logging_stderr); - if (debug_logging && !output.empty()) - { + std::thread t( + [wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, update_bottles_dispatcher = &update_bottles_dispatcher_, + logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), + output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), + output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_] { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - Helper::wait_until_wineserver_is_terminated(wine_prefix); - // Emit update bottles (via dispatcher, so the GUI update can take place in the GUI thread) - update_bottles_dispatcher->emit(); - }); + string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, "wineboot -u", true, logging_stderr); + if (debug_logging && !output.empty()) + { + { + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + Helper::wait_until_wineserver_is_terminated(wine_prefix); + // Emit update bottles (via dispatcher, so the GUI update can take place in the GUI thread) + update_bottles_dispatcher->emit(); + }); t.detach(); } } @@ -770,21 +779,23 @@ void BottleManager::kill_processes() string wine_prefix = active_bottle_->wine_location(); bool is_debug_logging = active_bottle_->is_debug_logging(); int debug_log_level = active_bottle_->debug_log_level(); - std::thread t([wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, logging_stderr = std::move(is_logging_stderr_), - debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), - logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), - write_log_dispatcher = &write_log_dispatcher_] { - string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, "wineboot -k", true, logging_stderr); - if (debug_logging && !output.empty()) - { + std::thread t( + [wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, logging_stderr = std::move(is_logging_stderr_), + debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), + logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), + write_log_dispatcher = &write_log_dispatcher_] { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - }); + string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, "wineboot -k", true, logging_stderr); + if (debug_logging && !output.empty()) + { + { + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + }); t.detach(); main_window_.show_info_message("Kill processes requested."); } @@ -812,23 +823,25 @@ void BottleManager::install_d3dx9(Gtk::Window& parent, const string& version) int debug_log_level = active_bottle_->debug_log_level(); string program = Helper::get_winetricks_location() + " -q " + package; // finished_package_install_dispatcher signal is needed in order to close the busy dialog again - std::thread t([wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), - output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), - output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, - finish_dispatcher = &finished_package_install_dispatcher] { - string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); - if (debug_logging && !output.empty()) - { + std::thread t( + [wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), + output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), + output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, + finish_dispatcher = &finished_package_install_dispatcher] { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - Helper::wait_until_wineserver_is_terminated(wine_prefix); - finish_dispatcher->emit(); - }); + string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); + if (debug_logging && !output.empty()) + { + { + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + Helper::wait_until_wineserver_is_terminated(wine_prefix); + finish_dispatcher->emit(); + }); t.detach(); } } @@ -856,23 +869,25 @@ void BottleManager::install_dxvk(Gtk::Window& parent, const string& version) int debug_log_level = active_bottle_->debug_log_level(); string program = Helper::get_winetricks_location() + " -q " + package; // finished_package_install_dispatcher signal is needed in order to close the busy dialog again - std::thread t([wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), - output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), - output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, - finish_dispatcher = &finished_package_install_dispatcher] { - string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); - if (debug_logging && !output.empty()) - { + std::thread t( + [wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), + output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), + output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, + finish_dispatcher = &finished_package_install_dispatcher] { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - Helper::wait_until_wineserver_is_terminated(wine_prefix); - finish_dispatcher->emit(); - }); + string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); + if (debug_logging && !output.empty()) + { + { + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + Helper::wait_until_wineserver_is_terminated(wine_prefix); + finish_dispatcher->emit(); + }); t.detach(); } } @@ -895,23 +910,25 @@ void BottleManager::install_visual_cpp_package(Gtk::Window& parent, const string int debug_log_level = active_bottle_->debug_log_level(); string program = Helper::get_winetricks_location() + " -q " + package; // finished_package_install_dispatcher signal is needed in order to close the busy dialog again - std::thread t([wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), - output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), - output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, - finish_dispatcher = &finished_package_install_dispatcher] { - string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); - if (debug_logging && !output.empty()) - { + std::thread t( + [wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), + output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), + output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, + finish_dispatcher = &finished_package_install_dispatcher] { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - Helper::wait_until_wineserver_is_terminated(wine_prefix); - finish_dispatcher->emit(); - }); + string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); + if (debug_logging && !output.empty()) + { + { + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + Helper::wait_until_wineserver_is_terminated(wine_prefix); + finish_dispatcher->emit(); + }); t.detach(); } } @@ -953,23 +970,25 @@ void BottleManager::install_dot_net(Gtk::Window& parent, const string& version) program = install_command; } // finished_package_install_dispatcher signal is needed in order to close the busy dialog again - std::thread t([wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), - debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), - logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), - write_log_dispatcher = &write_log_dispatcher_, finish_dispatcher = &finished_package_install_dispatcher] { - string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); - if (debug_logging && !output.empty()) - { + std::thread t( + [wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), + output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), + output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, + finish_dispatcher = &finished_package_install_dispatcher] { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - Helper::wait_until_wineserver_is_terminated(wine_prefix); - finish_dispatcher->emit(); - }); + string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); + if (debug_logging && !output.empty()) + { + { + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + Helper::wait_until_wineserver_is_terminated(wine_prefix); + finish_dispatcher->emit(); + }); t.detach(); } else @@ -995,23 +1014,25 @@ void BottleManager::install_core_fonts(Gtk::Window& parent) int debug_log_level = active_bottle_->debug_log_level(); string program = Helper::get_winetricks_location() + " -q corefonts"; // finished_package_install_dispatcher signal is needed in order to close the busy dialog again - std::thread t([wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), - output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), - output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, - finish_dispatcher = &finished_package_install_dispatcher] { - string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); - if (debug_logging && !output.empty()) - { + std::thread t( + [wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), + output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), + output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, + finish_dispatcher = &finished_package_install_dispatcher] { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - Helper::wait_until_wineserver_is_terminated(wine_prefix); - finish_dispatcher->emit(); - }); + string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); + if (debug_logging && !output.empty()) + { + { + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + Helper::wait_until_wineserver_is_terminated(wine_prefix); + finish_dispatcher->emit(); + }); t.detach(); } } @@ -1032,23 +1053,25 @@ void BottleManager::install_liberation(Gtk::Window& parent) int debug_log_level = active_bottle_->debug_log_level(); string program = Helper::get_winetricks_location() + " -q liberation"; // finished_package_install_dispatcher signal is needed in order to close the busy dialog again - std::thread t([wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), - output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), - output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, - finish_dispatcher = &finished_package_install_dispatcher] { - string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); - if (debug_logging && !output.empty()) - { + std::thread t( + [wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), + output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), + output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, + finish_dispatcher = &finished_package_install_dispatcher] { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - Helper::wait_until_wineserver_is_terminated(wine_prefix); - finish_dispatcher->emit(); - }); + string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); + if (debug_logging && !output.empty()) + { + { + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + Helper::wait_until_wineserver_is_terminated(wine_prefix); + finish_dispatcher->emit(); + }); t.detach(); } } @@ -1140,7 +1163,7 @@ std::vector BottleManager::get_bottle_paths() { if (!Helper::dir_exists(bottle_location_)) { - // Create directory if not exist yet + // Create bottle prefix directory if not exist yet if (!Helper::create_dir(bottle_location_)) { throw std::runtime_error("Failed to create the Wine bottle directory: " + bottle_location_); diff --git a/src/general_config_file.cc b/src/general_config_file.cc index 2154c4a..4e3de43 100644 --- a/src/general_config_file.cc +++ b/src/general_config_file.cc @@ -19,6 +19,7 @@ * along with this program. If not, see . */ #include "general_config_file.h" +#include #include #include @@ -46,16 +47,18 @@ bool GeneralConfigFile::write_config_file(const GeneralConfigData& general_confi { bool success = false; Glib::KeyFile keyfile; - std::vector config_dirs{Glib::get_home_dir(), ".winegui"}; + // Verify: No need to check the old location, since read_config_file() should already + // migrated the config file to the new location during start-up. + std::vector config_dirs{Glib::get_user_config_dir(), "winegui"}; std::string config_location = Glib::build_path(G_DIR_SEPARATOR_S, config_dirs); - std::string file_path = Glib::build_filename(config_location, "config.ini"); + std::string config_file_path = Glib::build_filename(config_location, "config.ini"); try { keyfile.set_string("General", "DefaultFolder", general_config.default_folder); keyfile.set_boolean("General", "DisplayDefaultWineMachine", general_config.display_default_wine_machine); keyfile.set_boolean("General", "PreferWine64", general_config.prefer_wine64); keyfile.set_boolean("General", "EnableLoggingStderr", general_config.enable_logging_stderr); - success = keyfile.save_to_file(file_path); + success = keyfile.save_to_file(config_file_path); } catch (const Glib::Error& ex) { @@ -72,22 +75,34 @@ bool GeneralConfigFile::write_config_file(const GeneralConfigData& general_confi GeneralConfigData GeneralConfigFile::read_config_file() { Glib::KeyFile keyfile; - std::vector config_dirs{Glib::get_home_dir(), ".winegui"}; + std::vector config_dirs{Glib::get_user_config_dir(), "winegui"}; std::string config_location = Glib::build_path(G_DIR_SEPARATOR_S, config_dirs); - std::string file_path = Glib::build_filename(config_location, "config.ini"); - - std::vector prefix_dirs{Glib::get_home_dir(), ".winegui", "prefixes"}; + std::string config_file_path = Glib::build_filename(config_location, "config.ini"); + std::vector prefix_dirs{Glib::get_user_data_dir(), "winegui", "prefixes"}; std::string default_prefix_folder = Glib::build_path(G_DIR_SEPARATOR_S, prefix_dirs); + // Check if config folder directory exists + if (!Glib::file_test(config_location, Glib::FileTest::FILE_TEST_IS_DIR)) + { + // Directory doesn't exists, make new config directory (incl. parents) + Glib::RefPtr directory = Gio::File::create_for_path(config_location); + if (directory) + directory->make_directory_with_parents(); + } + + // Execute migration (if required) + // Returns the default prefix folder, depending if there are bottles found in the old prefix location + std::string final_default_prefix_folder = config_and_folder_migration(config_file_path, default_prefix_folder); + struct GeneralConfigData general_config; // Defaults config values - general_config.default_folder = default_prefix_folder; + general_config.default_folder = final_default_prefix_folder; general_config.display_default_wine_machine = true; general_config.prefer_wine64 = false; general_config.enable_logging_stderr = true; // Check if config file exists - if (!Glib::file_test(file_path, Glib::FileTest::FILE_TEST_IS_REGULAR)) + if (!Glib::file_test(config_file_path, Glib::FileTest::FILE_TEST_IS_REGULAR)) { // Config file doesn't exist, make a new file with default configs, return default config data below GeneralConfigFile::write_config_file(general_config); @@ -97,7 +112,7 @@ GeneralConfigData GeneralConfigFile::read_config_file() // Config file exists try { - keyfile.load_from_file(file_path); + keyfile.load_from_file(config_file_path); general_config.default_folder = keyfile.get_string("General", "DefaultFolder"); general_config.display_default_wine_machine = keyfile.get_boolean("General", "DisplayDefaultWineMachine"); general_config.prefer_wine64 = keyfile.get_boolean("General", "PreferWine64"); @@ -112,3 +127,119 @@ GeneralConfigData GeneralConfigFile::read_config_file() } return general_config; } + +/** + * \brief Migration code from old to new location. + * \param config_file_path_new The new config file path + * \param default_prefix_folder_new The new prefix folder location + * \return The final default bottle prefix folder location + */ +std::string GeneralConfigFile::config_and_folder_migration(const std::string& config_file_path_new, const std::string& default_prefix_folder_new) +{ + std::string final_default_prefix_folder = default_prefix_folder_new; // set default prefix folder first + + // For migration we search for the existing config file first, + // if needed we move the config file to the new location (without any user impact) + std::vector config_dirs_old{Glib::get_home_dir(), ".winegui"}; + std::string config_location_old = Glib::build_path(G_DIR_SEPARATOR_S, config_dirs_old); + std::string config_file_path_old = Glib::build_filename(config_location_old, "config.ini"); + // Also define old Winetricks binary file path + std::string winetricks_file_path_old = Glib::build_filename(config_location_old, "winetricks"); + std::string winetricks_file_path_bak_old = Glib::build_filename(config_location_old, "winetricks.bak"); + + // For the prefix location, we first check if the old location exists and contains any + // bottles, if so, we keep using the old location. + // Rationale: We can't just copy existing bottles to the new location, this might break shortcuts. + // However, if the old location is un-used, we use the new location (which is the new default). + std::vector prefix_dirs_old{Glib::get_home_dir(), ".winegui", "prefixes"}; + std::string default_prefix_folder_old = Glib::build_path(G_DIR_SEPARATOR_S, prefix_dirs_old); + + // Check if old config directory (~/.winegui) still exists + if (Glib::file_test(config_location_old, Glib::FileTest::FILE_TEST_IS_DIR)) + { + // Check on old config.ini file + if (Glib::file_test(config_file_path_old, Glib::FileTest::FILE_TEST_IS_REGULAR)) + { + try + { + // Move the existing config file to the new location + Glib::RefPtr file_to_move = Gio::File::create_for_path(config_file_path_old); + if (!file_to_move) + std::cerr << "Gio::File::create_for_path() returned an empty pointer." << std::endl; + else + file_to_move->move(Gio::File::create_for_path(config_file_path_new)); + std::cout << "INFO: Config file is moved successfully!" << std::endl; + } + catch (const Gio::Error& ex) + { + std::cerr << "Migration failed. Could not copy existing config file to new location, error: " << ex.what() << std::endl; + } + catch (const Glib::Error& ex) + { + std::cerr << "Migration failed. Could not copy existing config file to new location, error: " << ex.what() << std::endl; + } + } + + // Also remove old winetricks & winetricks.bak binaries location (if present) + if (Glib::file_test(winetricks_file_path_old, Glib::FileTest::FILE_TEST_IS_REGULAR)) + { + // Remove winetricks binary + if (!Gio::File::create_for_path(winetricks_file_path_old)->remove()) + std::cerr << "Could not remove old winetrick file." << std::endl; + } + if (Glib::file_test(winetricks_file_path_bak_old, Glib::FileTest::FILE_TEST_IS_REGULAR)) + { + // Remove winetricks.bak binary + if (!Gio::File::create_for_path(winetricks_file_path_bak_old)->remove()) + std::cerr << "Could not remove old winetrick.bak file." << std::endl; + } + + // TODO: Eventually warn users about the obsolete prefixes folder. And remove/clean-up the migration code in the future. + // For now give people some time to migrate. + + // Check if the old prefix directoy is a directory / can be found & check if prefix folder is used. + if (Glib::file_test(default_prefix_folder_old, Glib::FileTest::FILE_TEST_IS_DIR)) + { + try + { + // Now check if there are any folders still present? + Glib::RefPtr old_folder = Gio::File::create_for_path(default_prefix_folder_old); + if (!old_folder) + { + std::cerr << "Gio::File::create_for_path() returned an empty pointer." << std::endl; + } + else + { + // Enumerate the children of the folder + Glib::RefPtr enumerator = old_folder->enumerate_children(); + if (!enumerator) + { + std::cerr << "Gio::File::enumerate_children() returned an empty pointer." << std::endl; + } + else + { + // Count the folders + int folder_count = 0; + while (auto file_info = enumerator->next_file()) + { + // Check if the file is a directory + if (file_info->get_file_type() == Gio::FILE_TYPE_DIRECTORY) + folder_count++; + } + if (folder_count > 0) + final_default_prefix_folder = default_prefix_folder_old; // Keep using the old location, just to be safe + } + } + } + catch (const Gio::Error& ex) + { + std::cerr << "Migration check failed. Unable to inspect old prefix folder, error: " << ex.what() << std::endl; + } + catch (const Glib::FileError& ex) + { + std::cerr << "Migration check failed. Unable to inspect old prefix folder, error: " << ex.what() << std::endl; + } + } + } + return final_default_prefix_folder; +} \ No newline at end of file diff --git a/src/helper.cc b/src/helper.cc index f091c40..67bdd26 100644 --- a/src/helper.cc +++ b/src/helper.cc @@ -42,8 +42,8 @@ #include #include -std::vector wineGuiDirs{Glib::get_home_dir(), ".winegui"}; /*!< WineGui config/storage directory path */ -static string WineGuiDir = Glib::build_path(G_DIR_SEPARATOR_S, wineGuiDirs); +std::vector wineGuiDataDirs{Glib::get_user_data_dir(), "winegui"}; /*!< WineGUI data directory path */ +static string WineGuiDataDir = Glib::build_path(G_DIR_SEPARATOR_S, wineGuiDataDirs); std::vector defaultWineDir{Glib::get_home_dir(), ".wine"}; /*!< Default Wine bottle location */ static string DefaultBottleWineDir = Glib::build_path(G_DIR_SEPARATOR_S, defaultWineDir); @@ -52,7 +52,7 @@ static string DefaultBottleWineDir = Glib::build_path(G_DIR_SEPARATOR_S, default static const string WineExecutable = "wine"; /*!< Currently expect to be installed globally */ static const string WineExecutable64 = "wine64"; /*!< Currently expect to be installed globally */ static const string WinetricksExecutable = - Glib::build_filename(WineGuiDir, "winetricks"); /*!< winetricks shall be located within the .winegui folder */ + Glib::build_filename(WineGuiDataDir, "winetricks"); /*!< winetricks shall be located within the WineGUI data directory */ // Reg files static const string SystemReg = "system.reg"; @@ -991,13 +991,17 @@ bool Helper::dir_exists(const string& dir_path) } /** - * \brief Create directory (and intermediate parent directories if needed) + * \brief Create directory (with parent directories if needed) * \param[in] dir_path The directory to be created * \return true if successfully created, otherwise false */ bool Helper::create_dir(const string& dir_path) { - return (g_mkdir_with_parents(dir_path.c_str(), 0775) == 0); + Glib::RefPtr directory = Gio::File::create_for_path(dir_path); + if (directory) + return directory->make_directory_with_parents(); + else + return false; } /** @@ -1017,13 +1021,13 @@ bool Helper::file_exists(const string& file_path) */ void Helper::install_or_update_winetricks() { - // Check if ~/.winegui directory is created - if (!dir_exists(WineGuiDir)) + // Check if ~/.local/share/winegui directory is created + if (!dir_exists(WineGuiDataDir)) { - bool created = create_dir(WineGuiDir); + bool created = create_dir(WineGuiDataDir); if (!created) { - throw std::runtime_error("Incorrect permissions to create a .winegui configuration folder! Abort."); + throw std::runtime_error("Incorrect permissions to create a WineGUI data folder (" + WineGuiDataDir + ")! Abort."); } } @@ -1996,7 +2000,8 @@ string Helper::unescape_reg_key_data(const string& src) { auto to_hex = [](char ch) -> char { return std::isdigit(ch) ? ch - '0' : std::tolower(ch) - 'a' + 10; }; - auto wchar_to_utf8 = [](wchar_t wc) -> string { + auto wchar_to_utf8 = [](wchar_t wc) -> string + { string s; if (0 <= wc && wc <= 0x7f) { -- GitLab From 37a70bd7187cc4671b8245e164eebdeb174226a1 Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Sat, 27 May 2023 22:41:24 +0200 Subject: [PATCH 2/3] Fix format of bottle_manager again --- src/bottle_manager.cc | 389 ++++++++++++++++++++---------------------- src/helper.cc | 3 +- 2 files changed, 184 insertions(+), 208 deletions(-) diff --git a/src/bottle_manager.cc b/src/bottle_manager.cc index a68c56c..2c97a36 100644 --- a/src/bottle_manager.cc +++ b/src/bottle_manager.cc @@ -585,23 +585,21 @@ void BottleManager::run_executable(string filename, bool is_msi_file = false) string program_prefix = is_msi_file ? "msiexec /i" : "start /unix"; // Be-sure to execute the filename also between quotes (due to spaces) string program = program_prefix + " \"" + filename + "\""; - std::thread t( - [wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), - debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), - logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), - write_log_dispatcher = &write_log_dispatcher_] + std::thread t([wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), + debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), + logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), + write_log_dispatcher = &write_log_dispatcher_] { + string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, program, true, logging_stderr); + if (debug_logging && !output.empty()) + { { - string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, program, true, logging_stderr); - if (debug_logging && !output.empty()) - { - { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - }); + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + }); t.detach(); } } @@ -622,44 +620,41 @@ void BottleManager::run_program(string program) { // Between quotes (due to spaces) program = "\"" + program + "\""; - std::thread t( - [wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), - debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), - logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), - write_log_dispatcher = &write_log_dispatcher_] + std::thread t([wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), + debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), + logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), + write_log_dispatcher = &write_log_dispatcher_] { + string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, program, true, logging_stderr); + if (debug_logging && !output.empty()) + { { - string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, program, true, logging_stderr); - if (debug_logging && !output.empty()) - { - { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - }); + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + }); t.detach(); } else { // We have an exception for winetricks, since that doesn't need the wine command - std::thread t( - [wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), - output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), - output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_] + std::thread t([wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), + debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), + logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), + write_log_dispatcher = &write_log_dispatcher_] { + string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); + if (debug_logging && !output.empty()) + { { - string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); - if (debug_logging && !output.empty()) - { - { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - }); + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + }); t.detach(); } } @@ -689,23 +684,21 @@ void BottleManager::reboot() string wine_prefix = active_bottle_->wine_location(); bool is_debug_logging = active_bottle_->is_debug_logging(); int debug_log_level = active_bottle_->debug_log_level(); - std::thread t( - [wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, logging_stderr = std::move(is_logging_stderr_), - debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), - logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), - write_log_dispatcher = &write_log_dispatcher_] + std::thread t([wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, logging_stderr = std::move(is_logging_stderr_), + debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), + logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), + write_log_dispatcher = &write_log_dispatcher_] { + string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, "wineboot -r", true, logging_stderr); + if (debug_logging && !output.empty()) + { { - string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, "wineboot -r", true, logging_stderr); - if (debug_logging && !output.empty()) - { - { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - }); + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + }); t.detach(); main_window_.show_info_message("Machine emulate reboot requested."); } @@ -721,26 +714,24 @@ void BottleManager::update() string wine_prefix = active_bottle_->wine_location(); bool is_debug_logging = active_bottle_->is_debug_logging(); int debug_log_level = active_bottle_->debug_log_level(); - std::thread t( - [wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, update_bottles_dispatcher = &update_bottles_dispatcher_, - logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), - output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), - output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_] + std::thread t([wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, update_bottles_dispatcher = &update_bottles_dispatcher_, + logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), + output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), + output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_] { + string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, "wineboot -u", true, logging_stderr); + if (debug_logging && !output.empty()) + { { - string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, "wineboot -u", true, logging_stderr); - if (debug_logging && !output.empty()) - { - { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - Helper::wait_until_wineserver_is_terminated(wine_prefix); - // Emit update bottles (via dispatcher, so the GUI update can take place in the GUI thread) - update_bottles_dispatcher->emit(); - }); + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + Helper::wait_until_wineserver_is_terminated(wine_prefix); + // Emit update bottles (via dispatcher, so the GUI update can take place in the GUI thread) + update_bottles_dispatcher->emit(); + }); t.detach(); } } @@ -779,23 +770,21 @@ void BottleManager::kill_processes() string wine_prefix = active_bottle_->wine_location(); bool is_debug_logging = active_bottle_->is_debug_logging(); int debug_log_level = active_bottle_->debug_log_level(); - std::thread t( - [wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, logging_stderr = std::move(is_logging_stderr_), - debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), - logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), - write_log_dispatcher = &write_log_dispatcher_] + std::thread t([wine64 = std::move(is_wine64_bit_), wine_prefix, debug_log_level, logging_stderr = std::move(is_logging_stderr_), + debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), + logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), + write_log_dispatcher = &write_log_dispatcher_] { + string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, "wineboot -k", true, logging_stderr); + if (debug_logging && !output.empty()) + { { - string output = Helper::run_program_under_wine(wine64, wine_prefix, debug_log_level, "wineboot -k", true, logging_stderr); - if (debug_logging && !output.empty()) - { - { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - }); + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + }); t.detach(); main_window_.show_info_message("Kill processes requested."); } @@ -823,25 +812,23 @@ void BottleManager::install_d3dx9(Gtk::Window& parent, const string& version) int debug_log_level = active_bottle_->debug_log_level(); string program = Helper::get_winetricks_location() + " -q " + package; // finished_package_install_dispatcher signal is needed in order to close the busy dialog again - std::thread t( - [wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), - output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), - output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, - finish_dispatcher = &finished_package_install_dispatcher] + std::thread t([wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), + output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), + output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, + finish_dispatcher = &finished_package_install_dispatcher] { + string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); + if (debug_logging && !output.empty()) + { { - string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); - if (debug_logging && !output.empty()) - { - { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - Helper::wait_until_wineserver_is_terminated(wine_prefix); - finish_dispatcher->emit(); - }); + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + Helper::wait_until_wineserver_is_terminated(wine_prefix); + finish_dispatcher->emit(); + }); t.detach(); } } @@ -869,25 +856,23 @@ void BottleManager::install_dxvk(Gtk::Window& parent, const string& version) int debug_log_level = active_bottle_->debug_log_level(); string program = Helper::get_winetricks_location() + " -q " + package; // finished_package_install_dispatcher signal is needed in order to close the busy dialog again - std::thread t( - [wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), - output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), - output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, - finish_dispatcher = &finished_package_install_dispatcher] + std::thread t([wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), + output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), + output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, + finish_dispatcher = &finished_package_install_dispatcher] { + string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); + if (debug_logging && !output.empty()) + { { - string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); - if (debug_logging && !output.empty()) - { - { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - Helper::wait_until_wineserver_is_terminated(wine_prefix); - finish_dispatcher->emit(); - }); + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + Helper::wait_until_wineserver_is_terminated(wine_prefix); + finish_dispatcher->emit(); + }); t.detach(); } } @@ -910,25 +895,23 @@ void BottleManager::install_visual_cpp_package(Gtk::Window& parent, const string int debug_log_level = active_bottle_->debug_log_level(); string program = Helper::get_winetricks_location() + " -q " + package; // finished_package_install_dispatcher signal is needed in order to close the busy dialog again - std::thread t( - [wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), - output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), - output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, - finish_dispatcher = &finished_package_install_dispatcher] + std::thread t([wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), + output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), + output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, + finish_dispatcher = &finished_package_install_dispatcher] { + string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); + if (debug_logging && !output.empty()) + { { - string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); - if (debug_logging && !output.empty()) - { - { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - Helper::wait_until_wineserver_is_terminated(wine_prefix); - finish_dispatcher->emit(); - }); + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + Helper::wait_until_wineserver_is_terminated(wine_prefix); + finish_dispatcher->emit(); + }); t.detach(); } } @@ -970,25 +953,23 @@ void BottleManager::install_dot_net(Gtk::Window& parent, const string& version) program = install_command; } // finished_package_install_dispatcher signal is needed in order to close the busy dialog again - std::thread t( - [wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), - output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), - output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, - finish_dispatcher = &finished_package_install_dispatcher] + std::thread t([wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), + debug_logging = std::move(is_debug_logging), output_logging_mutex = std::ref(output_loging_mutex_), + logging_bottle_prefix = std::ref(logging_bottle_prefix_), output_logging = std::ref(output_logging_), + write_log_dispatcher = &write_log_dispatcher_, finish_dispatcher = &finished_package_install_dispatcher] { + string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); + if (debug_logging && !output.empty()) + { { - string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); - if (debug_logging && !output.empty()) - { - { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - Helper::wait_until_wineserver_is_terminated(wine_prefix); - finish_dispatcher->emit(); - }); + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + Helper::wait_until_wineserver_is_terminated(wine_prefix); + finish_dispatcher->emit(); + }); t.detach(); } else @@ -1014,25 +995,23 @@ void BottleManager::install_core_fonts(Gtk::Window& parent) int debug_log_level = active_bottle_->debug_log_level(); string program = Helper::get_winetricks_location() + " -q corefonts"; // finished_package_install_dispatcher signal is needed in order to close the busy dialog again - std::thread t( - [wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), - output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), - output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, - finish_dispatcher = &finished_package_install_dispatcher] + std::thread t([wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), + output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), + output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, + finish_dispatcher = &finished_package_install_dispatcher] { + string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); + if (debug_logging && !output.empty()) + { { - string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); - if (debug_logging && !output.empty()) - { - { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - Helper::wait_until_wineserver_is_terminated(wine_prefix); - finish_dispatcher->emit(); - }); + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + Helper::wait_until_wineserver_is_terminated(wine_prefix); + finish_dispatcher->emit(); + }); t.detach(); } } @@ -1053,25 +1032,23 @@ void BottleManager::install_liberation(Gtk::Window& parent) int debug_log_level = active_bottle_->debug_log_level(); string program = Helper::get_winetricks_location() + " -q liberation"; // finished_package_install_dispatcher signal is needed in order to close the busy dialog again - std::thread t( - [wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), - output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), - output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, - finish_dispatcher = &finished_package_install_dispatcher] + std::thread t([wine_prefix, debug_log_level, program, logging_stderr = std::move(is_logging_stderr_), debug_logging = std::move(is_debug_logging), + output_logging_mutex = std::ref(output_loging_mutex_), logging_bottle_prefix = std::ref(logging_bottle_prefix_), + output_logging = std::ref(output_logging_), write_log_dispatcher = &write_log_dispatcher_, + finish_dispatcher = &finished_package_install_dispatcher] { + string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); + if (debug_logging && !output.empty()) + { { - string output = Helper::run_program(wine_prefix, debug_log_level, program, true, logging_stderr); - if (debug_logging && !output.empty()) - { - { - std::lock_guard lock(output_logging_mutex); - logging_bottle_prefix.get() = wine_prefix; - output_logging.get() = output; - } - write_log_dispatcher->emit(); - } - Helper::wait_until_wineserver_is_terminated(wine_prefix); - finish_dispatcher->emit(); - }); + std::lock_guard lock(output_logging_mutex); + logging_bottle_prefix.get() = wine_prefix; + output_logging.get() = output; + } + write_log_dispatcher->emit(); + } + Helper::wait_until_wineserver_is_terminated(wine_prefix); + finish_dispatcher->emit(); + }); t.detach(); } } diff --git a/src/helper.cc b/src/helper.cc index 67bdd26..7d6b3ee 100644 --- a/src/helper.cc +++ b/src/helper.cc @@ -2000,8 +2000,7 @@ string Helper::unescape_reg_key_data(const string& src) { auto to_hex = [](char ch) -> char { return std::isdigit(ch) ? ch - '0' : std::tolower(ch) - 'a' + 10; }; - auto wchar_to_utf8 = [](wchar_t wc) -> string - { + auto wchar_to_utf8 = [](wchar_t wc) -> string { string s; if (0 <= wc && wc <= 0x7f) { -- GitLab From f06f1abfd620a713aa3c0663feec90979e9e33be Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Sat, 27 May 2023 23:01:11 +0200 Subject: [PATCH 3/3] Add error/warn prefix in error message. And remove old config.ini if it couldnt move it --- src/general_config_file.cc | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/general_config_file.cc b/src/general_config_file.cc index 4e3de43..d17c8a1 100644 --- a/src/general_config_file.cc +++ b/src/general_config_file.cc @@ -160,23 +160,36 @@ std::string GeneralConfigFile::config_and_folder_migration(const std::string& co // Check on old config.ini file if (Glib::file_test(config_file_path_old, Glib::FileTest::FILE_TEST_IS_REGULAR)) { + bool has_error = false; try { // Move the existing config file to the new location Glib::RefPtr file_to_move = Gio::File::create_for_path(config_file_path_old); if (!file_to_move) - std::cerr << "Gio::File::create_for_path() returned an empty pointer." << std::endl; + std::cerr << "Error: Gio::File::create_for_path() returned an empty pointer." << std::endl; else file_to_move->move(Gio::File::create_for_path(config_file_path_new)); std::cout << "INFO: Config file is moved successfully!" << std::endl; } catch (const Gio::Error& ex) { - std::cerr << "Migration failed. Could not copy existing config file to new location, error: " << ex.what() << std::endl; + has_error = true; + std::cerr << "Error: Migration failed. Could not copy existing config file to new location, error: " << ex.what() << std::endl; } catch (const Glib::Error& ex) { - std::cerr << "Migration failed. Could not copy existing config file to new location, error: " << ex.what() << std::endl; + has_error = true; + std::cerr << "Error: Migration failed. Could not copy existing config file to new location, error: " << ex.what() << std::endl; + } + if (has_error) + { + // Maybe the config.ini file is already present in the new location? + if (Glib::file_test(config_file_path_new, Glib::FileTest::FILE_TEST_IS_REGULAR)) + { + // In that case, remove the old config file, without migration (maybe it was migrated in the past?) + if (!Gio::File::create_for_path(config_file_path_old)->remove()) + std::cerr << "Warn: Could not remove the old config.ini file." << std::endl; + } } } @@ -185,13 +198,13 @@ std::string GeneralConfigFile::config_and_folder_migration(const std::string& co { // Remove winetricks binary if (!Gio::File::create_for_path(winetricks_file_path_old)->remove()) - std::cerr << "Could not remove old winetrick file." << std::endl; + std::cerr << "Warn: Could not remove old winetrick file." << std::endl; } if (Glib::file_test(winetricks_file_path_bak_old, Glib::FileTest::FILE_TEST_IS_REGULAR)) { // Remove winetricks.bak binary if (!Gio::File::create_for_path(winetricks_file_path_bak_old)->remove()) - std::cerr << "Could not remove old winetrick.bak file." << std::endl; + std::cerr << "Warn: Could not remove old winetrick.bak file." << std::endl; } // TODO: Eventually warn users about the obsolete prefixes folder. And remove/clean-up the migration code in the future. @@ -206,7 +219,7 @@ std::string GeneralConfigFile::config_and_folder_migration(const std::string& co Glib::RefPtr old_folder = Gio::File::create_for_path(default_prefix_folder_old); if (!old_folder) { - std::cerr << "Gio::File::create_for_path() returned an empty pointer." << std::endl; + std::cerr << "Error: Gio::File::create_for_path() returned an empty pointer." << std::endl; } else { @@ -214,7 +227,7 @@ std::string GeneralConfigFile::config_and_folder_migration(const std::string& co Glib::RefPtr enumerator = old_folder->enumerate_children(); if (!enumerator) { - std::cerr << "Gio::File::enumerate_children() returned an empty pointer." << std::endl; + std::cerr << "Error: Gio::File::enumerate_children() returned an empty pointer." << std::endl; } else { @@ -233,11 +246,11 @@ std::string GeneralConfigFile::config_and_folder_migration(const std::string& co } catch (const Gio::Error& ex) { - std::cerr << "Migration check failed. Unable to inspect old prefix folder, error: " << ex.what() << std::endl; + std::cerr << "Error: Migration check failed. Unable to inspect old prefix folder, error: " << ex.what() << std::endl; } catch (const Glib::FileError& ex) { - std::cerr << "Migration check failed. Unable to inspect old prefix folder, error: " << ex.what() << std::endl; + std::cerr << "Error: Migration check failed. Unable to inspect old prefix folder, error: " << ex.what() << std::endl; } } } -- GitLab