SHA256
162 lines
5.2 KiB
C#
162 lines
5.2 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using MelonLoader;
|
|
|
|
namespace ADOFAIRenderer.Util;
|
|
|
|
internal static class FolderDialogUtil
|
|
{
|
|
public static void OpenFolderBrowser(string initialDirectory, Action<string?> onSelected)
|
|
{
|
|
var syncContext = SynchronizationContext.Current;
|
|
|
|
Task.Run(() =>
|
|
{
|
|
string? selected = null;
|
|
try
|
|
{
|
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|
{
|
|
selected = OpenWindowsFolderBrowser(initialDirectory);
|
|
}
|
|
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
|
{
|
|
selected = OpenMacFolderBrowser(initialDirectory);
|
|
}
|
|
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
|
{
|
|
selected = OpenLinuxFolderBrowser(initialDirectory);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MelonLogger.Warning($"[FolderDialogUtil] Failed to open folder browser: {ex.Message}");
|
|
}
|
|
|
|
if (syncContext != null)
|
|
{
|
|
syncContext.Post(_ => onSelected(selected), null);
|
|
}
|
|
else
|
|
{
|
|
onSelected(selected);
|
|
}
|
|
});
|
|
}
|
|
|
|
private static string? OpenWindowsFolderBrowser(string initialDirectory)
|
|
{
|
|
try
|
|
{
|
|
var escapedDir = initialDirectory.Replace("'", "''");
|
|
var script = $@"
|
|
[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') | Out-Null
|
|
$f = New-Object System.Windows.Forms.FolderBrowserDialog
|
|
$f.Description = 'Select Output Directory'
|
|
if ([System.IO.Directory]::Exists('{escapedDir}')) {{
|
|
$f.SelectedPath = '{escapedDir}'
|
|
}}
|
|
$f.ShowNewFolderButton = $true
|
|
if ($f.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {{
|
|
[Console]::Write($f.SelectedPath)
|
|
}}";
|
|
|
|
var bytes = System.Text.Encoding.Unicode.GetBytes(script);
|
|
var base64 = Convert.ToBase64String(bytes);
|
|
|
|
var startInfo = new ProcessStartInfo
|
|
{
|
|
FileName = "powershell.exe",
|
|
Arguments = $"-NoProfile -NonInteractive -ExecutionPolicy Bypass -EncodedCommand {base64}",
|
|
CreateNoWindow = true,
|
|
UseShellExecute = false,
|
|
RedirectStandardOutput = true,
|
|
WindowStyle = ProcessWindowStyle.Hidden
|
|
};
|
|
|
|
using var process = Process.Start(startInfo);
|
|
if (process == null) return null;
|
|
|
|
var output = process.StandardOutput.ReadToEnd().Trim();
|
|
process.WaitForExit();
|
|
|
|
return !string.IsNullOrEmpty(output) && Directory.Exists(output) ? output : null;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MelonLogger.Warning($"[FolderDialogUtil] Windows folder dialog error: {ex.Message}");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private static string? OpenMacFolderBrowser(string initialDirectory)
|
|
{
|
|
try
|
|
{
|
|
var escaped = initialDirectory.Replace("\"", "\\\"");
|
|
var script = $"POSIX path of (choose folder with prompt \"Select Output Directory\" default location \"{escaped}\")";
|
|
|
|
var startInfo = new ProcessStartInfo
|
|
{
|
|
FileName = "osascript",
|
|
CreateNoWindow = true,
|
|
UseShellExecute = false,
|
|
RedirectStandardOutput = true,
|
|
WindowStyle = ProcessWindowStyle.Hidden
|
|
};
|
|
startInfo.ArgumentList.Add("-e");
|
|
startInfo.ArgumentList.Add(script);
|
|
|
|
using var process = Process.Start(startInfo);
|
|
if (process == null) return null;
|
|
|
|
var output = process.StandardOutput.ReadToEnd().Trim();
|
|
process.WaitForExit();
|
|
|
|
return !string.IsNullOrEmpty(output) && Directory.Exists(output) ? output : null;
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private static string? OpenLinuxFolderBrowser(string initialDirectory)
|
|
{
|
|
try
|
|
{
|
|
var startInfo = new ProcessStartInfo
|
|
{
|
|
FileName = "zenity",
|
|
CreateNoWindow = true,
|
|
UseShellExecute = false,
|
|
RedirectStandardOutput = true,
|
|
WindowStyle = ProcessWindowStyle.Hidden
|
|
};
|
|
startInfo.ArgumentList.Add("--file-selection");
|
|
startInfo.ArgumentList.Add("--directory");
|
|
startInfo.ArgumentList.Add("--title=Select Output Directory");
|
|
if (!string.IsNullOrEmpty(initialDirectory) && Directory.Exists(initialDirectory))
|
|
{
|
|
startInfo.ArgumentList.Add($"--filename={initialDirectory}");
|
|
}
|
|
|
|
using var process = Process.Start(startInfo);
|
|
if (process == null) return null;
|
|
|
|
var output = process.StandardOutput.ReadToEnd().Trim();
|
|
process.WaitForExit();
|
|
|
|
return !string.IsNullOrEmpty(output) && Directory.Exists(output) ? output : null;
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
}
|