Search code examples
windowsregistryprotocolslocalurl-scheme

Custom Protocol ( via Windows registry ) to open file in local folder and with default software


Please Read My Answer Below

I would like to open local files in their default software when clicking a HTML link ( in chrome ) by having a custom URI scheme defined in the Windows Registry. I have tried many different syntax for the registry rule definition and for the link I use. My default .reg file looks like this :

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\test]
"URL Protocol"=""
@="URL:test Protocol"
"DefaultIcon"="\"C:\\Windows\\system32\\notepad.exe\",1"

[HKEY_CLASSES_ROOT\test\shell]

[HKEY_CLASSES_ROOT\test\shell\open]

[HKEY_CLASSES_ROOT\test\shell\open\command]
@="\"C:\\Windows\\system32\\notepad.exe\" \"%1\""

I've tried with every example I could find for the %1, %*, "%1" "%2" ... For now I'm just trying with notepad although eventually I would like to use explorer.exe for it to open the default software for the specified type of file.

My HTML file is :

<a href="test:C:test.txt">Open</a>

I've tried test://C:[...], test:///C:[...], and with slashes and backslashes in the file path.

With the 2 versions above, notepad opens but I get "The filename, directory name, or volume label syntax is incorrect." ( I put my file in the C drive root to be sure any special characters are avoided )

Also, if I define the direct path to a file instead of a parameter string : @="\"C:\Windows\explorer.exe\" \"C:\test.txt\"" , the file opens without any problem.

What am I doing wrong ? Is there a way to see the String received as parameter ?

UPDATE I have modified the registry key to call a simple batch file ("C:\test.bat" %1) with an echo command to see the received parameter (echo %1 pause). By default the whole URI is passed ( e.g: "test:C:\test.txt" ). I've found that if I put a comma after the scheme, the batch file receives 2 parameters : %1="test:" & %2="C:\test.txt". But the registry key value still needs to have "%1"...

"%2" doesn't contain anything before it gets to the batch file. So sadly I can't directly call '"app.exe" %2' and need to call it from a .bat, I'll update if I find a solution.


Solution

  • Solution :

    You can define a registry key to call a script with the link's href as argument :

    Windows Registry Editor Version 5.00
    
    [HKEY_CLASSES_ROOT\test]
    "URL Protocol"=""
    @="URL:test Protocol"
    
    [HKEY_CLASSES_ROOT\test\shell]
    
    [HKEY_CLASSES_ROOT\test\shell\open]
    
    [HKEY_CLASSES_ROOT\test\shell\open\command]
    @="\"C:\\Windows\\Your-Script.bat\" %1"
    

    And then use JScript in Your-Script.bat to split & decode the URI :

    @if (@This==@IsBatch) @then
    wscript //E:JScript "%~dpnx0" %1
    exit /b
    @end
    WScript.CreateObject("WScript.Shell").Run("explorer.exe " + decodeURIComponent(WScript.arguments(0).split("test:")[1]));
    WScript.Quit(0);
    

    This will launch the default application and open your file.

    ======================================================================

    You can use easy javascript functions instead of weird batch parsing for any need you may have, for instance I replace all slashes with backslashes in my script. You can also define your reg key with the custom protocol as argument, and use that to split.

    reg file line :

    @="\"C:\\Windows\\Your-Script.bat\" %test:% %1"
    

    script :

    @if (@This==@IsBatch) @then
    wscript //E:JScript "%~dpnx0" %*
    exit /b
    @end
    WScript.CreateObject("WScript.Shell").Run("explorer.exe " + decodeURIComponent(WScript.arguments(1).split(WScript.arguments(0))[1]));
    WScript.Quit(0);
    

    You could even do it without hard-coding your protocol or giving it as an argument, if you put the link's file path between commas :

    <a href="test:,C:test.txt,">Open</a>
    

    with :

    @="\"C:\\Windows\\Your-Script.bat\" %2"
    

    and in your script :

    wscript //E:JScript "%~dpnx0" %2
    

    ======================================================================

    Your file should open in the default software with any web browser you wish to use.

    If you want your browser to stop asking you to allow the script execution every time (Chrome/Edge) you can run this reg file :

    Windows Registry Editor Version 5.00
    
    [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge]
    "ExternalProtocolDialogShowAlwaysOpenCheckbox"=dword:00000001
    
    [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome]
    "ExternalProtocolDialogShowAlwaysOpenCheckbox"=dword:00000001
    
    [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Chromium]
    "ExternalProtocolDialogShowAlwaysOpenCheckbox"=dword:00000001
    

    It will display the "remember" checkbox.