LocalExplorer/Program.cs
kougyoku bb91cdc95e Update Program.cs
Change uri scheme to SaoLocalExplorer
enable opening mp3, mp4, and wmv files by simply calling it in cmd.exe and letting system figure out executable to open rather than call shell32.
2022-05-17 20:04:24 -07:00

189 lines
6.6 KiB
C#

/*
* REFERENCES:
* https://www.joe0.com/2019/01/27/how-create-a-custom-browser-uri-scheme-and-c-protocol-handler-client-that-supports-opening-and-editing-of-remotely-hosted-documents-through-webdav/
* https://stackoverflow.com/questions/44675085/minimize-console-at-app-startup-c-sharp
*
*/
using System;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
namespace LocalExplorer
{
class Program
{
[DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool ShowWindow([In] IntPtr hWnd, [In] int nCmdShow);
[DllImport("shell32.dll", EntryPoint = "FindExecutable")]
private static extern long FindExecutable(string lpFile, string lpDirectory, StringBuilder lpResult);
static void Main(string[] args)
{
bool bDirectoryExists = false;
bool bFileExists = false;
//Start this process hidden
IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;
ShowWindow(handle, 0);
//Check to make sure a path was passed in as an argument to the program.
if (args.Length == 0)
{
Console.WriteLine("usage: LocalExplorer.exe <path to open with Explorer.exe>");
WriteOutputFile("no args passed to program");
Environment.Exit(1);
}
//Collect up the path
//the replace function is here to trim out the arg as it
//comes in from the url protocol handler
string path = args[0].Replace("saolocalexplorer:", "").Replace("%5C", "\\");
//If there is a space in the path as it comes from the URL
//protocol handler, replace it with an actual space.
path = path.Replace("%20", " ");
WriteOutputFile($"arg passed: {path}");
//Determine if file or directory.
//Check to see if the directory or file exists.
if (Directory.Exists(path))
{ bDirectoryExists = true; }
if (!bDirectoryExists && File.Exists(path))
{ bFileExists = true; }
//if the directory exists pop it open.
if (bDirectoryExists)
{
OpenDirectory(path);
}
else if (bFileExists)
{
OpenFile(path);
}
else //The directory or file does not exist.
{
MessageBox.Show($"Directory or File does not exist: {path}");
WriteOutputFile($"Directory or File does not exist: {path}");
Console.WriteLine($"Directory or File does not exist: {path}");
}
} //end main
private static void OpenDirectory(string path)
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
Arguments = path,
FileName = "explorer.exe"
};
//put this inside try/catch block just in case
//explorer.exe has a permission issue or something.
try
{
Process.Start(startInfo);
}
catch
{
Console.WriteLine($"Could not proc explorer.exe to open {path}");
WriteOutputFile($"Could not proc explorer.exe to open {path}");
}
}
private static void OpenFile(string pathToFile)
{
string PATH_PREFIX = Properties.Settings.Default.PREFIX;
StringCollection ALLOWED_EXTENSIONS = Properties.Settings.Default.ALLOWED_EXTENSIONS;
string commandToRun;
//Perform sanity checks.
//Check for ssv.wa.lcl prefix.
if (!pathToFile.Contains(PATH_PREFIX))
{
MessageBox.Show($"Not permitted to open file because path does not contain {PATH_PREFIX} : {pathToFile}");
return;
}
//Check for allowed file extensions. List of allowed extensions is above.
//GetExtension returns .docx as example, strip out to match allowed extensions
string extension = Path.GetExtension(pathToFile);
if (!ALLOWED_EXTENSIONS.Contains(extension))
{
MessageBox.Show($"Not an allowed extension: {pathToFile} ; extension: {extension}");
return;
}
string path = $"{Path.GetTempFileName()}{Path.GetExtension(pathToFile)}";
//Need to create the new temp file.
if (!File.Exists(path))
{
using (StreamWriter sw = File.CreateText(path)) { }
}
if (HasExecutable(path))
{
commandToRun = $"\"{FindExecutable(path)}\" \"{pathToFile}\"";
}
else
{
commandToRun = $"\"{pathToFile}\"";
WriteOutputFile($"This file does not have an assigned executable: {pathToFile}");
}
WriteOutputFile($"opening file with command: {commandToRun}");
//LOOKS LIKE YOUR COMMAND LINE JUST GOT EXECUTED
try
{
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = true;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();
cmd.StandardInput.WriteLine(commandToRun);
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
}
catch
{
MessageBox.Show($"Unable to execute command: {commandToRun}");
return;
}
}
private static void WriteOutputFile(string debugLine)
{
// comment this out to debug the program
return;
StreamWriter outFile = new StreamWriter(@"C:\LocalExplorer\OUTPUT.txt", true);
outFile.WriteLine(debugLine);
outFile.Close();
}
public static bool HasExecutable(string path)
{
var executable = FindExecutable(path);
return !string.IsNullOrEmpty(executable);
}
private static string FindExecutable(string path)
{
var executable = new StringBuilder(1024);
FindExecutable(path, string.Empty, executable);
return executable.ToString();
}
}
}