我想将自定义URL协议(例如myprotocol://SomeFolder/SomePage
)与ClickOnce应用程序相关联。
我可以毫无问题地创建关联 - 问题是每次更新应用程序(经常更新)时,EXE 文件的路径都会更改。
有没有办法解决这个问题?
似乎这个问题的答案是你不能,但是我确实想出了一个解决方案。
我创建了一个启动器(非常简单的应用程序),它可以找到快捷方式并将其启动参数传递给 ClickOnce 应用程序。我需要以传统方式安装启动器,但仍可以在需要时通过 ClickOnce 更新主应用程序。
我发现这些链接很有用:
安装应用程序后,系统会在开始菜单中创建一个链接。该链接实际上是一个带有“appref-ms”扩展名的文件。因此,诀窍是注册一个将使用“appref-ms”打开应用程序的协议。
因此,当您的 ClickOnce 应用程序启动时,您可以创建以下注册表项来注册您的协议。HKEY_CLASSES_ROOT myprotocol = {协议描述} shell 打开命令 = explorer %1
就是这样。现在,当有人单击 myprotocol: XXX 之类的 url 时,您的应用程序将被打开并以“作为 ClickOnce”应用程序的方式打开,因此它将检查是否有新版本等。
如果您尝试 ClickOnce 已经将适当的密钥添加到 HKCR,只是没有所需的 URL 协议值。我将此代码添加到我的应用程序逻辑的开头:
try
{
RegistryKey rk = Registry.ClassesRoot.OpenSubKey("MyProgramName", true);
rk.SetValue("URL Protocol", "");
}
catch (Exception ex)
{
// handle, log, etc.
}
效果很好,因为这就是我希望 URL 协议引用的内容(例如“ MyProgramName://....
”。我能够在我的应用程序没有管理权限的情况下成功地做到这一点 - 如果我试图注册不同的处理程序,也许它是必需的,所以 YMMV. 至少,查看其中的值应该让您了解如何正确启动应用程序。
这是默认创建的注册表项:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\MyAppName]
@="Electronic Data Interchange (EDI) File"
"AppId"="MyAppName.application, Culture=neutral, PublicKeyToken=31fc6d113f9bb401, processorArchitecture=msil"
"DeploymentProviderUrl"="file://server/share/MyAppName/MyAppName.application"
"Guid"="{MY_APP_GUID}"
[HKEY_CLASSES_ROOT\MyAppName\shell]
@="open"
[HKEY_CLASSES_ROOT\MyAppName\shell\open]
[HKEY_CLASSES_ROOT\MyAppName\shell\open\command]
@="rundll32.exe dfshim.dll, ShOpenVerbExtension {MY_APP_GUID} %1"
[HKEY_CLASSES_ROOT\MyAppName\shellex]
[HKEY_CLASSES_ROOT\MyAppName\shellex\IconHandler]
@="{MY_APP_GUID}"
我发布的代码只是在节点URL Protocol
下添加了一个空值。MyAppName
为此,我制作了一个 npm 模块。
这是链接。
因此,要在 nodejs 中执行此操作,您只需要运行以下代码:
首先安装它
npm i protocol-registry
然后使用下面的代码注册你的入口文件。
const path = require('path');
const ProtocolRegistry = require('protocol-registry');
console.log('Registering...');
// Registers the Protocol
ProtocolRegistry.register({
protocol: 'testproto', // sets protocol for your command , testproto://**
command: `node ${path.join(__dirname, './index.js')} $_URL_`, // $_URL_ will the replaces by the url used to initiate it
override: true, // Use this with caution as it will destroy all previous Registrations on this protocol
terminal: true, // Use this to run your command inside a terminal
script: false
}).then(async () => {
console.log('Successfully registered');
});
然后假设有人打开testproto://test
然后一个新的终端将被启动执行:
node yourapp/index.js testproto://test
该模块处理所有跨平台的东西。