ClickOnce Protocol Handler (also works for Silvelight or Xbap)
So if your goal is to create a protocol handler so that you can create a link with some data in it, click on it and have your clickonce, silverlight or xbap application open up and react to the given data in the link... this is how you do it. As a matter of semantics - you probably know an xbap IS a clickonce deployed application - xml browser application. Actually the application manifest is almost identical to any other clickonce deployed application except that it has an additional few sections indicating to launch in a browser. All three of these will work using this technique though there may be slight variations necessary. I'll cover the more tricky parts that I ran into.
Protocol Handler
So let's say you've defined your protocol as MYPROTOCOL. when you normally open a webpage you type in https://whatever - but once your protocol is registered you would type in MYPROTOCOL://whateverarguments and it will execute your deployed application passing the argments specified. You can type that into Vista's start search, or into the browser - or even create a link in an email. Perhaps you will include the ID to some data element and when your application opens it will launch the appropriate UI to load that data based on the ID. This is the scenario I'll be describing - not search protocols or other implementations.
Approach
When the user clicks your new custom link it will execute a bootstrapper passing it the command line arguments. That bootstrapper will in turn execute the URL for your clickonce (or silverlight or xbap) deployed application passing the command line arguments as URL parameters. If you were to try to execute the local installed version of your clickonce exe - you will find that it does not execute under the proper permisisons designated by the certificate you used to sign it. The only way to reliably ensure that your application executes under the correct permissions is to launch the URL and pass querystring parameters to it. Henceforth I'll refer to all of these (clickonce, silverlight, xbap) as simply "application". Note: there is a nifty way to keep a single instance of your application even if they click the link multiple times... however as that applies only to clickonce and not to the other application types I won't cover that here. Tip: look at using the VB libraries in your C# library. Otherwise - each link click will open a new instance.
So here's the task break-down:
1) Configure your application to accept querystring parameters.
2) Modify the protocol handler bootstrapper (download included) for your application url.
3) Create an MSI installer to register your protocol and install the bootstrapper... (yes - you need to install something on the user's client machine!)
Configure your application to accept querystring parameters
The first step is to prepare your application to receive and act on these querystring parameters. You will want to set that up and test it out first. In the end clicking on a link such as https://mydeploymentserver/MyApplicationFolder/MyApplication.application?param1=foo¶m2=bar should open your application and do whatever you want it to do.
There's ton's of articles out there detailing how to do that customized per application type - so I won't regurgitate but instead point you in the right direction...
> For clickonce check out this article here.
> For xbaps check out this article here.
> For silverlight check out this article here.
Protocol Handler Bootstrapper
Ok so you've got that first part working now, right? Pretty cool, huh? At this point you may be asking yourself why in the world do I even need a protocol handler? I could just use the full link to do whatever I need and WITHOUT requiring the end user to install anything on their client machine. That's absolutely true - you could and if you don't need any of the advantages listed below then that's what I suggest you do.
Advantages of the protocol handler vs. using the full application url + querystring params directly:
1) The URL data doesn't change per deployed environment.
> This one was a big deal for us. We have a lot of test case data pointing to links such as OurProtocol://id=123 that we didn't want to have to change the data per environment url (dev, smoke, test, uat, etc).
2) The user can type a much shorter entry into Start or Browser (such as openMe:\\id=123 instead of https://www.whatever.com?id=123. )
3) You can piggy back on this to install different desktop shortcuts that will open your application to particular given states.
Ok - so you've weighed the pros and cons and still want the protocol handler. :) Your bootstrapper will convert the arguments given into a url and launch your browser with the given URL. See the full solution here.
Register your Protocol You have a few options here. In the end you will want to have an addition to the registry that has the path to your ProtocolBootstrapper.exe and the cmd args - as shown below. Note - if you need to bypass some security restrictions use the "runas" instead of the "open" as shown in the second example below. You could create a .reg file and then execute that with elevated permissions directly from your clickonce application (that's what we did) but that won't work for Silverlight and Xbap. The better approach is to put your new ProtocolBootstrapper.exe into a new MSI that will also update the user's registry with the necessary new keys - then have the users that want to enable this functionality install the MSI.
For articles on creating an MSI see here, here and here!
Example Registry Entry
[HKEY_CLASSES_ROOT]
[YourProtocol]
(Default) = "URL:Your Protocol Description"
URL Protocol = ""
[shell]
[open]
[command]
(Default) = "c:\whereever\ProtocolBootstrapper.exe "%1""
[HKEY_CLASSES_ROOT]
[YourProtocol]
(Default) = "URL:Your Protocol Description"
URL Protocol = ""
[shell]
[runas]
[command]
(Default) = "c:\whereever\ProtocolBootstrapper.exe "%1""
Comments
Anonymous
January 01, 2003
I wanted to do this for my app, but I felt like having a separate MSI installer for a bootstrapper defeated the purpose of ClickOnce deployment. Instead, I added a function to my main form class that figures out where the clickonce app is running from via Application.ExecutablePath, then creates all the relevent keys in HKEY_CURRENT_USERSoftwareClasses. Works like a charm so far...Anonymous
July 08, 2015
@superstator Very good tip. Thank you!