Search code examples
batch-filewindows-7registryuri

Registering Custom URI Scheme not working on Windows 7 when url has hashtag and question mark


So I'm having to register a custom uri, cnx://, to have IE launch Chrome.

I've tested my registry entry on Windows 7, Windows 8 and Windows 10.

Everything works fine, except on Win7 when there's a URL with a hashtag and a question mark:

cnx:// www.url.com/something/#place/page.php?foo=bar

For whatever reason, that then gets mangled to

cnx:// www.url.com/something/?foo=bar#place/page.php

I have tested this by changing the important registry entry from

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CNX\shell\open\command]
@="\"C:\\Program Files (x86)\\Google\\Chrome\\Application\\Chrome.exe\" %1"

to just

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CNX\shell\open\command]
@="cmd /k echo %1"

which explicitly shows the mangling in a command prompt.

Only happens on Windows 7. Works without issues on Win8 and Win10. And other URL conventions work just fine on windows7, just not when it has a # and ?

Then, it gets mangled.

And of course, doing http://www.url.com/something/#place/page.php?foo=bar works just fine. It only trips up using this custom uri functionality.

Can anyone maybe offer a workaround?

I tried like crazy encoding #place with %23place but then I lost my mind trying to do the string replacement back to the original #place


Solution

  • @ECHO OFF
    SETLOCAL
    
    :: This part merely for demonstration - begin
    CALL :sub "cnx:// www.url.com/something/#place/page.php?foo=bar"
    CALL :sub "cnx:// www.url.com/something/?foo=bar#place/page.php"
    GOTO :eof
    :: This part merely for demonstration - end
    
    :sub
    FOR /f "tokens=1-3delims=?#" %%a IN (%1) DO (
     SET "parta=%%a"
     SET "partb=%%b"
     SET "partc=%%c"
    )
    
    SET "combo=%parta%#%partb%?%partc%"
    
    IF %* neq "%combo%" SET "combo=%parta%#%partc%?%partb%"
    
    ECHO "C:\Program Files (x86)\Google\Chrome\Application\Chrome.exe %combo%"
    
    GOTO :EOF
    

    ISTM %1 is supplied differently in Win7, so the trick is to tokenise on ? and #, then reassemble to tokens appropriately.

    The key should be

    @="thisbatch "%1""
    

    (I believe - no expert here. Point being that %1 should be "quoted"


    [response to comments - on-the-fly, untested; probably requires some escapes...]

    @="cmd /c cd C:\Program Files (x86)\Google\Chrome\Application&FOR /f "tokens=1-3delims=?#" %%a IN ("%1") DO (if "%%a#%%b?%%c"=="%1" (chrome.exe %1) else (chrome.exe %%a#%%c?%%b) )"