How to escape & ampersand in Custom protocol handler in Windows - windows

I made a custom protocol handler following this link. The case is I need to open a link which can only be opened in IE and might contains several query parameters and should be opened in IE from our web app which is running on Chrome (this is really annoying). After many tries and fails, I managed to find the snippet to add entry to the windows registry hive and made .reg file and run:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Classes\ie]
"URL Protocol"="\"\""
#="\"URL:IE Protocol\""
[HKEY_CURRENT_USER\Software\Classes\ie\DefaultIcon]
#="\"explorer.exe,1\""
[HKEY_CURRENT_USER\Software\Classes\ie\shell]
[HKEY_CURRENT_USER\Software\Classes\ie\shell\open]
[HKEY_CURRENT_USER\Software\Classes\ie\shell\open\command]
#="cmd /k set myvar=%1 & call set myvar=%%myvar:ie:=%% & call \"C:\\Program Files (x86)\\Internet Explorer\\iexplore.exe\" %%myvar%% & exit /B"
It worked but the problem is if a link contains more than 1 query params, all but the first are omitted, I am sure this because of character encoding in windows command line:
e.g. some_example_url?query1=value1&query2=value2&query3=value3 is becoming some_example_url?query1=value1
I find this solution but it did not work either. How can I properly escape & character, so that it can be opened on IE with all query parameters. (as before mentioned link is triggered by web app running on Chrome)
EDIT: The code which triggers:
fileClicked(url) {
// url should be escaped with ^
const escapedUrl = url.replace(/&/gi, '^&');
const ie = document.createElement('a');
// ie: scheme => custom protocol handler
// host computer (windows) should add custom protocol to windows registry
ie.href = `ie:${escapedUrl}`;
ie.click();
}
EDIT 2
#muzafako fixed the script, just last line should be replaced like below:
#="cmd /c set url=\"%1\" & call set url=%%url:ie:=%% & call start iexplore -nosessionmerging -noframemerging %%url%%"

You don't need to decode query parameters at all. I've tried to find solution for this issue and saw this answer. Its works for me. just change command line to:
#="cmd /c set url=\"%1\" & call set url=%%url:ie:=%% & call start iexplore -nosessionmerging -noframemerging %%url%%"

Related

Open Internet Explorer from Chrome using a protocol handler (ie:url)

I've followed these steps and it doesn't work correctly for me.
Custom protocol handler in chrome
Basically, I don't have a custom app. I just want to create an handler to open IE with a specific URL.
Here are my reg:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Classes\ie]
"URL Protocol"="\"\""
#="\"URL:IE Protocol\""
[HKEY_CURRENT_USER\Software\Classes\ie\DefaultIcon]
#="\"explorer.exe,1\""
[HKEY_CURRENT_USER\Software\Classes\ie\shell]
[HKEY_CURRENT_USER\Software\Classes\ie\shell\open]
[HKEY_CURRENT_USER\Software\Classes\ie\shell\open\command]
#="\"C:\\Program Files\\Internet Explorer\\iexplore.exe\" \"%1\""
It's working but... when I'm opening ie:www.google.com from Chrome, it ask to open IE but it keeps the "ie:" in the opened URL... which generate a endless loop.
How can I fix that?
Thanks
Create a Protocol Handler
save this script as internet-explorer-protocol-handler.reg:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Classes\ie]
"URL Protocol"="\"\""
#="\"URL:IE Protocol\""
[HKEY_CURRENT_USER\Software\Classes\ie\DefaultIcon]
#="\"explorer.exe,1\""
[HKEY_CURRENT_USER\Software\Classes\ie\shell]
[HKEY_CURRENT_USER\Software\Classes\ie\shell\open]
[HKEY_CURRENT_USER\Software\Classes\ie\shell\open\command]
#="cmd /k set myvar=%1 & call set myvar=%%myvar:ie:=%% & call \"C:\\Program Files (x86)\\Internet Explorer\\iexplore.exe\" %%myvar%% & exit /B"
Then run the script to install the keys in your registry. It will look like this:
Now links that use the ie: protocol will open in Internet Explorer.
Google
Demo Page
Here is a solution that should solve the problem with extended url's that contain parameters and special characters (&, % etc.)
Like this:
https://www.google.com/search?q=open-internet-explorer-from-chrome-using-a-protocol-handler&oq=open-internet-explorer-from-chrome-using-a-protocol-handler&aqs=chrome..69i57j69i60l3.1754j0j4&sourceid=chrome&ie=UTF-8
Replace the command in reg file with this:
powershell -windowstyle hidden -command "& {$Url = '%1' ; $Url = $Url -replace 'ie:',''; $IE=new-object -com internetexplorer.application ; $IE.navigate2($Url) ; $IE.visible=$true }"
After few tests, I move to another strategy.
I'm targetin an intermediate batch script instead.
And the batch split the protocol and the url, and open IE.
Here is the batch:
echo %1%
set var=%1
set var=%var:~4,-1%
Start "" "%ProgramFiles%\Internet Explorer\iexplore.exe" %var%
Working registry:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Classes\ie]
"URL Protocol"=""
#="URL:IE Protocol"
[HKEY_CURRENT_USER\Software\Classes\ie\shell]
[HKEY_CURRENT_USER\Software\Classes\ie\shell\open]
[HKEY_CURRENT_USER\Software\Classes\ie\shell\open\command]
#="cmd /c set url=\"%1\" & call set url=%%url:ie:=%% & call start iexplore -nosessionmerging -noframemerging %%url%%"
Some important notes:
You have to wrap %1 in double quotes. Otherwise url with multiple params like example.com?a=1&b=2 will be stripped to example.com?a=1, params after & will be ignored.
You have to remove the double quotes when calling iexplore. If you don't remove the double quotes and open multiple IE window from chrome, only the first IE window will get the correct URL. But removing quotes with command set url=%%url:\"=%% or set url=%%url:~1,-1%% doesn't work.
If you just can't make it to remove those quotes, add switches -nosessionmerging and -noframemerging to iexplore. These are command-line options to control "merging" behavior for IE.
The implementation of the registry will be more generic if you last line of the registry as
#="cmd /C set myvar=%1 & call set myvar=%%myvar:ie:=%% & call start /separate iexplore %%myvar%% & exit"
You wont need to create a custom script.
In case, the target URL can have more than 1 query params, you might face an issue that only the first param gets passed to IE (check the address bar on IE to validate).
In such a case, you can go for the following workaround ... simply create a new html file passing the target URL after encoding it and open this HTML on IE.
window.location = "ie:"+<URL to the above HTML>+"?path="+encodeURIComponent(<target URL>);
In the HTML file, just redirect to the decoded target URL
<html>
<head>
<title>
IE Redirect
</title>
<script>
function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi,
function(m,key,value) {
vars[key] = value;
});
return vars;
}
function openURL(){
window.location.href=decodeURIComponent(getUrlVars()["path"]);
}
</script>
</head>
<body onload="openURL()">
</body>
</html>
The above worked perfectly in my application.
the following command will work for all query params to be passed:
cmd /C set myvar="%1" & call set myvar=%%myvar:ie:=%% & call start /separate "iexplore.exe" %%myvar%% & exit
the following command will work for all query params to be passed:
cmd /C set myvar="%1" & call set myvar=%%myvar:ie:=%% & call start
/separate "iexplore.exe" %%myvar%% & exit
We need to use the double quotes when a link had an ampersand in it and would not open in IE11 as anything after the ampersand was trimmed off.

Open a file with a .hta file [duplicate]

This question already has answers here:
Open a file with an HTA application
(2 answers)
Closed 2 years ago.
I'm making two HTA-applications. One is to install the other one. The code below is the VBScript in the installer HTA which does so that the computer recognises the .sjs extension (an extension which i've created and which has to do with the HTA being installed).
Public Sub Association(EXT, FileType, FileName, Icon)
Set b = CreateObject("wscript.shell")
b.regwrite "HKCR\" & EXT & "\", FileType
b.regwrite "HKCR\" & FileType & "\", "MY file"
b.regwrite "HKCR\" & FileType & "\DefaultIcon\", Icon
b.regwrite "HKCR\" & FileType & "\shell\open\command\", FileName & " %L"
b.regdelete "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" & EXT & "\Application"
b.regwrite "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" & EXT & "\Application", FileName
b.regdelete "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" & EXT & "\OpenWithList\"
b.regwrite "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" & EXT & "\OpenWithList\a", FileName
End Sub
Association ".sjs", "SJS file", "C:\Users\Donald\my_app.hta","C:\Users\Donald\Desktop\my_icon.ico"
I would like it to do so that when I open a .sjs file, it opens the file C:\Users\Donald\my_app.hta, but like this it opens a dialog box where it says "C:\Users\Donald\Documents\file.sjs isn't a valid Win32 application". How can I do so that it does as I want?
Using On Error Resume Next without error check is irresponsible.
[Dim ] xxx As Object isn't valid VBScript. (Should be: [Dim ] xxx As yyy to emphasize that all typed declarations are illegal in VBScript)
Fix that and try again. Use ftype and assoc to check the result of your registry manipulation.
On second thought:
I think that a .HTA file should/must be opened with mshta.exe. (Should have an "explicitly" somewhere; see below)
Update:
I use isql.hta to work with ADO Databases interactively. Parameters and statements are stored in .isql text files. So to tried to mimic your problem with: "I want .isql files associated with the isql.hta application; proof of success: doubleclick on .isql file opens isql.hta". So
assoc .isql=ISQLFile
.isql=ISQLFile
ftype ISQLFile="X:\pathto\isql.hta" %*
ISQLFile="X:\pathto\isql.hta" %*
Doubleclick =>
---------------------------
M:\lib\amfvbs0703\amsinc.isql
---------------------------
M:\lib\amfvbs0703\amsinc.isql is not a valid Win32 application.
---------------------------
OK
---------------------------
M: is a mapped drive; so Windows thinks it's enemy country.
ftype ISQLFile=c:\WINDOWS\system32\mshta.exe "X:\pathto\isql.hta" %*
ISQLFile=c:\WINDOWS\system32\mshta.exe "X:\pathto\isql.hta" %*
Doubleclick => SUCCESS

Error reading registry entry for Firefox

I have an AutoIt v3 script (copied from the author of FF.au3):
#Include <FF.au3>
_FFStart("http://ff-au3-example.thorsten-willert.de/")
If _FFIsConnected() Then
Sleep(2000)
_FFAction("presentationmode", True)
Sleep(2000)
_FFOpenURL("http://www.google.com")
Sleep(2000)
_FFAction("back")
_FFAction("presentationmode", False)
Sleep(2000)
_FFOpenURL("chrome:bookmarks")
Sleep(2000)
_FFAction("alert", "Bye bye ...")
_FFQuit()
EndIf
Exit
But when I run it, I get an error message:
__FFStartProcess ==> General Error: Error reading registry entry for FireFox.
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mozilla\Mozilla Firefox\*CurrentVersion*\Main\PathToExe
Error from RegRead: 1
I have Firefox and AutoIt v3 installed, I downloaded the FF.au3 UDF to same directory as my script, and I have MozRepl Firefox plugin installed and activated (it's active at the menu->plug-ins, I don't see the "Activate on startup" option). I do have an entry at:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mozilla\Mozilla Firefox\26.0 (pl)\Main
That points to the right destination. Why is there an "Error reading registry entry for FireFox."?
Here is the relevant piece of code from the Firefox library:
Local $sHKLM = 'HKEY_LOCAL_MACHINE\SOFTWARE\'
If #OSArch <> 'X86' Then $sHKLM &= 'Wow6432Node\'
$sHKLM &= 'Mozilla\Mozilla Firefox'
Local $sFFExe = RegRead($sHKLM & "" & RegRead($sHKLM, "CurrentVersion") & "\Main", "PathToExe")
If #error Then
SetError(__FFError($sFuncName, $_FF_ERROR_GeneralError, "Error reading registry entry for FireFox." & #CRLF & _
$sHKLM & "\*CurrentVersion*\Main\PathToExe" & #CRLF & _
"Error from RegRead: " & #error))
Return 0
EndIf
It reads the key CurrentVersion (probably of type REG_SZ) from the path HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mozilla\Mozilla Firefox to get the current version of the application. Say for example that this returns the string "27.0".
Then it looks in HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mozilla\Mozilla Firefox\27.0\Main (based on the string it just found for the current version) for the key PathToExe (REG_SZ also probably). This is the first attempt and if it does not fail it uses this path for the executable.
If this fails though, it checks the path HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mozilla\Mozilla Firefox\*CurrentVersion*\Main (literally with the asterisks) for the key PathToExe. This fails as well and that's why you are getting the error.
Check all of the above registry paths for your system. It may be possible that the Firefox library needs to be updated for the later Firefox versions. Try an "as clean as possible" install of Firefox and see if that works. Also try repairing the installation via the setup/deinstaller if that is possible.
If nothing works and you are left to modifying your own system to get it to work, I will check and ask the author of the Firefox library to update it.
I think there's a missing backslash. In the FF.au3 UDF change the following:
Local $sFFExe = RegRead($sHKLM & "" & RegRead($sHKLM, "CurrentVersion") & "\Main", "PathToExe")
to:
Local $sFFExe = RegRead($sHKLM & "\" & RegRead($sHKLM, "CurrentVersion") & "\Main", "PathToExe")
Regards,
Gonnosuke
Most registry manipulation problems are about lack of permissions.
Add #RequireAdmin at the top of your code.
"When running on 64-bit Windows if you want to read a value specific to the 64-bit environment you have to suffix the HK... with 64 i.e. HKLM64."

What parameters to pass to mshtml.dll?

I am currently trying to print a HTML file using mshtml.dll. Looking up in the registry I found for html-files, the following print-to entry:
"%systemroot%\system32\rundll32.exe"
"%systemroot%\system32\mshtml.dll",PrintHTML "%1" "%2" "%3" "%4"
Unexpectedly there are some parameters to pass to mshtml.dll, what are the parameters of mshtml.dll (numbered %1, %2, %3, %4 in this registry information)?
You found this in the printto verb of the htmlfile progid. Which runs when you drag an HTML file from Explorer and drop it on a printer shortcut. The printto verb has these arguments:
%1: the path to the HTML file
%2: the printer name
%3: the printer driver name (optional)
%4: the printer port name (optional)
Taking a dependency on an undocumented function is unwise, you can't rely on this still working in the next Windows version. Using WebBrowser.Print() is the documented way. IWebBrowser2::ExecWB() in native code.
Neither the printer's name is mandatory, in fact in the "print" verb of the htmlfile progid only one parameter is specified for the same command.
By the way: I tried to replace %2 with the printer's name (with and without quotes) but it didn't do anything different, that is, the print dialog is still there.
Tried on Windows 10 and Windows 7.

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.

Resources