24 Aug 2010

onebit_26

Note: This is part of a series, you can find the rest of the parts in the series index.

I’ve mentioned previously about Pull’s support for protocol handlers (see part 4) which enable the application to subscribe to a feed easily just by clicking a link. Today I will look at how I to register protocol handlers.

image

Protocol Handlers

Registering a protocol handler is one of the simplest things I did in Pull, because it is merely a registry key which needs to be added to the system. The registry key follows the pattern below.

Key

  • blue = registry key
  • orange = key/value setting

image

The important points (numbered above) are:

  1. This is the protocol that you want to register, so if you want to register say zune:// then this is zune.
  2. This is a useful description on the default key.
  3. This is a setting named URL Protocol but the value must remain blank.
  4. This is path to the icon. So for Pull I just use the default program icon by setting the value to: E:\PortableApps\Pull\Pull.exe,1
  5. This is the command to execute when the URL is added. In Pull this is (note the %1 for the URL parameter): "E:\PortableApps\Pull\Pull.exe" "%1"

The code to do this is rather simple:

public static void Register(string executablePath, string uri)
{
    if (!OurProtocolHandler(uri))
    {
        return;
    }

    using (RegistryKey uriKey = Registry.ClassesRoot.CreateSubKey(uri, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryOptions.None))
    {
        uriKey.SetValue(string.Empty, Pull.Properties.Resources.PullPodcastURIHandler);
        uriKey.SetValue("URL Protocol", string.Empty, RegistryValueKind.String);
        using (RegistryKey iconKey = uriKey.CreateSubKey("DefaultIcon", RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryOptions.None))
        {
            iconKey.SetValue(string.Empty, string.Format(CultureInfo.CurrentCulture, "{0},1", executablePath));
        }

        using (RegistryKey shellKey = uriKey.CreateSubKey("shell", RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryOptions.None))
        {
            using (RegistryKey openKey = shellKey.CreateSubKey("open", RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryOptions.None))
            {
                using (RegistryKey commandKey = openKey.CreateSubKey("command", RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryOptions.None))
                {
                    commandKey.SetValue(string.Empty, string.Format(CultureInfo.CurrentCulture, "\"{0}\" \"%1\"", executablePath));
                }
            }
        }
    }
}

Being a good citizen

Pull is aware that some people may have other podcatchers installed, and to make sure I do not steal their protocol handlers I have a simple method, OurProtocolHandler, which checks if the protocol is in use and if a protocol is in use we do not override it.

private static bool OurProtocolHandler(string uri)
{
    using (RegistryKey uriKey = Registry.ClassesRoot.OpenSubKey(uri))
    {
        if (Registry.ClassesRoot.OpenSubKey(uri) != null)
        {
            return uriKey.GetValue(string.Empty).Equals(Pull.Properties.Resources.PullPodcastURIHandler);
        }
        else
        {
            return true;
        }
    }
}

Final Thoughts

This is one of the easiest parts to get working, however incorporating it in the application is not as simple which I will cover next.

Add new comment