How do I register a custom URL protocol in Windows? - windows

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?

Go to Start then in Find type regedit -> it should open Registry editor
Click Right Mouse on HKEY_CLASSES_ROOT then New -> Key
In the Key give the lowercase name by which you want urls to be called (in my case it will be testus://sdfsdfsdf) then Click Right Mouse on testus -> then New -> String Value and add URL Protocol without value.
Then add more entries like you did with protocol ( Right Mouse 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"
To test if it works go to Internet Explorer (not Chrome or Firefox) and enter 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.

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.

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\""
Pasted that into notepad, the 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

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.

Related

Xamarin Windows cannot access the specified device, path, or file

I have a Xamarin application running on Windows, and I have a method which includes an opening of a pdf file like this:
var psi = new ProcessStartInfo
{
FileName = "cmd",
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false,
CreateNoWindow = true,
Arguments = $"/c start {filename}"
};
Process.Start(psi);
When this executes, the windows opens a dialog with the following message:
Windows cannot access the specified device, path, or file. You may not have the appropriate permissions to access the item.
The filename is a pdf file located in the LocalApplicationData, and I also have a database there, and the application is normally creating a database there and manipulates with it, so it should have a permission to access that folder. Also, when I run that pdf with double-click outside the application, the pdf opens normally with Chrome. How to solve this?
Unless you have a file there called "cmd" this won't work, as you have declared your filename as a string with the value "cmd".

xcode lauch Arbuments - return Null in final Build

I just finished a Mac OS X App with xCode that allows you to be launched with a Paraneter which is used to build an URL that will query a web Service etc...
So after reading around, i can to the solution, 2Eviroment " Variables are the used Method for this...
So i went to Sheme, aded an environment Variable with a Value, and tried to era it from my .m file, to construct the URL for a Web View
As a Control Instance i set the Window Title to contain the Argument
In xCode this works so far flawlessly, but after building my App, i save it to desktop, i open Terminal and send this:
open -a MonstAr.app --args "searchkey=test"
the "search key" is the variable where it is searched for and grabbed the value,
but in the final build, this doesn't work,
the part where i read the variable for the title, it returns "NULL" as a string and for the Web View URL, it uses the predefined Variable i set in xCode Sheme
In my .m file i use this code to read the Variables:
NSString *string1, *string2, *myString, *pre, *arg1, *arg2,*title;
arg1 = [[[NSProcessInfo processInfo] environment] objectForKey:#"searchkey"];
I tried to use "arguments" instead of environment, but this throws an error in Xcode...
Can someone help? thx

Cannot set File association with my program under development

Windows 7 - I can't associate the executable I'm programming to the file type it create.
I'm using (2 ways) to get the "Open with dialog":
1 -------------------
Control Panel - Default Programs - Associate a file type or protocol with a program
I select my file extension and then press "Change program"
2 -------------------
Double click my document file (which does not have any extension yet)
Select "Select a program from a list of installed programs"
In both cases, I get "Open With" dialog.
Problem description:
I can browse for my .exe file but when I select it ("Open" in "Open With..." file selection dialog box)... nothing happen. No new file appears in the section of available executable of the "open With" dialog.
Why it does not work ???
Permissions ? Corrupted registry ? New rules ?
Here is what you should do :
Make sure your application is handling the arguments correctly. When you open an associated file type with an application, It would be equivalent of executing this command in cmd
YourApp.exe "C:\Path\fileName.ext"
So C:\Path\fileName.ext would be passed as an argument to your application.
Your main class should look something like this :
static void Main(string[] args) { ... }
Check for filePath in args and write the code to load the read the file.
You need to associate file extension with the Application. You can either do it via Control Panel or by browsing the App in Open With window. (This you have already done)
Edit : Try using these registries to associate file type with your application :
[HKEY_CURRENT_USER\Software\Classes\<fileExt>]
#="<fileClass>"
[HKEY_CURRENT_USER\Software\Classes\<fileClass>]
[HKEY_CURRENT_USER\Software\Classes\<fileClass>\OpenWithList]
[HKEY_CURRENT_USER\Software\Classes\<fileClass>\OpenWithList\<appName>]
[HKEY_CURRENT_USER\Software\Classes\Applications\<appName>]
[HKEY_CURRENT_USER\Software\Classes\Applications\<appName>\shell]
[HKEY_CURRENT_USER\Software\Classes\Applications\<appName>\shell\open]
[HKEY_CURRENT_USER\Software\Classes\Applications\<appName>\shell\open\command]
#="\"C:\\Program Files\\appFolder\\<appName>\" \"%1\""
[HKEY_CURRENT_USER\Software\Classes\Applications\<appName>\SupportedTypes]
"<fileExt>"=""

Creating Custom Protocol (Windows 7)

I've been trying to create a custom protocol (open_php_file://) to open local files through the browser. I've created the following registery-keys:
HKEY_CLASSES_ROOT
open_php_file
(Default) = "URL:PHPEd protocol"
URL Protocol = ""
DefaultIcon
(Default) = "phped.exe"
shell
open
command
(Default) = "C:\Program Files (x86)\NuSphere\7.0\phped.exe" "%1"
The problem is: I can't open files in my browser (example: open_php_file://c:\file.txt), and the protocol isn't listed in the windows default programms.
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\openphpfile]
#="\"URL:openphpfile Protocol\""
"EditFlags"=hex:02,00,00,00
"URL Protocol"=""
[HKEY_CLASSES_ROOT\openphpfile\DefaultIcon]
#="\"C:\\Users\\ABC\\Documents\\Programs\\CB\\Chunks\\CGI.exe\",0"
[HKEY_CLASSES_ROOT\openphpfile\shell]
[HKEY_CLASSES_ROOT\openphpfile\shell\open]
[HKEY_CLASSES_ROOT\openphpfile\shell\open\command]
#="\"C:\\Users\\ABC\\Documents\\Programs\\CB\\Chunks\\CGI.exe\" -c \"%1\""
Basically the problem was with the underscores in your protocol.Once removed everything started working fine.You can change the path of executable as per your wish i.e. "C:\Program Files (x86)\NuSphere\7.0\phped.exe".
I tried openphpfile:blast and it worked quite nicely :)
EDIT:
the problem with this solution is that %1 gets replaced with
"open_php_file://[file]" instead of just "[file]". This way I need
some sort of filter that chops "open_php_file://".
put a space after openphpfile:[Space]Your_Content and change parameter to %2 you will get the expected result
[HKEY_CLASSES_ROOT\openphpfile\shell\open\command]
#="\"C:\\Users\\ABC\\Documents\\Programs\\CB\\Chunks\\CGI.exe\" -c \"%2\""
Windows always replaces %1 with the full URI that was entered. AFAIK there is no way to change that behavior.
This leaves you two options:
If you've written the program being called yourself, you can filter the URI when it is being invoked.
You could use an intermediate program that acts as a filter for the URI and then forwards the result to the actual protocol implementation. Fortunately for you, someone has already done exactly that. See 'CustomURL' on CodePlex. CustomURL is a small utility for registering custom URL protocols. For example you can associate the rdp:// protocol with Remote Desktop Client or the ssh:// protocol with Putty or another SSH client.

How can I make org-protocol work on Openbox?

I tried the instructions - I am using Firefox on Lubuntu (Openbox). But I get the error
"Firefox doesn't know how to open this address, because the protocol (org-protocol) isn't associated with any program".
How should I fix this?
The following steps for setting up org-protocol work with Ubuntu 16.04 (Xenial Xerus) and presumably later versions. Org-mode is assumed to have already been set-up (and installed using apt-get install org-mode or via the ELPA repository).
Set-up
Add .desktop file
Create and save a file called org-protocol.desktop to ~/.local/share/applications containing:
[Desktop Entry]
Name=org-protocol
Exec=emacsclient %u
Type=Application
Terminal=false
Categories=System;
MimeType=x-scheme-handler/org-protocol;
Then run:
$ update-desktop-database ~/.local/share/applications/
This step makes Firefox aware that "org-protocol" is a valid scheme-handler or protocol (by updating ~/.local/share/applications/mimeinfo.cache), and causes Firefox to prompt for a program to use when opening these kinds of links.
Add config settings to ~/.emacs.d/init.el (or ~/.emacs) file
Have the following settings in your Emacs configuration file:
(server-start)
(require 'org-protocol)
Also add some template definitions to the configuration file, for example:
(setq org-protocol-default-template-key "l")
(setq org-capture-templates
'(("t" "Todo" entry (file+headline "/path/to/notes.org" "Tasks")
"* TODO %?\n %i\n %a")
("l" "Link" entry (file+olp "/path/to/notes.org" "Web Links")
"* %a\n %?\n %i")
("j" "Journal" entry (file+datetree "/path/to/journal.org")
"* %?\nEntered on %U\n %i\n %a")))
Now run Emacs.
Create your notes.org file
Assuming you use the capture templates defined in step 2, you will need to prepare a notes.org file at the location you specified in step 2. You must create this file -- if it is not created along with the headlines specified in step 2, org-mode will just give a warning when you try to capture web-pages. So, given the capture templates from step 2, notes.org should contain the following:
* Tasks
* Web Links
Add bookmarklet(s) to Firefox
Save bookmark to toolbar containing something like the following as the location:
javascript:location.href='org-protocol://capture?template=l&url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)+'&body='+encodeURIComponent(window.getSelection())
If you are using an older version of org-mode, you may need to use the following instead:
javascript:location.href='org-protocol://capture://l/'+encodeURIComponent(location.href)+'/'+encodeURIComponent(document.title)+'/'+encodeURIComponent(window.getSelection())
Notice the 'l' (lowercase L) in the above URL -- this is what chooses the capture template (automatically) -- it is the key one would normally have to press when capturing with org-mode via C-c c.
When you click on this bookmarklet, Firefox will ask what program to use to handle the "org-protocol" protocol. You can simply choose the default program that appears ("org-protocol").
Using it
(Optionally) select some text on a webpage you're viewing in Firefox. When you click on the bookmarklet, the link and selected text will be placed in the Emacs capture buffer. Go to Emacs, modify the capture buffer as desired, and press C-c C-c to save it.
Add protocol handler
Create file ~/.local/share/applications/org-protocol.desktop containing:
[Desktop Entry]
Name=org-protocol
Exec=emacsclient %u
Type=Application
Terminal=false
Categories=System;
MimeType=x-scheme-handler/org-protocol;
Note: Each line's key must be capitalized exactly as displayed, or it will be an invalid .desktop file.
Then update ~/.local/share/applications/mimeinfo.cache by running:
On GNOME:
update-desktop-database ~/.local/share/applications/
On KDE:
kbuildsycoca4
Configure Emacs
Init file
Add to your Emacs init file:
(server-start)
(require 'org-protocol)
Capture template
You'll probably want to add a capture template something like this:
("w" "Web site"
entry
(file+olp "/path/to/inbox.org" "Web")
"* %c :website:\n%U %?%:initial")
Note: Using %:initial instead of %i seems to handle multi-line content better.
This will result in a capture like this:
\* [[http://orgmode.org/worg/org-contrib/org-protocol.html][org-protocol.el – Intercept calls from emacsclient to trigger custom actions]] :website:
[2015-09-29 Tue 11:09] About org-protocol.el
org-protocol.el is based on code and ideas from org-annotation-helper.el and org-browser-url.el.
Configure Firefox
Expose protocol-handler
On some versions of Firefox, it may be necessary to add this setting. You may skip this step and come back to it if you get an error saying that Firefox doesn't know how to handle org-protocol links.
Open about:config and create a new boolean value named network.protocol-handler.expose.org-protocol and set it to true.
Note: If you do skip this step, and you do encounter the error, Firefox may replace all open tabs in the window with the error message, making it difficult or impossible to recover those tabs. It's best to use a new window with a throwaway tab to test this setup until you know it's working.
Make bookmarklet
Make a bookmarklet with the location:
javascript:location.href='org-protocol://capture://w/'+encodeURIComponent(location.href)+'/'+encodeURIComponent(document.title)+'/'+encodeURIComponent(window.getSelection())
Note: The w in the URL chooses the corresponding capture template. You can leave it out if you want to be prompted for the template.
When you click on this bookmarklet for the first time, Firefox will ask what program to use to handle the org-protocol protocol. If you are using Ubuntu 12.04 (Precise Pangolin), you must add the /usr/bin/emacsclient program, and choose it. With Ubuntu 12.10 (Quantal Quetzal) or later, you can simply choose the default program that appears (org-protocol).
You can select text in the page when you capture and it will be copied into the template, or you can just capture the page title and URL.
Tridactyl
If you're using Tridactyl, you can map key sequences something like this:
bind cc js location.href='org-protocol://capture://w/'+encodeURIComponent(content.location.href)+'/'+encodeURIComponent(content.document.title)+'/'+encodeURIComponent(content.document.getSelection())
You might also want to add one for the `store-link` sub-protocol, like:
bind cl js location.href='org-protocol://store-link://'+encodeURIComponent(content.location.href)+'/'+encodeURIComponent(content.document.title)
Capture script
You may want to use this script to capture input from a terminal, either as an argument or piped in:
#!/bin/bash
if [[ $# ]]
then
data="$#"
else
data=$(cat)
fi
if [[ -z $data ]]
then
exit 1
fi
encoded=$(python -c "import sys, urllib; print urllib.quote(' '.join(sys.argv[1:]), safe='')" "${data[#]}")
# "link" and "title" are not used, but seem to be necessary to get
# $encoded to be captured
emacsclient "org-protocol://capture://link/title/$encoded"
Then you can capture input from the shell like this:
tail /var/log/syslog | org-capture
org-capture "I can capture from a terminal!"
These instructions are more up-to-date than the ones in Mark's answer.

Resources