I'm developing a cross-platform application on dotnet with Avalonia UI and ReactiveUI.
I need to implement a command that open the file browser on the folder containing the file with the focus/highlight on the file.
Here is the command that works for Windows and OSX, but I don't know how to implement the case for Linux
RevealInFolderCommand = ReactiveCommand.CreateFromTask<string>(async path =>
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
using Process fileOpener = new Process();
fileOpener.StartInfo.FileName = "explorer";
fileOpener.StartInfo.Arguments = "/select," + path + "\"";
fileOpener.Start();
await fileOpener.WaitForExitAsync();
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
using Process fileOpener = new Process();
fileOpener.StartInfo.FileName = "explorer";
fileOpener.StartInfo.Arguments = "-R " + path;
fileOpener.Start();
await fileOpener.WaitForExitAsync();
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
throw new NotImplementedException();
}
else
{
using Process fileOpener = new Process();
fileOpener.StartInfo.FileName = Path.GetDirectoryName(path);
fileOpener.StartInfo.UseShellExecute = true;
fileOpener.Start();
await fileOpener.WaitForExitAsync();
}
});
When supported, dbus can provide that feature with this command line:
dbus-send --print-reply --dest=org.freedesktop.FileManager1 /org/freedesktop/FileManager1 org.freedesktop.FileManager1.ShowItems array:string:"file:///some path/some file" string:""
Here is the code that handle the dbus case with a fallback to opening the folder:
RevealInFolderCommand = ReactiveCommand.CreateFromTask<string>(async path =>
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
using Process fileOpener = new Process();
fileOpener.StartInfo.FileName = "explorer";
fileOpener.StartInfo.Arguments = "/select," + path + "\"";
fileOpener.Start();
await fileOpener.WaitForExitAsync();
return;
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
using Process fileOpener = new Process();
fileOpener.StartInfo.FileName = "explorer";
fileOpener.StartInfo.Arguments = "-R " + path;
fileOpener.Start();
await fileOpener.WaitForExitAsync();
return;
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
using Process dbusShowItemsProcess = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "dbus-send",
Arguments = "--print-reply --dest=org.freedesktop.FileManager1 /org/freedesktop/FileManager1 org.freedesktop.FileManager1.ShowItems array:string:\"file://"+ path +"\" string:\"\"",
UseShellExecute = true
}
};
dbusShowItemsProcess.Start();
await dbusShowItemsProcess.WaitForExitAsync();
if (dbusShowItemsProcess.ExitCode == 0)
{
// The dbus invocation can fail for a variety of reasons:
// - dbus is not available
// - no programs implement the service,
// - ...
return;
}
}
using Process folderOpener = new Process();
folderOpener.StartInfo.FileName = Path.GetDirectoryName(path);
folderOpener.StartInfo.UseShellExecute = true;
folderOpener.Start();
await folderOpener.WaitForExitAsync();
});