diff --git a/Source/Core/Common/FileUtil.cpp b/Source/Core/Common/FileUtil.cpp index fe622ac21a..a631aa3edc 100644 --- a/Source/Core/Common/FileUtil.cpp +++ b/Source/Core/Common/FileUtil.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #endif @@ -683,6 +684,9 @@ std::string GetExePath() dolphin_path = TStrToUTF8(dolphin_exe_expanded_path); else dolphin_path = TStrToUTF8(dolphin_exe_path); +#elif defined(__APPLE__) + dolphin_path = GetBundleDirectory(); + dolphin_path = dolphin_path.substr(0, dolphin_path.find_last_of("Dolphin.app/Contents/MacOS")); #else char dolphin_exe_path[PATH_MAX]; ssize_t len = ::readlink("/proc/self/exe", dolphin_exe_path, sizeof(dolphin_exe_path)); diff --git a/Source/Core/MacUpdater/UI.mm b/Source/Core/MacUpdater/UI.mm index 749e5cd03b..0deb85db93 100644 --- a/Source/Core/MacUpdater/UI.mm +++ b/Source/Core/MacUpdater/UI.mm @@ -15,11 +15,15 @@ void run_on_main(std::function fnc) { if (![NSThread isMainThread]) + { dispatch_sync(dispatch_get_main_queue(), ^{ fnc(); }); + } else + { fnc(); + } } NSWindow* GetWindow() diff --git a/Source/Core/UICommon/AutoUpdate.cpp b/Source/Core/UICommon/AutoUpdate.cpp index 003135683a..00256ee174 100644 --- a/Source/Core/UICommon/AutoUpdate.cpp +++ b/Source/Core/UICommon/AutoUpdate.cpp @@ -19,23 +19,50 @@ #include #endif +#ifdef __APPLE__ +#include +#include +#include +#endif + +#if defined _WIN32 || defined __APPLE__ +#define OS_SUPPORTS_UPDATER +#endif + namespace { #ifdef _WIN32 const char UPDATER_FILENAME[] = "Updater.exe"; const char UPDATER_RELOC_FILENAME[] = "Updater.2.exe"; + +#elif defined(__APPLE__) + +const char UPDATER_FILENAME[] = "Dolphin Updater.app"; +const char UPDATER_RELOC_FILENAME[] = ".Dolphin Updater.2.app"; + +#endif + const char UPDATER_LOG_FILE[] = "Updater.log"; -std::wstring MakeUpdaterCommandLine(const std::map& flags) +#ifdef OS_SUPPORTS_UPDATER +std::string MakeUpdaterCommandLine(const std::map& flags) { - std::wstring cmdline = UTF8ToUTF16(UPDATER_FILENAME) + L" "; // Start with a fake argv[0]. +#ifdef __APPLE__ + std::string cmdline = "\"" + File::GetExeDirectory() + DIR_SEP + UPDATER_RELOC_FILENAME + + "/Contents/MacOS/Dolphin Updater\""; +#else + std::string cmdline = File::GetExeDirectory() + DIR_SEP + UPDATER_RELOC_FILENAME; +#endif + + cmdline += " "; + for (const auto& pair : flags) { std::string value = "--" + pair.first + "=" + pair.second; value = ReplaceAll(value, "\"", "\\\""); // Escape double quotes. value = "\"" + value + "\" "; - cmdline += UTF8ToUTF16(value); + cmdline += value; } return cmdline; } @@ -44,7 +71,12 @@ std::wstring MakeUpdaterCommandLine(const std::map& fl void CleanupFromPreviousUpdate() { std::string reloc_updater_path = File::GetExeDirectory() + DIR_SEP + UPDATER_RELOC_FILENAME; + +#ifdef __APPLE__ + File::DeleteDirRecursively(reloc_updater_path); +#else File::Delete(reloc_updater_path); +#endif } #endif @@ -93,28 +125,40 @@ std::string GenerateChangelog(const picojson::array& versions) bool AutoUpdateChecker::SystemSupportsAutoUpdates() { -#ifdef _WIN32 +#if defined _WIN32 || defined __APPLE__ return true; #else return false; #endif } +static std::string GetPlatformID() +{ +#if defined _WIN32 + return "win"; +#elif defined __APPLE__ + return "macos"; +#else + return "unknown"; +#endif +} + void AutoUpdateChecker::CheckForUpdate() { // Don't bother checking if updates are not supported or not enabled. if (!SystemSupportsAutoUpdates() || SConfig::GetInstance().m_auto_update_track.empty()) return; -#ifdef _WIN32 +#ifdef OS_SUPPORTS_UPDATER CleanupFromPreviousUpdate(); #endif std::string version_hash = SConfig::GetInstance().m_auto_update_hash_override.empty() ? SCM_REV_STR : SConfig::GetInstance().m_auto_update_hash_override; - std::string url = "https://dolphin-emu.org/update/check/v0/" + - SConfig::GetInstance().m_auto_update_track + "/" + version_hash; + std::string url = "https://dolphin-emu.org/update/check/v1/" + + SConfig::GetInstance().m_auto_update_track + "/" + version_hash + "/" + + GetPlatformID(); Common::HttpRequest req{std::chrono::seconds{10}}; auto resp = req.Get(url); @@ -157,12 +201,16 @@ void AutoUpdateChecker::CheckForUpdate() void AutoUpdateChecker::TriggerUpdate(const AutoUpdateChecker::NewVersionInformation& info, AutoUpdateChecker::RestartMode restart_mode) { -#ifdef _WIN32 +#ifdef OS_SUPPORTS_UPDATER std::map updater_flags; updater_flags["this-manifest-url"] = info.this_manifest_url; updater_flags["next-manifest-url"] = info.next_manifest_url; updater_flags["content-store-url"] = info.content_store_url; +#ifdef _WIN32 updater_flags["parent-pid"] = std::to_string(GetCurrentProcessId()); +#else + updater_flags["parent-pid"] = std::to_string(getpid()); +#endif updater_flags["install-base-path"] = File::GetExeDirectory(); updater_flags["log-file"] = File::GetExeDirectory() + DIR_SEP + UPDATER_LOG_FILE; @@ -172,19 +220,35 @@ void AutoUpdateChecker::TriggerUpdate(const AutoUpdateChecker::NewVersionInforma // Copy the updater so it can update itself if needed. std::string updater_path = File::GetExeDirectory() + DIR_SEP + UPDATER_FILENAME; std::string reloc_updater_path = File::GetExeDirectory() + DIR_SEP + UPDATER_RELOC_FILENAME; + +#ifdef __APPLE__ + File::CopyDir(updater_path, reloc_updater_path); + chmod((reloc_updater_path + "/Contents/MacOS/Dolphin Updater").c_str(), 0700); +#else File::Copy(updater_path, reloc_updater_path); +#endif // Run the updater! - std::wstring command_line = MakeUpdaterCommandLine(updater_flags); + std::string command_line = MakeUpdaterCommandLine(updater_flags); + + INFO_LOG(COMMON, "Updater command line: %s", command_line.c_str()); + +#ifdef _WIN32 STARTUPINFO sinfo = {sizeof(info)}; sinfo.dwFlags = STARTF_FORCEOFFFEEDBACK; // No hourglass cursor after starting the process. PROCESS_INFORMATION pinfo; - INFO_LOG(COMMON, "Updater command line: %s", UTF16ToUTF8(command_line).c_str()); if (!CreateProcessW(UTF8ToUTF16(reloc_updater_path).c_str(), - const_cast(command_line.c_str()), nullptr, nullptr, FALSE, 0, - nullptr, nullptr, &sinfo, &pinfo)) + const_cast(UTF8ToUTF16(command_line).c_str()), nullptr, nullptr, + FALSE, 0, nullptr, nullptr, &sinfo, &pinfo)) { ERROR_LOG(COMMON, "Could not start updater process: error=%d", GetLastError()); } +#else + if (popen(command_line.c_str(), "r") == nullptr) + { + ERROR_LOG(COMMON, "Could not start updater process: error=%d", errno); + } +#endif + #endif }