Registering an Application to a URI Scheme using .NET (custom protocol)

  • Gérald Barré

Many applications can be launched using a URI. Of course, you can start your favorite web browser using an URL such as https://www.meziantou.net. But you can also start you mail app using mailto:email@sample.com, or skype using skype:pseudo. Custom schemes allow your application to be launched from a web browser (<a href="scheme:...">) or an application (Process.Start("scheme:...")).

To register an application to a URI scheme, you need to create some registry keys. The final structure is:

HKEY_CLASSES_ROOT
   sample
      (Default) = "URL:Sample Protocol"
      URL Protocol = ""
      DefaultIcon
         (Default) = "sample.exe,1"
      shell
         open
            command
               (Default) = "C:\Program Files\Sample\sample.exe" "%1"

HKEY_CLASSES_ROOT is a view that merges the HKEY_LOCAL_MACHINE\Software\Classes and HKEY_CURRENT_USER\Software\Classes entries. So, you should write in HKLM or HKCU instead of HKCR. Let's create these keys:

const string UriScheme = "sample";
const string FriendlyName = "Sample Protocol";

public static void RegisterUriScheme()
{
    using (var key = Registry.CurrentUser.CreateSubKey("SOFTWARE\\Classes\\" + UriScheme))
    {
        string applicationLocation = typeof(App).Assembly.Location;

        key.SetValue("", "URL:" + FriendlyName);
        key.SetValue("URL Protocol", "");

        using (var defaultIcon = key.CreateSubKey("DefaultIcon"))
        {
            defaultIcon.SetValue("", applicationLocation + ",1");
        }

        using (var commandKey = key.CreateSubKey(@"shell\open\command"))
        {
            commandKey.SetValue("", "\"" + applicationLocation + "\" \"%1\"");
        }
    }
}

The scheme is now registered. When a user clicks a link with the sample: scheme, Windows starts the registered application with the URI as the first parameter. So, you can check the application is started from a URI by checking there is an argument and it starts with the custom scheme:

static void Main(string[] args)
{
    if(args.Length > 0)
    {
        if (Uri.TryCreate(args[0], UriKind.Absolute, out var uri) &&
            string.Equals(uri.Scheme, UriScheme, StringComparison.OrdinalIgnoreCase))
        {
            // TODO do something with the uri
        }
    }
}

THe following code will start your application using the protocol

Process.Start(new ProcessStartInfo()
{
    FileName = "sample:test",
    UseShellExecute = true, // Be sure to set this to true (not the default value on .NET Core)
});

You can now do what you want with the URI. Be creative!

Do you have a question or a suggestion about this post? Contact me!

Follow me:
Enjoy this blog?Buy Me A Coffee