Commit f12beac1 authored by Melroy van den Berg's avatar Melroy van den Berg
Browse files

Merge branch 'master' into 2-edit-menu

parents 1618abfc 9632e0d2
Pipeline #2796 passed with stages
in 14 seconds
...@@ -47,9 +47,9 @@ public: ...@@ -47,9 +47,9 @@ public:
static Helper& getInstance(); static Helper& getInstance();
static std::map<string, unsigned long> GetBottlesPaths(const string& dir_path); static std::map<string, unsigned long> GetBottlesPaths(const string& dir_path);
static void RunProgram(string prefix_path, string program, bool enable_tracing, bool give_error); static void RunProgram(string prefix_path, string program, bool give_error, bool enable_tracing);
static void RunProgramUnderWine(string prefix_path, string program, bool enable_tracing, bool is_msi_file); static void RunProgramUnderWine(string prefix_path, string program, bool give_error, bool enable_tracing);
static void RunProgramWithFinishCallback(string prefix_path, string program, bool enable_tracing, bool give_error, bool is_msi_file, Glib::Dispatcher* finishSignal); static void RunProgramWithFinishCallback(string prefix_path, string program, Glib::Dispatcher* finishSignal, bool give_error, bool enable_tracing);
static void WaitUntilWineserverIsTerminated(const string prefix_path); static void WaitUntilWineserverIsTerminated(const string prefix_path);
static string GetWineExecutableLocation(); static string GetWineExecutableLocation();
static string GetWinetricksLocation(); static string GetWinetricksLocation();
...@@ -86,7 +86,7 @@ private: ...@@ -86,7 +86,7 @@ private:
static string Exec(const char* cmd); static string Exec(const char* cmd);
static void ExecTracing(const char* cmd, bool enableTracing); static void ExecTracing(const char* cmd, bool enableTracing);
static int CloseFile(std::FILE* file); static int CloseExecStream(std::FILE* file);
static bool WriteFile(const string& filename, const gchar* contents, const gsize length); static bool WriteFile(const string& filename, const gchar* contents, const gsize length);
static bool ReadFile(const string& filename, gchar* contents); static bool ReadFile(const string& filename, gchar* contents);
static string GetWinetricksVersion(); static string GetWinetricksVersion();
......
...@@ -296,7 +296,10 @@ void BottleManager::RunProgram(string filename, bool is_msi_file = false) ...@@ -296,7 +296,10 @@ void BottleManager::RunProgram(string filename, bool is_msi_file = false)
{ {
if (isBottleNotNull()) { if (isBottleNotNull()) {
Glib::ustring wine_prefix = activeBottle->wine_location(); Glib::ustring wine_prefix = activeBottle->wine_location();
std::thread t(&Helper::RunProgramUnderWine, wine_prefix, filename, false, is_msi_file); Glib::ustring program_prefix = is_msi_file ? "msiexec /i" : "start /unix";
// Be-sure to execute the filename also between brackets (in case of spaces)
Glib::ustring program = program_prefix + " \"" + filename + "\"";
std::thread t(&Helper::RunProgramUnderWine, wine_prefix, program, true, false);
t.detach(); t.detach();
} }
} }
...@@ -358,7 +361,7 @@ void BottleManager::OpenExplorer() ...@@ -358,7 +361,7 @@ void BottleManager::OpenExplorer()
{ {
if (isBottleNotNull()) { if (isBottleNotNull()) {
Glib::ustring wine_prefix = activeBottle->wine_location(); Glib::ustring wine_prefix = activeBottle->wine_location();
std::thread t(&Helper::RunProgram, wine_prefix, "wine explorer", false, true); std::thread t(&Helper::RunProgramUnderWine, wine_prefix, "explorer", false, false);
t.detach(); t.detach();
} }
} }
...@@ -370,7 +373,7 @@ void BottleManager::OpenConsole() ...@@ -370,7 +373,7 @@ void BottleManager::OpenConsole()
{ {
if (isBottleNotNull()) { if (isBottleNotNull()) {
Glib::ustring wine_prefix = activeBottle->wine_location(); Glib::ustring wine_prefix = activeBottle->wine_location();
std::thread t(&Helper::RunProgram, wine_prefix, "wineconsole", false, true); std::thread t(&Helper::RunProgramUnderWine, wine_prefix, "wineconsole", false, false);
t.detach(); t.detach();
} }
} }
...@@ -382,7 +385,7 @@ void BottleManager::OpenWinecfg() ...@@ -382,7 +385,7 @@ void BottleManager::OpenWinecfg()
{ {
if (isBottleNotNull()) { if (isBottleNotNull()) {
Glib::ustring wine_prefix = activeBottle->wine_location(); Glib::ustring wine_prefix = activeBottle->wine_location();
std::thread t(&Helper::RunProgram, wine_prefix, "winecfg", false, true); std::thread t(&Helper::RunProgramUnderWine, wine_prefix, "winecfg", false, false);
t.detach(); t.detach();
} }
} }
...@@ -395,7 +398,7 @@ void BottleManager::OpenWinetricks() ...@@ -395,7 +398,7 @@ void BottleManager::OpenWinetricks()
if (isBottleNotNull()) { if (isBottleNotNull()) {
Glib::ustring wine_prefix = activeBottle->wine_location(); Glib::ustring wine_prefix = activeBottle->wine_location();
Glib::ustring program = Helper::GetWinetricksLocation() + " --gui"; Glib::ustring program = Helper::GetWinetricksLocation() + " --gui";
std::thread t(&Helper::RunProgram, wine_prefix, program, false, true); std::thread t(&Helper::RunProgram, wine_prefix, program, true, false);
t.detach(); t.detach();
} }
} }
...@@ -407,7 +410,7 @@ void BottleManager::OpenUninstaller() ...@@ -407,7 +410,7 @@ void BottleManager::OpenUninstaller()
{ {
if (isBottleNotNull()) { if (isBottleNotNull()) {
Glib::ustring wine_prefix = activeBottle->wine_location(); Glib::ustring wine_prefix = activeBottle->wine_location();
std::thread t(&Helper::RunProgram, wine_prefix, "wine uninstaller", false, false); std::thread t(&Helper::RunProgramUnderWine, wine_prefix, "uninstaller", false, false);
t.detach(); t.detach();
} }
} }
...@@ -419,7 +422,7 @@ void BottleManager::OpenTaskManager() ...@@ -419,7 +422,7 @@ void BottleManager::OpenTaskManager()
{ {
if (isBottleNotNull()) { if (isBottleNotNull()) {
Glib::ustring wine_prefix = activeBottle->wine_location(); Glib::ustring wine_prefix = activeBottle->wine_location();
std::thread t(&Helper::RunProgram, wine_prefix, "wine taskmgr", false, false); std::thread t(&Helper::RunProgramUnderWine, wine_prefix, "taskmgr", false, false);
t.detach(); t.detach();
} }
} }
...@@ -431,7 +434,7 @@ void BottleManager::OpenRegistertyEditor() ...@@ -431,7 +434,7 @@ void BottleManager::OpenRegistertyEditor()
{ {
if (isBottleNotNull()) { if (isBottleNotNull()) {
Glib::ustring wine_prefix = activeBottle->wine_location(); Glib::ustring wine_prefix = activeBottle->wine_location();
std::thread t(&Helper::RunProgram, wine_prefix, "wine regedit", false, true); std::thread t(&Helper::RunProgramUnderWine, wine_prefix, "regedit", false, false);
t.detach(); t.detach();
} }
} }
...@@ -490,7 +493,7 @@ void BottleManager::InstallD3DX9(Gtk::Window& parent, const Glib::ustring& versi ...@@ -490,7 +493,7 @@ void BottleManager::InstallD3DX9(Gtk::Window& parent, const Glib::ustring& versi
Glib::ustring wine_prefix = activeBottle->wine_location(); Glib::ustring wine_prefix = activeBottle->wine_location();
Glib::ustring program = Helper::GetWinetricksLocation() + " -q " + package; Glib::ustring program = Helper::GetWinetricksLocation() + " -q " + package;
// finishedPackageInstall signal is needed in order to close the busy dialog again // finishedPackageInstall signal is needed in order to close the busy dialog again
std::thread t(&Helper::RunProgramWithFinishCallback, wine_prefix, program, false, true, false, &finishedPackageInstall); std::thread t(&Helper::RunProgramWithFinishCallback, wine_prefix, program, &finishedPackageInstall, true, false);
t.detach(); t.detach();
} }
} }
...@@ -514,7 +517,7 @@ void BottleManager::InstallDXVK(Gtk::Window& parent, const Glib::ustring& versio ...@@ -514,7 +517,7 @@ void BottleManager::InstallDXVK(Gtk::Window& parent, const Glib::ustring& versio
Glib::ustring wine_prefix = activeBottle->wine_location(); Glib::ustring wine_prefix = activeBottle->wine_location();
Glib::ustring program = Helper::GetWinetricksLocation() + " -q " + package; Glib::ustring program = Helper::GetWinetricksLocation() + " -q " + package;
// finishedPackageInstall signal is needed in order to close the busy dialog again // finishedPackageInstall signal is needed in order to close the busy dialog again
std::thread t(&Helper::RunProgramWithFinishCallback, wine_prefix, program, false, true, false, &finishedPackageInstall); std::thread t(&Helper::RunProgramWithFinishCallback, wine_prefix, program, &finishedPackageInstall, true, false);
t.detach(); t.detach();
} }
} }
...@@ -534,7 +537,7 @@ void BottleManager::InstallVisualCppPackage(Gtk::Window& parent, const Glib::ust ...@@ -534,7 +537,7 @@ void BottleManager::InstallVisualCppPackage(Gtk::Window& parent, const Glib::ust
Glib::ustring wine_prefix = activeBottle->wine_location(); Glib::ustring wine_prefix = activeBottle->wine_location();
Glib::ustring program = Helper::GetWinetricksLocation() + " -q " + package; Glib::ustring program = Helper::GetWinetricksLocation() + " -q " + package;
// finishedPackageInstall signal is needed in order to close the busy dialog again // finishedPackageInstall signal is needed in order to close the busy dialog again
std::thread t(&Helper::RunProgramWithFinishCallback, wine_prefix, program, false, true, false, &finishedPackageInstall); std::thread t(&Helper::RunProgramWithFinishCallback, wine_prefix, program, &finishedPackageInstall, true, false);
t.detach(); t.detach();
} }
} }
...@@ -567,7 +570,7 @@ void BottleManager::InstallDotNet(Gtk::Window& parent, const Glib::ustring& vers ...@@ -567,7 +570,7 @@ void BottleManager::InstallDotNet(Gtk::Window& parent, const Glib::ustring& vers
program = installCommand; program = installCommand;
} }
// finishedPackageInstall signal is needed in order to close the busy dialog again // finishedPackageInstall signal is needed in order to close the busy dialog again
std::thread t(&Helper::RunProgramWithFinishCallback, wine_prefix, program, false, true, false, &finishedPackageInstall); std::thread t(&Helper::RunProgramWithFinishCallback, wine_prefix, program, &finishedPackageInstall, true, false);
t.detach(); t.detach();
} else { } else {
// Nothing, canceled // Nothing, canceled
...@@ -588,7 +591,7 @@ void BottleManager::InstallCoreFonts(Gtk::Window& parent) ...@@ -588,7 +591,7 @@ void BottleManager::InstallCoreFonts(Gtk::Window& parent)
Glib::ustring wine_prefix = activeBottle->wine_location(); Glib::ustring wine_prefix = activeBottle->wine_location();
Glib::ustring program = Helper::GetWinetricksLocation() + " -q corefonts"; Glib::ustring program = Helper::GetWinetricksLocation() + " -q corefonts";
// finishedPackageInstall signal is needed in order to close the busy dialog again // finishedPackageInstall signal is needed in order to close the busy dialog again
std::thread t(&Helper::RunProgramWithFinishCallback, wine_prefix, program, false, true, false, &finishedPackageInstall); std::thread t(&Helper::RunProgramWithFinishCallback, wine_prefix, program, &finishedPackageInstall, true, false);
t.detach(); t.detach();
} }
} }
...@@ -606,7 +609,7 @@ void BottleManager::InstallLiberation(Gtk::Window& parent) ...@@ -606,7 +609,7 @@ void BottleManager::InstallLiberation(Gtk::Window& parent)
Glib::ustring wine_prefix = activeBottle->wine_location(); Glib::ustring wine_prefix = activeBottle->wine_location();
Glib::ustring program = Helper::GetWinetricksLocation() + " -q liberation"; Glib::ustring program = Helper::GetWinetricksLocation() + " -q liberation";
// finishedPackageInstall signal is needed in order to close the busy dialog again // finishedPackageInstall signal is needed in order to close the busy dialog again
std::thread t(&Helper::RunProgramWithFinishCallback, wine_prefix, program, false, true, false, &finishedPackageInstall); std::thread t(&Helper::RunProgramWithFinishCallback, wine_prefix, program, &finishedPackageInstall, true, false);
t.detach(); t.detach();
} }
} }
......
...@@ -138,19 +138,12 @@ std::map<std::string, unsigned long> Helper::GetBottlesPaths(const string& dir_p ...@@ -138,19 +138,12 @@ std::map<std::string, unsigned long> Helper::GetBottlesPaths(const string& dir_p
* \brief Run any program with only setting the WINEPREFIX env variable (run this method async) * \brief Run any program with only setting the WINEPREFIX env variable (run this method async)
* \param[in] prefix_path - The path to wine bottle * \param[in] prefix_path - The path to wine bottle
* \param[in] program - Program that gets executed (ideally full path) * \param[in] program - Program that gets executed (ideally full path)
* \param[in] enable_tracing - Enable debugging tracing to file (give_error should be true as well!)
* \param[in] give_error - Inform user when application exit with non-zero exit code * \param[in] give_error - Inform user when application exit with non-zero exit code
* \param[in] enable_tracing - Enable debugging tracing to file (give_error should be true as well!)
*/ */
void Helper::RunProgram(string prefix_path, string program, bool enable_tracing, bool give_error) void Helper::RunProgram(string prefix_path, string program, bool give_error = true, bool enable_tracing = false)
{ {
bool execTracing = false; if (give_error) {
if (enable_tracing) {
execTracing = true;
}
if (!give_error) {
execTracing = false;
}
if (execTracing) {
// Execute the command and show the user a message when exit code is non-zero // Execute the command and show the user a message when exit code is non-zero
ExecTracing(("WINEPREFIX=\"" + prefix_path + "\" " + program).c_str(), enable_tracing); ExecTracing(("WINEPREFIX=\"" + prefix_path + "\" " + program).c_str(), enable_tracing);
} else { } else {
...@@ -162,18 +155,13 @@ void Helper::RunProgram(string prefix_path, string program, bool enable_tracing, ...@@ -162,18 +155,13 @@ void Helper::RunProgram(string prefix_path, string program, bool enable_tracing,
/** /**
* \brief Run a Windows program under Wine (run this method async) * \brief Run a Windows program under Wine (run this method async)
* \param[in] prefix_path - The path to bottle wine * \param[in] prefix_path - The path to bottle wine
* \param[in] program - Program/executable that will be executed * \param[in] program - Program/executable that will be executed (be sure your application executable is between brackets in case of spaces)
* \param[in] enable_tracing - Enable debugging tracing to file * \param[in] give_error - Inform user when application exit with non-zero exit code
* \param[in] is_msi_file - Is the program a MSI installer * \param[in] enable_tracing - Enable debugging tracing to file (give_error should be true as well!)
*/ */
void Helper::RunProgramUnderWine(string prefix_path, string program, bool enable_tracing, bool is_msi_file) void Helper::RunProgramUnderWine(string prefix_path, string program, bool give_error = true, bool enable_tracing = false)
{ {
string msi = ""; RunProgram(prefix_path, Helper::GetWineExecutableLocation() + " " + program, give_error, enable_tracing);
if (is_msi_file) {
msi = " msiexec /i";
}
// Execute the command and show the user a message when exit code is non-zero
ExecTracing(("WINEPREFIX=\"" + prefix_path + "\"" + msi + " " + Helper::GetWineExecutableLocation() + " " + program).c_str(), enable_tracing);
} }
/** /**
...@@ -181,36 +169,18 @@ void Helper::RunProgramUnderWine(string prefix_path, string program, bool enable ...@@ -181,36 +169,18 @@ void Helper::RunProgramUnderWine(string prefix_path, string program, bool enable
* This method will really wait until the wineserver is down. * This method will really wait until the wineserver is down.
* \param[in] prefix_path - The path to bottle wine * \param[in] prefix_path - The path to bottle wine
* \param[in] program - Program/executable that will be executed * \param[in] program - Program/executable that will be executed
* \param[in] enable_tracing - Enable debugging tracing to file
* \param[in] give_error - Inform user when application exit with non-zero exit code
* \param[in] is_msi_file - Is the program a MSI installer (don't forget to add GetWineExecutableLocation() to the program parameter)
* \param[in] finishSignal - Signal handler to be called when execution is finished * \param[in] finishSignal - Signal handler to be called when execution is finished
* \param[in] give_error - Inform user when application exit with non-zero exit code
* \param[in] enable_tracing - Enable debugging tracing to file (give_error should be true as well!)
*/ */
void Helper::RunProgramWithFinishCallback(string prefix_path, void Helper::RunProgramWithFinishCallback(string prefix_path,
string program, string program,
bool enable_tracing, Glib::Dispatcher* finishSignal,
bool give_error, bool give_error = true,
bool is_msi_file, bool enable_tracing = false)
Glib::Dispatcher* finishSignal)
{ {
bool execTracing = false; // Be-sure to execute the program also between brackets (in case of spaces)
if (enable_tracing) { RunProgram(prefix_path, program, give_error, enable_tracing);
execTracing = true;
}
if (!give_error) {
execTracing = false;
}
if (execTracing) {
string msi = "";
if (is_msi_file) {
msi = " msiexec /i";
}
// Execute the command and show the user a message when exit code is non-zero
ExecTracing(("WINEPREFIX=\"" + prefix_path + "\"" + msi + " " + program).c_str(), enable_tracing);
} else {
// No tracing and no error message when exit code is non-zero
Exec(("WINEPREFIX=\"" + prefix_path + "\" " + program).c_str());
}
// Blocking wait until wineserver is terminated (before we can look in the reg files for example) // Blocking wait until wineserver is terminated (before we can look in the reg files for example)
Helper::WaitUntilWineserverIsTerminated(prefix_path); Helper::WaitUntilWineserverIsTerminated(prefix_path);
...@@ -916,7 +886,8 @@ string Helper::Exec(const char* cmd) { ...@@ -916,7 +886,8 @@ string Helper::Exec(const char* cmd) {
std::array<char, 128> buffer; std::array<char, 128> buffer;
string result = ""; string result = "";
// Execute command using popen // Execute command using popen,
// And use the standard C pclose method during stream closure.
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), &pclose); std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), &pclose);
if (!pipe) { if (!pipe) {
throw std::runtime_error("popen() failed!"); throw std::runtime_error("popen() failed!");
...@@ -940,8 +911,8 @@ void Helper::ExecTracing(const char* cmd, bool enableTracing) { ...@@ -940,8 +911,8 @@ void Helper::ExecTracing(const char* cmd, bool enableTracing) {
string result = ""; string result = "";
// Execute command using popen // Execute command using popen
// Use a custom delete method (CloseFile) // Use a custom close file function during the pipe close (CloseExecStream method, see below)
std::unique_ptr<FILE, decltype(&CloseFile)> pipe(popen(cmd, "r"), &CloseFile); std::unique_ptr<FILE, decltype(&CloseExecStream)> pipe(popen(cmd, "r"), &CloseExecStream);
if (!pipe) { if (!pipe) {
throw std::runtime_error("popen() failed!"); throw std::runtime_error("popen() failed!");
} }
...@@ -955,7 +926,11 @@ void Helper::ExecTracing(const char* cmd, bool enableTracing) { ...@@ -955,7 +926,11 @@ void Helper::ExecTracing(const char* cmd, bool enableTracing) {
} }
} }
int Helper::CloseFile(std::FILE* file) { /**
* Custom fclose method, which is executed during the stream closure of C popen command.
* Check on fclose return value, signal a failure/pop-up to the user, when exit-code is non-zero.
*/
int Helper::CloseExecStream(std::FILE* file) {
if (file) { if (file) {
if (std::fclose(file) != 0) { if (std::fclose(file) != 0) {
// Dispatcher will run the connected slot in the main loop, // Dispatcher will run the connected slot in the main loop,
......
...@@ -6,60 +6,65 @@ ...@@ -6,60 +6,65 @@
], ],
"settings": { "settings": {
"files.associations": { "files.associations": {
"typeinfo": "cpp", "typeinfo": "cpp",
"system_error": "cpp", "system_error": "cpp",
"string": "cpp", "string": "cpp",
"stdexcept": "cpp", "stdexcept": "cpp",
"array": "cpp", "array": "cpp",
"*.tcc": "cpp", "*.tcc": "cpp",
"cctype": "cpp", "cctype": "cpp",
"chrono": "cpp", "chrono": "cpp",
"clocale": "cpp", "clocale": "cpp",
"cmath": "cpp", "cmath": "cpp",
"codecvt": "cpp", "codecvt": "cpp",
"cstdarg": "cpp", "cstdarg": "cpp",
"cstdint": "cpp", "cstdint": "cpp",
"cstdio": "cpp", "cstdio": "cpp",
"cstdlib": "cpp", "cstdlib": "cpp",
"cstring": "cpp", "cstring": "cpp",
"ctime": "cpp", "ctime": "cpp",
"cwchar": "cpp", "cwchar": "cpp",
"cwctype": "cpp", "cwctype": "cpp",
"deque": "cpp", "deque": "cpp",
"unordered_map": "cpp", "unordered_map": "cpp",
"vector": "cpp", "vector": "cpp",
"exception": "cpp", "exception": "cpp",
"fstream": "cpp", "fstream": "cpp",
"initializer_list": "cpp", "initializer_list": "cpp",
"iomanip": "cpp", "iomanip": "cpp",
"iosfwd": "cpp", "iosfwd": "cpp",
"iostream": "cpp", "iostream": "cpp",
"istream": "cpp", "istream": "cpp",
"limits": "cpp", "limits": "cpp",
"memory": "cpp", "memory": "cpp",
"new": "cpp", "new": "cpp",
"optional": "cpp", "optional": "cpp",
"ostream": "cpp", "ostream": "cpp",
"ratio": "cpp", "ratio": "cpp",
"sstream": "cpp", "sstream": "cpp",
"streambuf": "cpp", "streambuf": "cpp",
"string_view": "cpp", "string_view": "cpp",
"type_traits": "cpp", "type_traits": "cpp",
"tuple": "cpp", "tuple": "cpp",
"utility": "cpp", "utility": "cpp",
"condition_variable": "cpp", "condition_variable": "cpp",
"cstddef": "cpp", "cstddef": "cpp",
"list": "cpp", "list": "cpp",
"filesystem": "cpp", "filesystem": "cpp",
"functional": "cpp", "functional": "cpp",
"mutex": "cpp", "mutex": "cpp",
"thread": "cpp", "thread": "cpp",
"valarray": "cpp", "valarray": "cpp",
"algorithm": "cpp", "algorithm": "cpp",
"atomic": "cpp", "atomic": "cpp",
"iterator": "cpp", "iterator": "cpp",
"map": "cpp", "map": "cpp",
"memory_resource": "cpp" "memory_resource": "cpp",
} "numeric": "cpp",
"random": "cpp",
"set": "cpp",
"cinttypes": "cpp",
"bit": "cpp"
}
} }
} }
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment