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 <cmcooper123@hotmail.com>
This commit is contained in:
rs189
2025-07-14 12:54:41 +09:00
committed by GitHub
parent ee49e8897b
commit b6bc2cf202
2 changed files with 68 additions and 33 deletions

View File

@@ -20,28 +20,29 @@ namespace VRCX
public static string _steamUserdataPath; public static string _steamUserdataPath;
public static string _vrcPrefixPath; public static string _vrcPrefixPath;
public static string _vrcAppDataPath; public static string _vrcAppDataPath;
public static string _vrcCrashesPath;
static AppApiElectron() static AppApiElectron()
{ {
const string vrchatAppid = "438100"; const string vrchatAppid = "438100";
_homeDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); _homeDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
_steamUserdataPath = Path.Join(_homeDirectory, ".steam/steam/userdata"); _steamUserdataPath = Path.Join(_homeDirectory, ".steam/steam/userdata");
_steamPath = Path.Join(_homeDirectory, ".local/share/Steam"); _steamPath = Path.Join(_homeDirectory, ".local/share/Steam");
var flatpakSteamPath = Path.Join(_homeDirectory, ".var/app/com.valvesoftware.Steam/.local/share/Steam"); var flatpakSteamPath = Path.Join(_homeDirectory, ".var/app/com.valvesoftware.Steam/.local/share/Steam");
if (!Directory.Exists(_steamPath) && Directory.Exists(flatpakSteamPath)) if (!Directory.Exists(_steamPath) && Directory.Exists(flatpakSteamPath))
{ {
logger.Info("Flatpak Steam detected."); logger.Info("Flatpak Steam detected.");
_steamPath = flatpakSteamPath; _steamPath = flatpakSteamPath;
} }
var legacySteamPath = Path.Join(_homeDirectory, ".steam/steam"); var legacySteamPath = Path.Join(_homeDirectory, ".steam/steam");
if (!Directory.Exists(_steamPath) && Directory.Exists(legacySteamPath)) if (!Directory.Exists(_steamPath) && Directory.Exists(legacySteamPath))
{ {
logger.Info("Legacy Steam path detected."); logger.Info("Legacy Steam path detected.");
_steamPath = legacySteamPath; _steamPath = legacySteamPath;
} }
var libraryFoldersVdfPath = Path.Join(_steamPath, "config/libraryfolders.vdf"); var libraryFoldersVdfPath = Path.Join(_steamPath, "config/libraryfolders.vdf");
var vrcLibraryPath = GetLibraryWithAppId(libraryFoldersVdfPath, vrchatAppid); var vrcLibraryPath = GetLibraryWithAppId(libraryFoldersVdfPath, vrchatAppid);
if (string.IsNullOrEmpty(vrcLibraryPath)) if (string.IsNullOrEmpty(vrcLibraryPath))
@@ -52,6 +53,7 @@ namespace VRCX
logger.Info($"Using steam library path {vrcLibraryPath}"); logger.Info($"Using steam library path {vrcLibraryPath}");
_vrcPrefixPath = Path.Join(vrcLibraryPath, $"steamapps/compatdata/{vrchatAppid}/pfx"); _vrcPrefixPath = Path.Join(vrcLibraryPath, $"steamapps/compatdata/{vrchatAppid}/pfx");
_vrcAppDataPath = Path.Join(_vrcPrefixPath, "drive_c/users/steamuser/AppData/LocalLow/VRChat/VRChat"); _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) private static string? GetLibraryWithAppId(string libraryFoldersVdfPath, string appId)
@@ -61,14 +63,14 @@ namespace VRCX
string? libraryPath = null; string? libraryPath = null;
foreach (var line in File.ReadLines(libraryFoldersVdfPath)) foreach (var line in File.ReadLines(libraryFoldersVdfPath))
{ {
// Assumes line will be \t\t"path"\t\t"pathToLibrary" // Assumes line will be \t\t"path"\t\t"pathToLibrary"
if (line.Contains("\"path\"")) if (line.Contains("\"path\""))
{ {
var parts = line.Split("\t"); var parts = line.Split("\t");
if (parts.Length < 4) if (parts.Length < 4)
continue; continue;
libraryPath = parts[4].Replace("\"", ""); libraryPath = parts[4].Replace("\"", "");
} }
@@ -78,12 +80,12 @@ namespace VRCX
return null; return null;
} }
public override string GetVRChatAppDataLocation() public override string GetVRChatAppDataLocation()
{ {
return _vrcAppDataPath; return _vrcAppDataPath;
} }
public override string GetVRChatCacheLocation() public override string GetVRChatCacheLocation()
{ {
var defaultPath = Path.Join(GetVRChatAppDataLocation(), "Cache-WindowsPlayer"); var defaultPath = Path.Join(GetVRChatAppDataLocation(), "Cache-WindowsPlayer");
@@ -104,7 +106,7 @@ namespace VRCX
var cachePath = Path.Join(cacheDir, "Cache-WindowsPlayer"); var cachePath = Path.Join(cacheDir, "Cache-WindowsPlayer");
if (!Directory.Exists(cacheDir)) if (!Directory.Exists(cacheDir))
return defaultPath; return defaultPath;
return cachePath; return cachePath;
} }
catch (Exception e) catch (Exception e)
@@ -126,7 +128,7 @@ namespace VRCX
var obj = JsonConvert.DeserializeObject<JObject>(json, JsonSerializerSettings); var obj = JsonConvert.DeserializeObject<JObject>(json, JsonSerializerSettings);
if (obj["picture_output_folder"] == null) if (obj["picture_output_folder"] == null)
return defaultPath; return defaultPath;
var photosDir = (string)obj["picture_output_folder"]; var photosDir = (string)obj["picture_output_folder"];
if (string.IsNullOrEmpty(photosDir) || !Directory.Exists(photosDir)) if (string.IsNullOrEmpty(photosDir) || !Directory.Exists(photosDir))
return defaultPath; return defaultPath;
@@ -139,7 +141,7 @@ namespace VRCX
} }
return defaultPath; return defaultPath;
} }
public override string GetUGCPhotoLocation(string path = "") public override string GetUGCPhotoLocation(string path = "")
{ {
if (string.IsNullOrEmpty(path)) if (string.IsNullOrEmpty(path))
@@ -234,10 +236,14 @@ namespace VRCX
public override bool OpenCrashVrcCrashDumps() public override bool OpenCrashVrcCrashDumps()
{ {
// TODO: get path var path = _vrcCrashesPath;
return false; if (!Directory.Exists(path))
return false;
OpenFolderAndSelectItem(path, true);
return true;
} }
public override void OpenShortcutFolder() public override void OpenShortcutFolder()
{ {
var path = AutoAppLaunchManager.Instance.AppShortcutDirectory; var path = AutoAppLaunchManager.Instance.AppShortcutDirectory;
@@ -246,28 +252,31 @@ namespace VRCX
OpenFolderAndSelectItem(path, true); OpenFolderAndSelectItem(path, true);
} }
public override void OpenFolderAndSelectItem(string path, bool isFolder = false) public override void OpenFolderAndSelectItem(string path, bool isFolder = false)
{ {
if (!File.Exists(path) && !Directory.Exists(path)) if (!File.Exists(path) && !Directory.Exists(path))
return; return;
var directoryPath = isFolder ? path : Path.GetDirectoryName(path); string directoryPath = isFolder ? path : Path.GetDirectoryName(path);
var commandAttempt = new Dictionary<string, string> var commandAttempt = new Dictionary<string, string>
{ {
{ "nautilus", path }, { "nautilus", $"\"{path}\"" },
{ "nemo", path }, { "nemo", $"\"{path}\"" },
{ "thunar", path }, { "thunar", $"\"{path}\"" },
{ "caja", $"--select \"{path}\"" }, { "caja", $"--select \"{path}\"" },
{ "pcmanfm-qt", directoryPath }, { "pcmanfm-qt", $"\"{directoryPath}\"" },
{ "pcmanfm", directoryPath }, { "pcmanfm", $"\"{directoryPath}\"" },
{ "dolphin", $"--select \"{path}\"" }, { "dolphin", $"--select \"{path}\"" },
{ "konqueror", $"--select \"{path}\"" }, { "konqueror", $"--select \"{path}\"" },
{ "xdg-open", directoryPath } { "xdg-open", $"\"{directoryPath}\"" }
}; };
foreach (var command in commandAttempt) foreach (var command in commandAttempt)
{ {
if (!IsCommandAvailable(command.Key))
continue;
try try
{ {
var process = new Process var process = new Process
@@ -276,22 +285,48 @@ namespace VRCX
{ {
FileName = command.Key, FileName = command.Key,
Arguments = command.Value, Arguments = command.Value,
UseShellExecute = true, UseShellExecute = false,
CreateNoWindow = true RedirectStandardError = true,
RedirectStandardOutput = true,
CreateNoWindow = true,
} }
}; };
process.Start(); process.Start();
process.WaitForExit(); return; // Assume first successful start is enough
if (process.ExitCode == 0)
return;
} }
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<string> OpenFolderSelectorDialog(string defaultPath = "") public override async Task<string> OpenFolderSelectorDialog(string defaultPath = "")
{ {
// TODO: Implement // TODO: Implement

View File

@@ -1404,10 +1404,10 @@
<div class="options-container-item" style="margin-top: 15px"> <div class="options-container-item" style="margin-top: 15px">
<el-button-group> <el-button-group>
<el-button size="small" icon="el-icon-folder" @click="openVrcxAppDataFolder()" <el-button size="small" icon="el-icon-folder" @click="openVrcxAppDataFolder()"
>AppData (VRCX)</el-button >VRCX Data</el-button
> >
<el-button size="small" icon="el-icon-folder" @click="openVrcAppDataFolder()" <el-button size="small" icon="el-icon-folder" @click="openVrcAppDataFolder()"
>AppData</el-button >VRChat Data</el-button
> >
<el-button size="small" icon="el-icon-folder" @click="openCrashVrcCrashDumps()" <el-button size="small" icon="el-icon-folder" @click="openCrashVrcCrashDumps()"
>Crash Dumps</el-button >Crash Dumps</el-button