在 Windows 8 上的 C# 中注册自定义 URL 处理程序

Xyp*_*hos 2 c# windows-8

using System;
using System.Windows.Forms;
using Microsoft.Win32;

namespace Aodb
{
    internal static class AodbProtocol
    {
        private const string _Protocol = "aodb";
        private const string _ProtocolHandler = "url.aodb";

        private static readonly string _launch = string.Format(
            "{0}{1}{0} {0}%1{0}", (char)34, Application.ExecutablePath);

        private static readonly Version _win8Version = new Version(6, 2, 9200, 0);

        private static readonly bool _isWin8 =
            Environment.OSVersion.Platform == PlatformID.Win32NT &&
            Environment.OSVersion.Version >= _win8Version;

        internal static void Register()
        {
            if (_isWin8) RegisterWin8();
            else RegisterWin7();
        }

        private static void RegisterWin7()
        {
            var regKey = Registry.ClassesRoot.CreateSubKey(_Protocol);
            regKey.SetValue(null, "URL:aodb Protocol");
            regKey.SetValue("URL Protocol", "");

            regKey = regKey.CreateSubKey(@"shell\open\command");
            regKey.SetValue(null, _launch);
        }

        private static void RegisterWin8()
        {
            var regKey = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Classes")
                .CreateSubKey(_ProtocolHandler);

            regKey.SetValue(null, _Protocol);

            regKey.CreateSubKey("DefaultIcon")
                .SetValue(null, string.Format(
                    "{0}{1},1{0}", "\"", Application.ExecutablePath));

            regKey.CreateSubKey(@"shell\open\command").SetValue(null, _launch);

            Registry.LocalMachine.CreateSubKey(string.Format(
                @"SOFTWARE\{0}\{1}\Capabilities\ApplicationDescription\URLAssociations",
                Application.CompanyName, Application.ProductName))
                .SetValue(_Protocol, _ProtocolHandler);

            Registry.LocalMachine.CreateSubKey(@"SOFTWARE\RegisteredApplications")
                .SetValue(Application.ProductName, string.Format(
                    @"SOFTWARE\{0}\Capabilities", Application.ProductName));
        }

        internal static void Unregister()
        {
            if (!_isWin8)
            {
                Registry.ClassesRoot.DeleteSubKeyTree("aodb", false);
                return;
            }

            // extra work required.
            Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Classes")
                .DeleteSubKeyTree(_ProtocolHandler, false);

            Registry.LocalMachine.DeleteSubKeyTree(string.Format(@"SOFTWARE\{0}\{1}",
                Application.CompanyName, Application.ProductName));

            Registry.LocalMachine.CreateSubKey(@"SOFTWARE\RegisteredApplications")
                .DeleteValue(Application.ProductName);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的类是从我在网上找到的代码片段拼凑起来的,具体来说:

http://dotnet-snippets.com/snippet/register-user-defined-url-protocol/2707 <-- 适用于 Win7 但不适用于 Win8

这让我找到了在 Windows 8 中注册协议处理程序,这是一个未经证实的答案。

但是,我无法让 URL 协议在 Win8 中工作;单击aodb://1234超链接不会启动该应用程序,并且 Web 浏览器抱怨该协议不受支持,我认为上述文章不是正确答案。

有没有了解协议处理程序的人知道我在上面的代码中哪里出错了以及为什么该协议没有在 win8 中注册?通过查看 regedit 中的注册表项,我可以看到上述代码有效,但由于某种原因,无法识别该协议。

Xyp*_*hos 5

我知道了!最后。好吧,看来Win8及以上的Win7和Win8的注册表功能都要实现,不过Win7不需要额外的代码。下面是注册自定义协议的最后一个类。

using System;
using System.Windows.Forms;
using Microsoft.Win32;

namespace Aodb
{
    internal static class AodbProtocol
    {
        private const string _Protocol = "aodb";
        private const string _ProtocolHandler = "url.aodb";

        private static readonly string _launch = string.Format(
            "{0}{1}{0} {0}%1{0}", (char)34, Application.ExecutablePath);

        private static readonly Version _win8Version = new Version(6, 2, 9200, 0);

        private static readonly bool _isWin8 =
            Environment.OSVersion.Platform == PlatformID.Win32NT &&
            Environment.OSVersion.Version >= _win8Version;

        internal static void Register()
        {
            if (_isWin8) RegisterWin8();
            else RegisterWin7();
        }

        private static void RegisterWin7()
        {
            var regKey = Registry.ClassesRoot.CreateSubKey(_Protocol);

            regKey.CreateSubKey("DefaultIcon")
                .SetValue(null, string.Format("{0}{1},1{0}", (char)34, 
                    Application.ExecutablePath));

            regKey.SetValue(null, "URL:aodb Protocol");
            regKey.SetValue("URL Protocol", "");

            regKey = regKey.CreateSubKey(@"shell\open\command");
            regKey.SetValue(null, _launch);
        }

        private static void RegisterWin8()
        {
            RegisterWin7();

            var regKey = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Classes")
                .CreateSubKey(_ProtocolHandler);

            regKey.SetValue(null, _Protocol);

            regKey.CreateSubKey("DefaultIcon")
                 .SetValue(null, string.Format("{0}{1},1{0}", (char)34,
                     Application.ExecutablePath));

            regKey.CreateSubKey(@"shell\open\command").SetValue(null, _launch);

            Registry.LocalMachine.CreateSubKey(string.Format(
                @"SOFTWARE\{0}\{1}\Capabilities\ApplicationDescription\URLAssociations",
                Application.CompanyName, Application.ProductName))
                .SetValue(_Protocol, _ProtocolHandler);

            Registry.LocalMachine.CreateSubKey(@"SOFTWARE\RegisteredApplications")
                .SetValue(Application.ProductName, string.Format(
                    @"SOFTWARE\{0}\Capabilities", Application.ProductName));
        }

        internal static void Unregister()
        {
            if (!_isWin8)
            {
                Registry.ClassesRoot.DeleteSubKeyTree("aodb", false);
                return;
            }

            // extra work required.
            Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Classes")
                .DeleteSubKeyTree(_ProtocolHandler, false);

            Registry.LocalMachine.DeleteSubKeyTree(string.Format(@"SOFTWARE\{0}\{1}",
                Application.CompanyName, Application.ProductName));

            Registry.LocalMachine.CreateSubKey(@"SOFTWARE\RegisteredApplications")
                .DeleteValue(Application.ProductName);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)