Monday, May 27, 2013

Associate protocol with application exe or PowerShell script

First of all let me ask a simple question. Have you tried executing  'http://google.com' in the run command ? If not, just try it now. Use the short cut key Win+R to popup the run dialog. You can see your default browser is opening up and navigating to the google.com web site. Similarly if you try to execute the command 'mailto:joymon@gmail.com' in the run command it will open up your default email client and the 'to' address will be automatically populated as 'joymon@gmail.com'.

Now you might have thinking about your own protocol and your own processing application. Yes the http is a protocol. In a simple sense, its a format for communication. By seeing the word 'http' the consumers can process the remaining part of the message accordingly. Notice that, when we try to run the command which is prefixed with protocol through run dialog in windows, a program is catching the command and its taking actions after that. The program here means an .exe file.

This means if we know, how to link a protocol to an application we can have our own protocol which will be recognized by Windows. That linking is done in windows registry

Protocol to program mapping

If you are not familiar with windows registry, please get a basic idea about it from wiki. Windows registry is basically a configuration store for the Windows operating system. You can use the regedit.exe command to start editing the registry. Basically we need to create a hierarchy of keys in HKEY_CLASSES_ROOT element of registry. The hierarchy is <protocol name> -> shell -> open -> command. Inside the command key, we need to have default string value which is pointing to the application name. %1 denote that the Uri itself should be passed to the exe file as command line argument. Below is the registry entry for associating protocol named 'joymon:' with an application which will invoke TestProtocol.exe when I run the below via Run dialog or include in an HTML file.

joymon://WhateverYouWant/AsParameter - This whole line will be entering to the TestProtocol.exe as paramater


Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\joymon]
@="URL:joymon"
"URL Protocol"=""

[HKEY_CLASSES_ROOT\joymon\shell]

[HKEY_CLASSES_ROOT\joymon\shell\open]

[HKEY_CLASSES_ROOT\joymon\shell\open\command]
@="C:\\TestProtocol.exe  \"%1\""


The above lines of code can be saved to a file with extension .reg and that file can be imported to registry by double clicking. Another thing to note is the @="URL:joymon" and "URL Protocol"="" values. These are used to identify the protocol by the Windows.

If you ask me what is the code for simple C# TestProtocol.exe app to receive the notification, I will suggest a win forms app which obtains and process the command line args as follow.


//-------   C#.Net console program to process command line args ---------

    public class Program
    {
        static void Main(string[] args)
        {           
//Process the commandline string it will be like joymon://Joy's message
            string commandline = Environment.CommandLine;
            //Code to process the received argument
        }
   }

Protocol to PowerShell script / file mapping

We can even run PowerShell script in association with a protocol. But actually we are running the application named PowerShell.exe and passing the script as parameter. Below is the registry entry for the same.


Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\joymon]
@="URL:joymon"
"URL Protocol"=""

[HKEY_CLASSES_ROOT\joymon\shell]

[HKEY_CLASSES_ROOT\joymon\shell\open]

[HKEY_CLASSES_ROOT\joymon\shell\open\command]
@="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell -windowstyle hidden -command \"&{param ([string]$p);[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms');[Windows.Forms.Messagebox]::Show($p);}\" \"%1\""


If you are familiar with PowerShell you can easily identify that I am passing a script block prefixes with & to execute it to the PowerShell.exe. The argument will be relayed to the PowerShell script by the PowerShell.exe.

Real time use cases

  1. Short cut to your application's features - You can define your own protocol to create short cuts which are pointing to different screens of your application. So that when the user runs the protocol, your application can start and it can show up the corresponding screen .

    eg: If you are developing 'Address book' application you can have url, which say 'ad://list/1' can directly open the contact whose id is 1.
  2. Interoperability with other applications - If you expose URLs of your applications other apps can easily invoke modules of your app easily.

    eg: In an address book ad://adduser?name=joy&mobile=9544400706 can add a new user without opening up the application itself. This URL can be called by the other apps using Process.Start('ad://adduser?name=joy&mobile=9544400706');

No comments: