LocalExplorer/Program.cs

197 lines
6.9 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", " ");
//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();
}
}
}