Perhaps you're familiar with such URL protocol handlers such as http://microsoft.com , ftp://user:pass@server outlook:Contacts , file://http://www.coad.net/blog/images/Greenstone.bmp , ms-help://...
Want to make your own client-side URL handler? Maybe to pull data from a source and display it, share content between applications, launch apps from web links, etc?
Say you want to be able to link from your intranet to special resources you know are on your internal network, or render data between applications via a central server across platforms and technologies. This is one way to do some of that…
Sample Application
Here is a sample app that is designed to run registered applications on the local machine using a keyword. After installing the example RunAppUrlProtocol app, you can put links on web pages like runapp://calc , runapp://excel , or runapp://docs that will trigger this app, look up the keyword, and execute the app. You can install the app and then click the links to try it.
Registering the URL Protocol Handler
The key part here is the string value “URL Protocol” (with a blank value) which tells Windows to register this as a handler.
[HKEY_CLASSES_ROOT]
[runapp]
(Default) = "URL:RunApp Protocol Handler"
URL Protocol = ""
[DefaultIcon]
(Default) = "c:/whatever/RunAppUrlProtocol.exe”
[shell]
[open]
[command]
(Default) = "c:/whatever/RunAppUrlProtocol.exe "%1""
The Code
Here is a sample app that demonstrates writing your own handler, RunAppUrlProtocol.zip . The key elements here are:
- This started as a Console Application that I changed the project properties to a Windows Application so that a console window isn’t opened up. This allows the app to run “hidden”.
- Grabbing the protocol from the command line args, so “runapp://excel” would be passed as a command argument.
- The use of Regular Expressions here is trivial, but you can imagine it would be a lot more helpful when the URL is more complex, like the FTP URL with many optional components. ftp://[<username>][:<password>]@<server>[:<port>][/<resource>]
- This example has a minimal amount of user input checking, any decent app would have a lot more (for example, checking to make sure the target exists before trying to run it)
- A good way to extend this example would be to add support for command line arguments in the URL, like runapp://<appkey>/<args>
#region Namespace Inclusions
using System ;
using System .IO ;
using System .Xml ;
using System .Reflection ;
using System .Diagnostics ;
using System .Windows .Forms ;
using System .Text .RegularExpressions ;
#endregion
namespace RunAppUrlProtocol
{
class Program
{
static void Main (string [] args )
{
// The URL handler for this app
string prefix = "runapp://" ;
// The name of this app for user messages
string title = "RunApp URL Protocol Handler" ;
// Verify the command line arguments
if (args .Length == 0 || !args [0].StartsWith (prefix ))
{ MessageBox .Show ("Syntax:/nrunapp://<key>" , title ); return ; }
// Obtain the part of the protocol we're interested in
string key = Regex .Match (args [0], @"(?<=://).+?(?=:|/|/Z)" ).Value ;
// Path to the configuration file
string file = Path .Combine (Path .GetDirectoryName (
Assembly .GetExecutingAssembly ().Location ), "RegisteredApps.xml" );
// Load the config file
XmlDocument xml = new XmlDocument ();
xml .Load (file );
// Locate the app to run
XmlNode node = xml .SelectSingleNode (
String .Format ("/RunApp/App[@key='{0}']" , key ));
// If the app is not found, let the user know
if (node == null )
{ MessageBox .Show ("Key not found: " + key , title ); return ; }
// Resolve the target app name
string target = Environment .ExpandEnvironmentVariables (
node .SelectSingleNode ("@target" ).Value );
// Pull the command line args for the target app if they exist
string procargs = node .SelectSingleNode ("@args" ) != null ?
node .SelectSingleNode ("@args" ).Value : "" ;
// Start the application
Process .Start (target , procargs );
}
}
}
References
-
C# Source Code: RunAppUrlProtocol.zip