From b6bc2cf20208049b6a8acb5e98a4ecadd4d81543 Mon Sep 17 00:00:00 2001 From: rs189 <35667100+rs189@users.noreply.github.com> Date: Mon, 14 Jul 2025 12:54:41 +0900 Subject: [PATCH] Linux: fix open folder and select item (#1288) * fix: open folder and select item on linux * fix: crash dumps folder button on linux * Rename AppData --------- Co-authored-by: Natsumi --- Dotnet/AppApi/Electron/Folders.cs | 97 +++++++++++++++++++++---------- src/views/Settings/Settings.vue | 4 +- 2 files changed, 68 insertions(+), 33 deletions(-) diff --git a/Dotnet/AppApi/Electron/Folders.cs b/Dotnet/AppApi/Electron/Folders.cs index 435dc5d8..4bef51f1 100644 --- a/Dotnet/AppApi/Electron/Folders.cs +++ b/Dotnet/AppApi/Electron/Folders.cs @@ -20,28 +20,29 @@ namespace VRCX public static string _steamUserdataPath; public static string _vrcPrefixPath; public static string _vrcAppDataPath; - + public static string _vrcCrashesPath; + static AppApiElectron() { const string vrchatAppid = "438100"; _homeDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); _steamUserdataPath = Path.Join(_homeDirectory, ".steam/steam/userdata"); _steamPath = Path.Join(_homeDirectory, ".local/share/Steam"); - + var flatpakSteamPath = Path.Join(_homeDirectory, ".var/app/com.valvesoftware.Steam/.local/share/Steam"); if (!Directory.Exists(_steamPath) && Directory.Exists(flatpakSteamPath)) { logger.Info("Flatpak Steam detected."); _steamPath = flatpakSteamPath; } - + var legacySteamPath = Path.Join(_homeDirectory, ".steam/steam"); if (!Directory.Exists(_steamPath) && Directory.Exists(legacySteamPath)) { logger.Info("Legacy Steam path detected."); _steamPath = legacySteamPath; } - + var libraryFoldersVdfPath = Path.Join(_steamPath, "config/libraryfolders.vdf"); var vrcLibraryPath = GetLibraryWithAppId(libraryFoldersVdfPath, vrchatAppid); if (string.IsNullOrEmpty(vrcLibraryPath)) @@ -52,6 +53,7 @@ namespace VRCX logger.Info($"Using steam library path {vrcLibraryPath}"); _vrcPrefixPath = Path.Join(vrcLibraryPath, $"steamapps/compatdata/{vrchatAppid}/pfx"); _vrcAppDataPath = Path.Join(_vrcPrefixPath, "drive_c/users/steamuser/AppData/LocalLow/VRChat/VRChat"); + _vrcCrashesPath = Path.Join(_vrcPrefixPath, "drive_c/users/steamuser/AppData/Local/Temp/VRChat/VRChat/Crashes"); } private static string? GetLibraryWithAppId(string libraryFoldersVdfPath, string appId) @@ -61,14 +63,14 @@ namespace VRCX string? libraryPath = null; foreach (var line in File.ReadLines(libraryFoldersVdfPath)) - { + { // Assumes line will be \t\t"path"\t\t"pathToLibrary" if (line.Contains("\"path\"")) { var parts = line.Split("\t"); if (parts.Length < 4) continue; - + libraryPath = parts[4].Replace("\"", ""); } @@ -78,12 +80,12 @@ namespace VRCX return null; } - + public override string GetVRChatAppDataLocation() { return _vrcAppDataPath; } - + public override string GetVRChatCacheLocation() { var defaultPath = Path.Join(GetVRChatAppDataLocation(), "Cache-WindowsPlayer"); @@ -104,7 +106,7 @@ namespace VRCX var cachePath = Path.Join(cacheDir, "Cache-WindowsPlayer"); if (!Directory.Exists(cacheDir)) return defaultPath; - + return cachePath; } catch (Exception e) @@ -126,7 +128,7 @@ namespace VRCX var obj = JsonConvert.DeserializeObject(json, JsonSerializerSettings); if (obj["picture_output_folder"] == null) return defaultPath; - + var photosDir = (string)obj["picture_output_folder"]; if (string.IsNullOrEmpty(photosDir) || !Directory.Exists(photosDir)) return defaultPath; @@ -139,7 +141,7 @@ namespace VRCX } return defaultPath; } - + public override string GetUGCPhotoLocation(string path = "") { if (string.IsNullOrEmpty(path)) @@ -234,10 +236,14 @@ namespace VRCX public override bool OpenCrashVrcCrashDumps() { - // TODO: get path - return false; + var path = _vrcCrashesPath; + if (!Directory.Exists(path)) + return false; + + OpenFolderAndSelectItem(path, true); + return true; } - + public override void OpenShortcutFolder() { var path = AutoAppLaunchManager.Instance.AppShortcutDirectory; @@ -246,28 +252,31 @@ namespace VRCX OpenFolderAndSelectItem(path, true); } - + public override void OpenFolderAndSelectItem(string path, bool isFolder = false) { if (!File.Exists(path) && !Directory.Exists(path)) return; - - var directoryPath = isFolder ? path : Path.GetDirectoryName(path); + + string directoryPath = isFolder ? path : Path.GetDirectoryName(path); var commandAttempt = new Dictionary { - { "nautilus", path }, - { "nemo", path }, - { "thunar", path }, + { "nautilus", $"\"{path}\"" }, + { "nemo", $"\"{path}\"" }, + { "thunar", $"\"{path}\"" }, { "caja", $"--select \"{path}\"" }, - { "pcmanfm-qt", directoryPath }, - { "pcmanfm", directoryPath }, + { "pcmanfm-qt", $"\"{directoryPath}\"" }, + { "pcmanfm", $"\"{directoryPath}\"" }, { "dolphin", $"--select \"{path}\"" }, { "konqueror", $"--select \"{path}\"" }, - { "xdg-open", directoryPath } + { "xdg-open", $"\"{directoryPath}\"" } }; - + foreach (var command in commandAttempt) { + if (!IsCommandAvailable(command.Key)) + continue; + try { var process = new Process @@ -276,22 +285,48 @@ namespace VRCX { FileName = command.Key, Arguments = command.Value, - UseShellExecute = true, - CreateNoWindow = true + UseShellExecute = false, + RedirectStandardError = true, + RedirectStandardOutput = true, + CreateNoWindow = true, } }; process.Start(); - process.WaitForExit(); - if (process.ExitCode == 0) - return; + return; // Assume first successful start is enough } - catch (Exception) + catch { - // ignore the error and try the next command + // Ignore and try next } } } + private bool IsCommandAvailable(string command) + { + try + { + var which = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = "which", + Arguments = command, + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true, + } + }; + which.Start(); + string result = which.StandardOutput.ReadToEnd(); + which.WaitForExit(); + return which.ExitCode == 0 && !string.IsNullOrWhiteSpace(result); + } + catch + { + return false; + } + } + public override async Task OpenFolderSelectorDialog(string defaultPath = "") { // TODO: Implement diff --git a/src/views/Settings/Settings.vue b/src/views/Settings/Settings.vue index 54dd9fc0..7114a82f 100644 --- a/src/views/Settings/Settings.vue +++ b/src/views/Settings/Settings.vue @@ -1404,10 +1404,10 @@
AppData (VRCX)VRCX Data AppDataVRChat Data Crash Dumps