mirror of
https://github.com/RPCS3/rpcs3
synced 2024-11-02 11:45:30 +00:00
Utilities: Add support for portable user directory. (#15064)
This commit is contained in:
parent
96d880839a
commit
9c354ee269
6 changed files with 86 additions and 75 deletions
|
@ -8,6 +8,7 @@
|
|||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
||||
#include "util/asm.hpp"
|
||||
#include "util/coro.hpp"
|
||||
|
@ -137,6 +138,7 @@ static fs::error to_error(DWORD e)
|
|||
#if defined(__APPLE__)
|
||||
#include <copyfile.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <limits.h>
|
||||
#elif defined(__linux__) || defined(__sun)
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/syscall.h>
|
||||
|
@ -1898,6 +1900,71 @@ bool fs::file::strict_read_check(u64 _size, u64 type_size) const
|
|||
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()
|
||||
{
|
||||
// Use magic static
|
||||
|
@ -1905,6 +1972,13 @@ const std::string& fs::get_config_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
|
||||
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
|
||||
const std::string& get_config_dir();
|
||||
|
||||
|
|
|
@ -14,18 +14,6 @@
|
|||
#include <charconv>
|
||||
#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");
|
||||
|
||||
namespace rpcs3::utils
|
||||
|
@ -112,56 +100,6 @@ namespace rpcs3::utils
|
|||
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()
|
||||
{
|
||||
const std::string& emu_dir_ = g_cfg_vfs.emulator_dir;
|
||||
|
|
|
@ -13,14 +13,6 @@ namespace rpcs3::utils
|
|||
|
||||
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_hdd0_dir();
|
||||
std::string get_hdd1_dir();
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "Emu/system_utils.hpp"
|
||||
#include "Emu/VFS.h"
|
||||
#include "Emu/vfs_config.h"
|
||||
#include "Utilities/File.h"
|
||||
#include "Utilities/StrUtil.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -154,7 +155,7 @@ namespace gui::utils
|
|||
if (FAILED(res))
|
||||
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::wstring w_target_file = utf8_to_wchar(rpcs3_path);
|
||||
|
@ -219,7 +220,7 @@ namespace gui::utils
|
|||
|
||||
#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())
|
||||
{
|
||||
sys_log.error("Failed to create shortcut. App bundle path empty.");
|
||||
|
@ -307,7 +308,7 @@ namespace gui::utils
|
|||
|
||||
#else
|
||||
|
||||
const std::string exe_path = rpcs3::utils::get_executable_path();
|
||||
const std::string exe_path = fs::get_executable_path();
|
||||
if (exe_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
|
||||
|
||||
// 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::wstring wchar_orig_path = utf8_to_wchar(orig_path);
|
||||
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
|
||||
|
||||
std::string replace_path = rpcs3::utils::get_executable_path();
|
||||
std::string replace_path = fs::get_executable_path();
|
||||
if (replace_path.empty())
|
||||
{
|
||||
return false;
|
||||
|
|
Loading…
Reference in a new issue