mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
Utilities: Add support for portable user directory. (#15064)
This commit is contained in:
parent
96d880839a
commit
9c354ee269
@ -8,6 +8,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "util/asm.hpp"
|
#include "util/asm.hpp"
|
||||||
#include "util/coro.hpp"
|
#include "util/coro.hpp"
|
||||||
@ -137,6 +138,7 @@ static fs::error to_error(DWORD e)
|
|||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
#include <copyfile.h>
|
#include <copyfile.h>
|
||||||
#include <mach-o/dyld.h>
|
#include <mach-o/dyld.h>
|
||||||
|
#include <limits.h>
|
||||||
#elif defined(__linux__) || defined(__sun)
|
#elif defined(__linux__) || defined(__sun)
|
||||||
#include <sys/sendfile.h>
|
#include <sys/sendfile.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
@ -1898,6 +1900,71 @@ bool fs::file::strict_read_check(u64 _size, u64 type_size) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string fs::get_executable_path()
|
||||||
|
{
|
||||||
|
// Use magic static
|
||||||
|
static const std::string s_exe_path = []
|
||||||
|
{
|
||||||
|
#if defined(_WIN32)
|
||||||
|
std::vector<wchar_t> buffer(32767);
|
||||||
|
GetModuleFileNameW(nullptr, buffer.data(), buffer.size());
|
||||||
|
return wchar_to_utf8(buffer.data());
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
char bin_path[PATH_MAX];
|
||||||
|
uint32_t bin_path_size = sizeof(bin_path);
|
||||||
|
if (_NSGetExecutablePath(bin_path, &bin_path_size) != 0)
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to find app binary path" << std::endl;
|
||||||
|
return std::string{};
|
||||||
|
}
|
||||||
|
|
||||||
|
// App bundle directory is three levels up from the binary.
|
||||||
|
return get_parent_dir(bin_path, 3);
|
||||||
|
#else
|
||||||
|
if (const char* appimage_path = ::getenv("APPIMAGE"))
|
||||||
|
{
|
||||||
|
std::cout << "Found AppImage path: " << appimage_path << std::endl;
|
||||||
|
return std::string(appimage_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "No AppImage path found, checking for executable" << std::endl;
|
||||||
|
|
||||||
|
char exe_path[PATH_MAX];
|
||||||
|
const ssize_t len = ::readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
|
||||||
|
|
||||||
|
if (len == -1)
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to find executable path" << std::endl;
|
||||||
|
return std::string{};
|
||||||
|
}
|
||||||
|
|
||||||
|
exe_path[len] = '\0';
|
||||||
|
std::cout << "Found exec path: " << exe_path << std::endl;
|
||||||
|
|
||||||
|
return std::string(exe_path);
|
||||||
|
#endif
|
||||||
|
}();
|
||||||
|
|
||||||
|
return s_exe_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string fs::get_executable_dir()
|
||||||
|
{
|
||||||
|
// Use magic static
|
||||||
|
static const std::string s_exe_dir = []
|
||||||
|
{
|
||||||
|
std::string exe_path = get_executable_path();
|
||||||
|
if (exe_path.empty())
|
||||||
|
{
|
||||||
|
return exe_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
return get_parent_dir(exe_path);
|
||||||
|
}();
|
||||||
|
|
||||||
|
return s_exe_dir;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string& fs::get_config_dir()
|
const std::string& fs::get_config_dir()
|
||||||
{
|
{
|
||||||
// Use magic static
|
// Use magic static
|
||||||
@ -1905,6 +1972,13 @@ const std::string& fs::get_config_dir()
|
|||||||
{
|
{
|
||||||
std::string dir;
|
std::string dir;
|
||||||
|
|
||||||
|
// Check if a portable directory exists.
|
||||||
|
std::string portable_dir = get_executable_dir() + "/portable/";
|
||||||
|
if (is_dir(portable_dir))
|
||||||
|
{
|
||||||
|
return portable_dir;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
std::vector<wchar_t> buf;
|
std::vector<wchar_t> buf;
|
||||||
|
|
||||||
|
@ -660,6 +660,12 @@ namespace fs
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Get executable path
|
||||||
|
std::string get_executable_path();
|
||||||
|
|
||||||
|
// Get executable containing directory
|
||||||
|
std::string get_executable_dir();
|
||||||
|
|
||||||
// Get configuration directory
|
// Get configuration directory
|
||||||
const std::string& get_config_dir();
|
const std::string& get_config_dir();
|
||||||
|
|
||||||
|
@ -14,18 +14,6 @@
|
|||||||
#include <charconv>
|
#include <charconv>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
#else
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#include <mach-o/dyld.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <filesystem>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LOG_CHANNEL(sys_log, "SYS");
|
LOG_CHANNEL(sys_log, "SYS");
|
||||||
|
|
||||||
namespace rpcs3::utils
|
namespace rpcs3::utils
|
||||||
@ -112,56 +100,6 @@ namespace rpcs3::utils
|
|||||||
return worker();
|
return worker();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
std::string get_exe_dir()
|
|
||||||
{
|
|
||||||
wchar_t buffer[32767];
|
|
||||||
GetModuleFileNameW(nullptr, buffer, sizeof(buffer) / 2);
|
|
||||||
|
|
||||||
const std::string path_to_exe = wchar_to_utf8(buffer);
|
|
||||||
const usz last = path_to_exe.find_last_of('\\');
|
|
||||||
return last == std::string::npos ? std::string("") : path_to_exe.substr(0, last + 1);
|
|
||||||
}
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
std::string get_app_bundle_path()
|
|
||||||
{
|
|
||||||
char bin_path[PATH_MAX];
|
|
||||||
uint32_t bin_path_size = sizeof(bin_path);
|
|
||||||
if (_NSGetExecutablePath(bin_path, &bin_path_size) != 0)
|
|
||||||
{
|
|
||||||
sys_log.error("Failed to find app binary path");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::filesystem::path(bin_path).parent_path().parent_path().parent_path();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
std::string get_executable_path()
|
|
||||||
{
|
|
||||||
if (const char* appimage_path = ::getenv("APPIMAGE"))
|
|
||||||
{
|
|
||||||
sys_log.notice("Found AppImage path: %s", appimage_path);
|
|
||||||
return std::string(appimage_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
sys_log.warning("Failed to find AppImage path");
|
|
||||||
|
|
||||||
char exe_path[PATH_MAX];
|
|
||||||
const ssize_t len = ::readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
|
|
||||||
|
|
||||||
if (len == -1)
|
|
||||||
{
|
|
||||||
sys_log.error("Failed to find executable path");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
exe_path[len] = '\0';
|
|
||||||
sys_log.trace("Found exec path: %s", exe_path);
|
|
||||||
|
|
||||||
return std::string(exe_path);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::string get_emu_dir()
|
std::string get_emu_dir()
|
||||||
{
|
{
|
||||||
const std::string& emu_dir_ = g_cfg_vfs.emulator_dir;
|
const std::string& emu_dir_ = g_cfg_vfs.emulator_dir;
|
||||||
|
@ -13,14 +13,6 @@ namespace rpcs3::utils
|
|||||||
|
|
||||||
bool install_pkg(const std::string& path);
|
bool install_pkg(const std::string& path);
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
std::string get_exe_dir();
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
std::string get_app_bundle_path();
|
|
||||||
#else
|
|
||||||
std::string get_executable_path();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::string get_emu_dir();
|
std::string get_emu_dir();
|
||||||
std::string get_hdd0_dir();
|
std::string get_hdd0_dir();
|
||||||
std::string get_hdd1_dir();
|
std::string get_hdd1_dir();
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "Emu/system_utils.hpp"
|
#include "Emu/system_utils.hpp"
|
||||||
#include "Emu/VFS.h"
|
#include "Emu/VFS.h"
|
||||||
#include "Emu/vfs_config.h"
|
#include "Emu/vfs_config.h"
|
||||||
|
#include "Utilities/File.h"
|
||||||
#include "Utilities/StrUtil.h"
|
#include "Utilities/StrUtil.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -154,7 +155,7 @@ namespace gui::utils
|
|||||||
if (FAILED(res))
|
if (FAILED(res))
|
||||||
return cleanup(false, "CoCreateInstance failed");
|
return cleanup(false, "CoCreateInstance failed");
|
||||||
|
|
||||||
const std::string working_dir{ rpcs3::utils::get_exe_dir() };
|
const std::string working_dir{ fs::get_executable_dir() };
|
||||||
const std::string rpcs3_path{ working_dir + "rpcs3.exe" };
|
const std::string rpcs3_path{ working_dir + "rpcs3.exe" };
|
||||||
|
|
||||||
const std::wstring w_target_file = utf8_to_wchar(rpcs3_path);
|
const std::wstring w_target_file = utf8_to_wchar(rpcs3_path);
|
||||||
@ -219,7 +220,7 @@ namespace gui::utils
|
|||||||
|
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
|
|
||||||
const std::string app_bundle_path = rpcs3::utils::get_app_bundle_path();
|
const std::string app_bundle_path = fs::get_executable_path();
|
||||||
if (app_bundle_path.empty())
|
if (app_bundle_path.empty())
|
||||||
{
|
{
|
||||||
sys_log.error("Failed to create shortcut. App bundle path empty.");
|
sys_log.error("Failed to create shortcut. App bundle path empty.");
|
||||||
@ -307,7 +308,7 @@ namespace gui::utils
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
const std::string exe_path = rpcs3::utils::get_executable_path();
|
const std::string exe_path = fs::get_executable_path();
|
||||||
if (exe_path.empty())
|
if (exe_path.empty())
|
||||||
{
|
{
|
||||||
sys_log.error("Failed to create shortcut. Executable path empty.");
|
sys_log.error("Failed to create shortcut. Executable path empty.");
|
||||||
|
@ -393,7 +393,7 @@ bool update_manager::handle_rpcs3(const QByteArray& data, bool auto_accept)
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
// Get executable path
|
// Get executable path
|
||||||
const std::string exe_dir = rpcs3::utils::get_exe_dir();
|
const std::string exe_dir = fs::get_executable_dir();
|
||||||
const std::string orig_path = exe_dir + "rpcs3.exe";
|
const std::string orig_path = exe_dir + "rpcs3.exe";
|
||||||
const std::wstring wchar_orig_path = utf8_to_wchar(orig_path);
|
const std::wstring wchar_orig_path = utf8_to_wchar(orig_path);
|
||||||
const std::string tmpfile_path = fs::get_temp_dir() + "\\rpcs3_update.7z";
|
const std::string tmpfile_path = fs::get_temp_dir() + "\\rpcs3_update.7z";
|
||||||
@ -583,7 +583,7 @@ bool update_manager::handle_rpcs3(const QByteArray& data, bool auto_accept)
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
std::string replace_path = rpcs3::utils::get_executable_path();
|
std::string replace_path = fs::get_executable_path();
|
||||||
if (replace_path.empty())
|
if (replace_path.empty())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
Reference in New Issue
Block a user