/* * 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 "); 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", " "); //Replace / with \ to support proper unc path = path.Replace("/", "\\"); //If the URL contains a #, //Trim out everything after # including the # if(path.Contains("#")) { path = path.Substring(0, path.IndexOf("#")); } 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) { if (!Properties.Settings.Default.DEBUG) { 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(); } } }