본문 바로가기

OS (Operating System)/Window

윈도우(window) 웹에서 local 파일 실행, 크롬에서 exe 파일 실행 , scheme does not have a registered handler, Deep link to a native app from a browser, with a fallback

728x90

https://dogfootnote.tistory.com/46

 

윈도우(window) NSIS 설치파일(exe) 만들기

설치경로는 기존 설치경로의 흔적이 남아있으면 안바뀌는것같다 주의 NSIS로 윈도우 설치 파일(exe)을 만들어 보자. [펌] 맨땅에 헤딩하면서 터득한 내용이라 완벽한 방법이 아님을 미리 말씀드립

dogfootnote.tistory.com

 

.nsi 파일을 수정한후 install파일을 만들면

설치시에 Reg경로가 자동추가된다

Section -Post

  WriteRegStr HKCR "${Appname}" "URL protocol" ""

  WriteRegStr HKCR "${Appname}\shell" "" "open"

  WriteRegStr HKCR "${Appname}\shell\open" "" "command"

  WriteRegStr HKCR "${Appname}\shell\open\command" "" '"설치경로\Appname.exe" "%1"'


크롬(chrome)에서 로컬 exe파일 실행하는 방법 (ActiveX 대체) [펌]

윈도우에서 브라우저와 로컬 응용프로그램과 통신하기 위해서는 대다수들이 액티브엑스 방식으로 통신하여 로컬 응용프로그램에 접근할 수 있도록 개발합니다.

 

웹 브라우저 -> 액티브엑스 -> 개인 PC에 설치된 응용프로그램

 

이런 방식으로 웹 브라우저에서 할 수 없는 기능들을 각 클라이언트 로컬에 응용프로그램을 설치하도록 유도하고 실행되도록 하는 것이 액티브엑스의 기능입니다.

하지만 액티브엑스에 대한 유저들의 사용에 대한 번거로움과 보안에 대한 문제점이 점차 커지고 있습니다.

이에 따라 이번에 제가 소개하려는 것이 바로 Custom URL schemes입니다.

개인적으로는 액티브엑스에 대한 대안으로 Custom URL schemes 을 선택하여 실제 업무에서 기존 액티브엑스를 제거하고 이 방법을 채택하고 라이브 하였습니다.

일단 Custom URL schemes 장점은 브라우저별 특성을 타지 않고 로컬에 있는 응용프로그램을 호출할 수 있다고 할 수 있습니다.

게다가 개발자 입장에서 구현하는 데에 크게 어려운 부분이 없습니다.

일단 웹브라우저에서 Custom URL schemes을 호출하기 위해서는 로컬 레지스터에 등록해줘야 합니다. 인스톨할 때에 레지스터에 등록해주면 좋겠죠.

 

일단은 [Windows]키 + R 을 클릭한 후 그림과 같이 레지스트리 편집기를 엽니다.

 

 

 

레지스트리 편집기에서 [HKEY_CLASSES_ROOT] 에 키를 생성합니다.

 

 

 

이때 주의할 점은 고유의 키값을 만들어야 합니다. 쉽게 말씀드리면 다른 응용프로그램과 이름이 겹치면 안된다는 것입니다. 저는 임시로 test로 생성하였습니다.

 

 

 

그리고 test키 값안에 문자열을 추가합니다.

문자열 값은 "URL protocol" 로 입력해줘야 합니다.

 

 

 

 

그리고 test 키값을 생성하는 방법과 같이 하위에 shell -> open -> command를 아래의 그림과 같이 생성해 줍니다.

 

 

 

그리고 마지막 command 키 값 안에 문자열을 편집하여 

"응용프로그램 실행될 경로" "%1" 을 입력해줍니다.

"%1"은 인자값을 받기 위함이고 인자값을 받아야 하는 부분이 있다면 추가 해주셔야합니다. 

 

 

이렇게하면 레지스트리에 등록이 완료 됩니다.

이제 웹 브라우저에서 "test://인자값" 을 호출하면 레지스트리에 지정한 응용프로그램을 실행할 수 있습니다.

 

 

 

"appname://인자값" 형태로 호출하게 되면 실행될 응용프로그램에서 인자값을 전달 받을 수 있습니다.

밑에는 크롬에서 호출되는 팝업창이 뜹니다. 

간혹 외부 프로토콜 요청 팝업이 뜨지 않으신 분들은 크롬 설정 부분에 마그넷 설정에서 차단으로 설정되있을 수 있습니다.

 

 

 

이렇게해서 계산기가 실행된 것을 확인하실수 있습니다.

 

 

위와 같이 윈도우에서 Custom URL schemes 방식으로 호출하는 방법을 소개하였습니다. 윈도우에서 실제 이 방식으로 쓰는 프로그램도 있지만 대다수가 모바일 환경에서 이 방식을 사용합니다. 

 

https://msdn.microsoft.com/ko-kr/ko/library/aa767914(v=vs.85).aspx

 

해당 URL에서 더 구체적으로 Custom URL schemes 방법을 소개하고 있으니 참고하시면 될 것같습니다.

 

Custom URL schemes 를 통한 응용프로그램 호출에도 몇가지 단점이 있습니다.

위에 설명했듯이 레지스트리에 호출되는 네임이 고유의 값이여야 한다는 것입니다. 만약 다른 응용프로그램과 호출 네임이 같다면 둘 중에 어느것이 호출될지 모릅니다.

또한 브라우저에서 호출시 클라이언트 팝업창에서도 확인 할 수 있듯이 호출 내용을 확인할 수 있습니다. 이런 점은 공격 당하기 쉬운 부분이 될 수 있죠.

 

추가적으로 nsis 인스톨러를 사용하시는 분들은 인스톨시에 아래와 방법을 참고하시어 레지스트리에 등록하시면 도움이 될 것같습니다.

 

  WriteRegStr HKCR "${Appname}" "URL protocol" ""

  WriteRegStr HKCR "${Appname}\shell" "" "open"

  WriteRegStr HKCR "${Appname}\shell\open" "" "command"

 

  WriteRegStr HKCR "${Appname}\shell\open\command" "" '"설치경로\Appname.exe" "%1"'

 

 

출처:https://developerking.tistory.com/71

 

크롬(chrome)에서 로컬 exe파일 실행하는 방법 (ActiveX 대체)

윈도우에서 브라우저와 로컬 응용프로그램과 통신하기 위해서는 대다수들이 액티브엑스 방식으로 통신하여 로컬 응용프로그램에 접근할 수 있도록 개발합니다. 웹 브라우저 -> 액티브엑스 ->

developerking.tistory.com


Reg 경로를 잡아주고

location.href = 'TESTReg://';

호출을할경우 local의 exe파일이 열린다

 

설치파일을 깔기전에 local이라면 경로가 없기에 연결이 안되고 error메세지가 발생한다

 

Failed to launch 'TESTReg://' because the scheme does not have a registered handler.

문제는 이를 감지하는 이벤트가 크롬에는 없다

 

하지만 어떤 귀한 외국인형님이 캐치함수를 만들어놓으셨더라

 

    function DeepLinker(options) {
      if (!options) {
        throw new Error('no options')
      }

      var hasFocus = true;
      var didHide = false;

      // window is blurred when dialogs are shown
      function onBlur() {
        hasFocus = false;
      };

      // document is hidden when native app is shown or browser is backgrounded
      function onVisibilityChange(e) {
        if (e.target.visibilityState === 'hidden') {
          didHide = true;
        }
      };

      // window is focused when dialogs are hidden, or browser comes into view
      function onFocus() {
        if (didHide) {
          if (options.onReturn) {
            options.onReturn();
          }

          didHide = false; // reset
        } else {
          // ignore duplicate focus event when returning from native app on
          // iOS Safari 13.3+
          if (!hasFocus && options.onFallback) {
            // wait for app switch transition to fully complete - only then is
            // 'visibilitychange' fired
            setTimeout(function() {
              // if browser was not hidden, the deep link failed
              if (!didHide) {
                options.onFallback();
              }
            }, 1000);
          }
        }

        hasFocus = true;
      };

      // add/remove event listeners
      // `mode` can be "add" or "remove"
      function bindEvents(mode) {
        [
          [window, 'blur', onBlur],
          [document, 'visibilitychange', onVisibilityChange],
          [window, 'focus', onFocus],
        ].forEach(function(conf) {
          conf[0][mode + 'EventListener'](conf[1], conf[2]);
        });
      }

      // add event listeners
      bindEvents('add');

      // expose public API
      this.destroy = bindEvents.bind(null, 'remove');
      this.openURL = function(url) {
        // it can take a while for the dialog to appear
        var dialogTimeout = 500;

        setTimeout(function() {
          if (hasFocus && options.onIgnored) {
            options.onIgnored();
          }
        }, dialogTimeout);

        window.location = url;
      };
  }

/* usage */

var url = 'fb://profile/240995729348595';
var badURL = 'lksadjgajsdhfaskd://slkdfs';

var linker = new DeepLinker({
  onIgnored: function() {
    console.log('browser failed to respond to the deep link');
  },
  onFallback: function() {
    console.log('dialog hidden or user returned to tab');
  },
  onReturn: function() {
    console.log('user returned to the page from the native app');
  },
});

linker.openURL(url);

출처 : https://gist.github.com/diachedelic/0d60233dab3dcae3215da8a4dfdcd434

 

Deep link to a native app from a browser, with a fallback

Deep link to a native app from a browser, with a fallback - deep-link-from-browser.js

gist.github.com

 

이로서 하나의 버튼을 호출키로사용하면서

local에 파일이 없을경우 프로그램 다운을 유도하고

설치시에는 프로그램을 띄울수있게되었다

728x90