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

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!

Enjoy this blog? Buy Me A Coffee Donate 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).

Leave a reply