title: Detecting protocol handler with Javascript
body: <p><em>Foreword: I am not a Windows/software developer. I am just a Web Dev with Javascript skills, so I know that I may not understand the ins and outs of protocol handlers.</em></p>
  <p>I am part of a team that has created a piece of software that installs a protocol handler. Once a user has installed the software, they could launch it via visiting a link like <code>&lt;a href=&quot;myAwesomeApp://params&quot;&gt;Start!&lt;/a&gt;</code>.</p>
  <p>My issue (and I understand it is a very old issue) is I need a way to see if this protocol handler is installed.</p>
  <ul>
  <li>If it is, run the protocol handler</li>
  <li>If not, redirect to software installer location</li>
  </ul>
  <p>I have found a semi-promising solution that works for FF and Chrome <a href="https://gist.github.com/rajeshsegu/3716941" rel="nofollow noreferrer">here</a> (old blog post about script <a href="http://www.rajeshsegu.com/2012/09/browser-detect-custom-protocols/comment-page-1/" rel="nofollow noreferrer">here</a>). I'm not sure why this doesn't work for IE, even while the author explicitly created functionality for IE. Here is the code I am currently using (HTML/JS):</p>
  <pre><code>&lt;html&gt;
  &lt;head&gt;
      &lt;title&gt;Detect Custome Protocol&lt;/title&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://code.jquery.com/jquery-1.8.1.min.js&quot;&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
  &lt;input id=&quot;protocol&quot; value=&quot;&quot; placeholder=&quot;custom protocol&quot;/&gt;
  &lt;button id=&quot;launch&quot;&gt;Launch&lt;/button&gt;
  &lt;!-- Mozilla Only --&gt;
  &lt;iframe id=&quot;hiddenIframe&quot; src=&quot;about:blank&quot; style=&quot;display:none&quot;&gt;&lt;/iframe&gt;
  &lt;!-- IE Case 1 --&gt;
  &lt;a id=&quot;hiddenLink&quot; style=&quot;display:none;&quot; href=&quot;#&quot;&gt;custom protocol&lt;/a&gt;
  &lt;script&gt;
  
      //Default State
      var isSupported = false;
  
      //Helper Methods
      function getProtocol(){
          return $('#protocol').val();
      }
  
      function getUrl(){
          return getProtocol()+&quot;://&quot;+&quot;rajeshsegu.com&quot;;
      }
  
      function result(){
          alert(getProtocol() + &quot; supported =&gt; &quot; + isSupported);
      }
  
      //Handle Click on Launch button
      $('#launch').click(function(){
          if($.browser.mozilla){
              launchMozilla();
          }else if($.browser.chrome){
              launchChrome();
          }else if($.browser.msie){
              launchIE();
          }
      });
  
      //Handle IE
      function launchIE(){
  
          var url = getUrl(),
              aLink = $('#hiddenLink')[0];
  
          isSupported = false;
          aLink.href = url;
  
          //IE10+
          if(navigator.msLaunchUri){
              navigator.msLaunchUri(url, 
                     function(){ isSupported = true; result(); }, //success
                     function(){ isSupported=false; result();  }  //failure 
              );
              return;
          } else if (navigator.appName==&quot;Microsoft Internet Explorer&quot; &amp;&amp; aLink.protocolLong==&quot;Unknown Protocol&quot;){
              //Case 1: protcolLong
              console.log(&quot;Case 1&quot;);
              isSupported = false;
              result();
              return;
          }
  
          //Case2: Open New Window, set iframe src, and access the location.href
          console.log(&quot;Case 2&quot;);
          var myWindow = window.open('','','width=0,height=0');
          myWindow.document.write(&quot;&lt;iframe src='&quot;+ url + &quot;'&gt;&lt;/iframe&gt;&quot;);
          setTimeout(function(){
              try{
                  myWindow.location.href;
                  isSupported = true;
              }catch(e){ 
                  //Handle Exception
              }
  
              if(isSupported){
                  myWindow.setTimeout('window.close()', 100);
              }else{
                  myWindow.close();
              }
              result();
          }, 100)
  
      };
  
      //Handle Firefox
      function launchMozilla(){
  
          var url = getUrl(),
              iFrame = $('#hiddenIframe')[0];
  
          isSupported = false;
  
          //Set iframe.src and handle exception
          try{
              iFrame.contentWindow.location.href = url;
              isSupported = true;
              result();
          }catch(e){
              //FireFox
              if (e.name == &quot;NS_ERROR_UNKNOWN_PROTOCOL&quot;){
                  isSupported = false;
                  result();
              }
          }
      }
  
      //Handle Chrome
      function launchChrome(){
  
          var url = getUrl(),
              protcolEl = $('#protocol')[0];
  
          isSupported = false;
  
  
          protcolEl.focus();
          protcolEl.onblur = function(){
              isSupported = true;
              console.log(&quot;Text Field onblur called&quot;);
          };
  
          //will trigger onblur
          location.href = url;
          
          //Note: timeout could vary as per the browser version, have a higher value
          setTimeout(function(){
              protcolEl.onblur = null;
              result()
          }, 500);   
  
      }
  &lt;/script&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  <p>I have created a <a href="http://ignitepixels.com/sandbox/detectProtocol.html" rel="nofollow noreferrer">sample page</a> for troubleshooting purposes. There was a single <code>'</code> quote missing on <code>line 72</code>, so I have added that. Nothing else has changed.*</p>
  <h1>My question is two-fold:</h1>
  <ol>
  <li>Is there a better way to implement this type of protocol handler detection? Is there a way to fix the <code>launchIE()</code> function so it works?</li>
  <li>Is there a way to know what handlers I <em>should</em> have access to while using this check? For instance, with my current code, &quot;acrobat&quot; comes up as True in Chrome. In IE10, it comes up as false. I have a general idea of what should be true/false, but I don't know definitively.</li>
  </ol>
  <p>I am trying to do this in Javascript, as the requirements of this project are to start the program from the browser (and later return results). If this is not possible in Javascript, I am open to hearing any other solutions.</p>