Last active
August 29, 2015 14:04
-
-
Save davecluderay/f306de1131189b70d3ce to your computer and use it in GitHub Desktop.
Handles kiln:// URLs, translating them into the full http(s) form before executing them.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.ComponentModel; | |
using System.Diagnostics; | |
using System.IO; | |
using System.Reflection; | |
using System.Runtime.InteropServices; | |
using System.Text; | |
using System.Text.RegularExpressions; | |
using System.Windows.Forms; | |
using Microsoft.Win32; | |
namespace KilnUrlHandler | |
{ | |
public class Program | |
{ | |
public static void Main(string[] args) | |
{ | |
try | |
{ | |
if (args.Length < 1) | |
{ | |
RegisterForKilnScheme(); | |
return; | |
} | |
var pattern = new Regex("^kiln://(?<Path>.+)$", RegexOptions.IgnoreCase); | |
var match = pattern.Match(args[0]); | |
if (!match.Success) | |
{ | |
return; | |
} | |
var kilnUrl = GetKilnUrl(); | |
if (kilnUrl == null) return; | |
var path = match.Groups["Path"].Value; | |
var fullUri = new Uri(kilnUrl, path); | |
Process.Start(fullUri.AbsoluteUri); | |
} | |
catch (Exception exception) | |
{ | |
MessageBox.Show(exception.Message, "Kiln URL Handler", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); | |
} | |
} | |
private static void RegisterForKilnScheme() | |
{ | |
string executablePath = GetExecutablePath(); | |
Registry.SetValue("HKEY_CURRENT_USER\\Software\\Classes\\kiln", | |
"", | |
"URL: Kiln Scheme"); | |
Registry.SetValue("HKEY_CURRENT_USER\\Software\\Classes\\kiln", | |
"URL Protocol", | |
""); | |
Registry.SetValue("HKEY_CURRENT_USER\\Software\\Classes\\kiln\\DefaultIcon", | |
"", | |
string.Format("\"{0}\"", executablePath)); | |
Registry.SetValue("HKEY_CURRENT_USER\\Software\\Classes\\kiln\\shell\\open\\command", | |
"", | |
string.Format("\"{0}\" \"%1\"", executablePath)); | |
} | |
private static string GetExecutablePath() | |
{ | |
return new Uri(Assembly.GetEntryAssembly().CodeBase).LocalPath; | |
} | |
private static Uri GetKilnUrl() | |
{ | |
string profileDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); | |
string[] mercurialIniFiles = Directory.GetFiles(profileDirectory, "mercurial*.ini"); | |
foreach (var mercurialIniFile in mercurialIniFiles) | |
{ | |
var buffer = new StringBuilder(1024); | |
uint result = GetPrivateProfileString("schemes", "kiln", "", buffer, (uint)buffer.Capacity, mercurialIniFile); | |
if (result == 0) | |
{ | |
int lastError = Marshal.GetLastWin32Error(); | |
if (lastError != ErrorSuccess && lastError != ErrorNoToken && lastError != ErrorFileNotFound) | |
throw new Win32Exception(lastError); | |
continue; | |
} | |
var url = buffer.ToString(); | |
if (Uri.IsWellFormedUriString(url, UriKind.Absolute)) | |
{ | |
if (!url.EndsWith("/")) url += "/"; | |
return new Uri(url, UriKind.Absolute); | |
} | |
} | |
return null; | |
} | |
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] | |
private static extern uint GetPrivateProfileString(string lpAppName, | |
string lpKeyName, | |
string lpDefault, | |
StringBuilder lpReturnedString, | |
uint nSize, | |
string lpFileName); | |
private const int ErrorSuccess = 0; | |
private const int ErrorFileNotFound = 2; | |
private const int ErrorNoToken = 1008; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment