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

  • .NET

Many applications can be launched using a URI. Of course, you can start your favorite web browser using an URL such as But you can also start you mail app using, 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:

      (Default) = "URL:Sample Protocol"
      URL Protocol = ""
         (Default) = "sample.exe,1"
               (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

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 on Twitter or by email!

Follow me:
Enjoy this blog?Buy Me A CoffeeDonate with PayPal


Cleiton Martins -

Hello, I created the schema as an example, but I can not call it with the command Process.Start("scheme: sample") or the url in the browser, Would you help me?

Taking advantage of if I need to pass another parameter is just me "\" \"% 2\" "

Gérald Barré -

First, you need to check the value in the registry under HKEY_CURRENT_USER\Software\Classes\sample\shell\open\command. In my case it is C:\Users\mezia\source\repos\ConsoleApp3\ConsoleApp3\bin\Debug\netcoreapp3.0\ConsoleApp3.exe" "%1".

Then, to use the protocol from .NET, be sure to start the process using UseShellExecute = true (not the default on .NET Core)

Process.Start(new ProcessStartInfo()
    FileName = "sample:test",
    UseShellExecute = true,

From the browser, you may get a popup that asks you if you really want to start the application (at least the first time you enter the url in the address bar).

Joe -

In Windows 10 1803 and higher, if there is an app that was designed to handle specific URIs, such as Skype, which handles the SIP protocol, if you try to change the registry keys to use a custom app, Skype continues to handle the protocol and eventually the registry keys get restored to show the Skype app path.