Reputation: 4758
How do I register a custom protocol with Windows so that when clicking a link in an email or on a web page my application is opened and the parameters from the URL are passed to it?
Upvotes: 169
Views: 172508
Reputation: 867
If anyone wants a .reg file for creating the association, see below:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\duck]
"URL Protocol"=""
[HKEY_CLASSES_ROOT\duck\shell]
[HKEY_CLASSES_ROOT\duck\shell\open]
[HKEY_CLASSES_ROOT\duck\shell\open\command]
@="\"C:\\Users\\duck\\source\\repos\\ConsoleApp1\\ConsoleApp1\\bin\\Debug\\net6.0\\ConsoleApp1.exe\" \"%1\""
Paste that into notepad, then file -> save as -> duck.reg, and then run it. After running it, when you type duck://arg-here
into chrome, ConsoleApp1.exe will run with "arg-here" as an argument. Double slashes are required for the path to the exe and double quotes must be escaped.
Tested and working on Windows 11 with Edge (the chrome version) and Chrome
Upvotes: 25
Reputation: 61399
Go to Start
then in Find
type regedit
-> it should open Registry editor
Click Right Mouse on HKEY_CLASSES_ROOT
then New
-> Key
testus://sdfsdfsdf
) then Click Right Mouse on testus
-> then New
-> String Value
and add URL Protocol
without value.New
-> Key
) and create hierarchy like testus
-> shell
-> open
-> command
and inside command
change (Default)
to the path where .exe
you want to launch is, if you want to pass parameters to your exe then wrap path to exe in ""
and add "%1"
to look like: "c:\testing\test.exe" "%1"
testus:have_you_seen_this_man
this should fire your .exe
(give you some prompts that you want to do this - say Yes) and pass into args testus://have_you_seen_this_man
.Here's sample console app to test:
using System;
namespace Testing
{
class Program
{
static void Main(string[] args)
{
if (args!= null && args.Length > 0)
Console.WriteLine(args[0]);
Console.ReadKey();
}
}
}
Hope this saves you some time.
Upvotes: 178
Reputation: 1097
To further the existing answers a bit more, the application invoked to handle the protocol does not have to be a compiled application. It can also be a script file.
For example, you could create a Windows batch file - such as that below to - handle the call. Let us assume you save that script to c:\temp\testprotocol-handler.bat
.
REM just echo the passed argument
echo off
echo Hello from the custom protocol handling script.
echo script name: %0
echo script arg : %1
pause
Use the following registry configuration to map the script to the protocol testprotocol
.
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\testprotocol]
"URL Protocol"=""
[HKEY_CLASSES_ROOT\testprotocol\shell]
[HKEY_CLASSES_ROOT\testprotocol\shell\open]
[HKEY_CLASSES_ROOT\testprotocol\shell\open\command]
@="\"C:\\temp\\testprotocol-handler.bat\" \"%1\""
When the OS encounters the protocol it will execute the script - opening a command window and displaying the content of the echo
statements in the script.
Upvotes: 3
Reputation: 179907
[Obsolete - the MSDN information has been replaced by a new page which does address the security concerns]
The MSDN link is nice, but the security information there isn't complete. The handler registration should contain "%1", not %1. This is a security measure, because some URL sources incorrectly decode %20 before invoking your custom protocol handler.
PS. You'll get the entire URL, not just the URL parameters. But the URL might be subject to some mistreatment, besides the already mentioned %20->space conversion. It helps to be conservative in your URL syntax design. Don't throw in random // or you'll get into the mess that file:// is.
Upvotes: 25
Reputation: 596
There is an npm module for this purpose.
link :https://www.npmjs.com/package/protocol-registry
So to do this in nodejs you just need to run the code below:
First Install it
npm i protocol-registry
Then use the code below to register you entry file.
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');
});
Then suppose someone opens testproto://test then a new terminal will be launched executing :
node yourapp/index.js testproto://test
It also supports all other operating system.
Upvotes: 8