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 your 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))
{
// Replace typeof(App) by the class that contains the Main method or any class located in the project that produces the exe.
// or replace typeof(App).Assembly.Location by anything that gives the full path to the exe
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!
#Additional resources
Do you have a question or a suggestion about this post? Contact me!