views:

2034

answers:

9

I have created a custom URL protocol handler.

http://

mailto://

custom://

I have registered a WinForms application to respond accordingly. This all works great.

But I would like to be able to gracefully handle the case where the user doesn't have the custom URL protocol handler installed, yet.

In order to be able to do this I need to be able to detect the browser's registered protocol handlers, I would assume from JavaScript. But I have been unable to find a way to poll for the information. I am hoping to find a solution to this problem.

Thanks for any ideas you might be able to share.

+2  A: 

This would be a very, very hacky way to do this... but would this work?

  • Put the link in as normal...
  • But attach an onclick handler to it, that sets a timer and adds an onblur handler for the window
  • (in theory) if the browser handles the link (application X) will load stealing the focus from the window...
  • If the onblur event fires, clear the timer...
  • Otherwise in 3-5seconds let your timeout fire... and notify the user "Hmm, looks like you don't have the Mega Uber Cool Application installed... would you like to install it now? (Ok) (Cancel)"

Far from bulletproof... but it might help?

scunliffe
:D It's a clever idea. Seems like there would be a way because it seems like a common need.
CJCraft.com
+1  A: 

Protocol handlers are registered in the Windows registry under HKEY_CLASSES_ROOT\PROTOCOLS\Handler

Stijn Sanders
True, but I need to do this client side. Show HTML A if registered, and HTML B if not registered.
CJCraft.com
Oh, in JavaScript, would this do? `if(document.getElementById("somelink").protocolLong=="Unknown Protocol")`
Stijn Sanders
@Stijn Sanders: Did you try out your JavaScript? I doubt that it would work.
Martin
http://yoy.be/test/testProtLong.html
Stijn Sanders
It works in IE 8, but not in Firefox/Opera/Chrome/Safari
Deebster
Registry is inaccesible from a web browser. Would only work on WINE or WINDOWS.
Hugo
A: 

This is not a trivial task; one option might be to use signed code, which you could leverage to access the registry and/or filesystem (please note that this is a very expensive option). There is also no unified API or specification for code signing, so you would be required to generate specific code for each target browser. A support nightmare.

Also, I know that Steam, the gaming content delivery system, doesn't seem to have this problem solved either.

ken
The signed code should be signed by a certificate that is installed along with the application that handles the custom:// so there'd be no need for a really expensive application certificate signed by someone like verisign.
Hugo
Very insightful, thanks!
ken
A: 

protocolLong - Works great, in IE only unfortunately.

We've been using a browser plug-in.

effish
A: 

You say you need to detect the browser's protocol handlers - do you really?

What if you did something like what happens when you download a file from sourceforge? Let's say you want to open myapp://something. Instead of simply creating a link to it, create a link to another HTML page accessed via HTTP. Then, on that page, say that you're attempting to open the application for them. If it doesn't work, they need to install your application, which they can do by clicking on the link you'll provide. If it does work, then you're all set.

Brian
+3  A: 

There seems to be no straightforward way via javascript to detect the presence of an installed app that has registered a protocol handler.

In the iTunes model, Apple provides urls to their servers, which then provide pages that run some javascript:

http://ax.itunes.apple.com/detection/itmsCheck.js

So the iTunes installer apparently deploys plugins for the major browsers, whose presence can then be detected.

If your plugin is installed, then you can be reasonably sure that redirecting to your app-specific url will succeed.

liftedelm
This should be the most reliable solution. But I means that you need to install and also create a plugin for most of the browser and that is kind of tricky. I could be more userfriendly to be able to redirect the user to the download page instead.
Natim
A: 

What seams the most easy solution is to ask the user the first time.

Using a Javascript confirm dialog per example:

You need this software to be able to read this link. Did you install it ?

if yes: create a cookie to not ask next time; return false and the link applies
if false: window.location.href = '/downloadpage/'
Natim
A: 

I'm trying to do something similar and I just discovered a trick that works with Firefox. If you combine it with the trick for IE you can have one that works on both main browsers (I'm not sure if it works in Safari and I know it doesn't work in Chrome)

if (navigator.appName=="Microsoft Internet Explorer" && document.getElementById("testprotocollink").protocolLong=="Unknown Protocol") {
    alert("No handler registered");
} else {
    try {
        window.location = "custom://stuff";
    } catch(err) {
        if (err.toString().search("NS_ERROR_UNKNOWN_PROTOCOL") != -1) {
            alert("No handler registered");
        }
    }
}

In order for this to work you also need to have a hidden link somewhere on the page, like this:

<a id="testprotocollink" href="custom://testprotocol" style="display: none;">testprotocollink</a>

It's a bit hacky but it works. The Firefox version unfortunately still pops up the default alert that comes up when you try to visit a link with an unknown protocol, but it will run your code after the alert is dismissed.

I found I still got the "Firefox doesn't know how to open this address, because the protocol (tel) isn't associated with any program." message before the catch block
Deebster
A: 

You can try something like this:

function OpenCustumLink(link) {

    var w = window.open(link, 'xyz', 'status=0,toolbar=0, menubar =0, height=0, width =0, top= -10, left=-10 ');
    if(w == null) {            
        //Work Fine
    }
    else {
        w.close();
        if (confirm('You Need a Custom Program. Do you want to install?')) {
            window.location = 'SetupCustomProtocol.exe'; //Url for installer
        }
    }
}
Ariel Guitian