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 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
        }
    }
}

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

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

Comments

rezene ile zayıflama -

Nice weblog right here! Also your web site lots up very fast! What host are you using? Can I am gestting your affiliate link to your host? I want my website loaded up as quickly as yours lol

Gérald Barré -

Hi, The website is hosted by OVH on a VPS. There are also lots of optimizations to make this website fast. I'll write blog posts about it soon.

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.

Leave a reply