如何在Windows 8上正确注册协议处理程序?

9
我有一个处理tel:协议链接的小项目。这是一个桌面应用程序,我正在使用Visual Studio 2013 Community Edition进行开发。
以前,我曾经通过简单的注册表修改来注册处理程序:
Microsoft.Win32.Registry.SetValue(registryKey, string.Empty, registryValue, Microsoft.Win32.RegistryValueKind.String);
Microsoft.Win32.Registry.SetValue(registryKey, "URL Protocol", String.Empty, Microsoft.Win32.RegistryValueKind.String);

registryKey = @"HKEY_CLASSES_ROOT\tel\shell\open\command";
registryValue = "\"" + AppDomain.CurrentDomain.BaseDirectory + "TelProtocolHandler.exe\" \"%1\"";
Microsoft.Win32.Registry.SetValue(registryKey, string.Empty, registryValue, Microsoft.Win32.RegistryValueKind.String);

然而,在 Windows 8 上似乎无法这样操作。尽管注册表键具有所需的值,但链接仍由其他应用程序处理。 我的工具甚至没有出现在协议处理程序选择中:

enter image description here

我看过使用Windows 8自定义协议激活的演示文稿,但是我无法将所提到的信息与我的应用程序联系起来。该文章提到了一个.appxmanifest文件,但我在我的项目中没有这个文件,也无法将其添加为新项目。

你的应用程序是Windows商店应用程序还是桌面应用程序?你使用的是哪个Visual Studio版本?| 你在链接文章的哪个部分遇到了问题?你应该能够在项目设置的协议列表中添加“tel:”,然后它应该出现在用户可以选择协议处理程序的列表中。 - CodesInChaos
@CodesInChaos:这是一个桌面应用程序。我正在使用VS2013社区版。文章中提到了一个清单文件,但我在我的项目中没有这个文件,似乎也无法添加进去。文章明确提到了那个清单文件,而我并没有这个文件。 - Oliver Salzburg
1个回答

13

在提问之后,我偶然发现了如何在Windows 8中注册协议处理程序

那里排名最高的答案让我找到了正确的方向,尽管还存在其他问题。最终,这是我得出的结果:

// Register as the default handler for the tel: protocol.
const string protocolValue = "TEL:Telephone Invocation";
Registry.SetValue(
    @"HKEY_CLASSES_ROOT\tel",
    string.Empty,
    protocolValue,
    RegistryValueKind.String );
Registry.SetValue(
    @"HKEY_CLASSES_ROOT\tel",
    "URL Protocol",
    String.Empty,
    RegistryValueKind.String );

const string binaryName = "tel.exe";
string command = string.Format( "\"{0}{1}\" \"%1\"", AppDomain.CurrentDomain.BaseDirectory, binaryName );
Registry.SetValue( @"HKEY_CLASSES_ROOT\tel\shell\open\command", string.Empty, command, RegistryValueKind.String );

// For Windows 8+, register as a choosable protocol handler.

// Version detection from https://dev59.com/sGYr5IYBdhLWcg3wg6b9#17796139
Version win8Version = new Version( 6, 2, 9200, 0 );
if( Environment.OSVersion.Platform == PlatformID.Win32NT &&
    Environment.OSVersion.Version >= win8Version ) {
    Registry.SetValue(
        @"HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TelProtocolHandler",
        string.Empty,
        protocolValue,
        RegistryValueKind.String );
    Registry.SetValue(
        @"HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TelProtocolHandler\shell\open\command",
        string.Empty,
        command,
        RegistryValueKind.String );

    Registry.SetValue(
        @"HKEY_LOCAL_MACHINE\SOFTWARE\TelProtocolHandler\Capabilities\URLAssociations",
        "tel",
        "TelProtocolHandler",
        RegistryValueKind.String );
    Registry.SetValue(
        @"HKEY_LOCAL_MACHINE\SOFTWARE\RegisteredApplications",
        "TelProtocolHandler",
        @"SOFTWARE\TelProtocolHandler\Capabilities",
        RegistryValueKind.String );
}

TelProtocolHandler是我的应用程序名称,应该替换为您处理程序的名称。

其他问题中接受的答案在注册表中也有ApplicationDescription。我没有看到其他已检查的注册处理程序中具有相同的键,因此我将其省略并未检测到任何问题。

另一个关键问题是,如果设置处理程序的应用程序是32位的,则所有这些都不起作用。当在Wow6432Node中进行条目输入时,我无法选择处理程序作为给定协议的默认值。我花了一些时间才发现这一点,因为我的应用程序编译为AnyCPU。我最初忽略的是项目属性中的这个小标志:

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接