Python을 이용한 윈도 메시지 Hooking 및 크롬 컨트롤

2018. 11. 2. 17:12기타/Windows 개발

Windows 10에서 제공하는 Single-app Kiosk 기능을 이용하려했는데, 반드시 UWP로 만든 앱만 가능하다고 해서 Visual Studio까지 설치하고 UWP 앱을 만들어서 테스트를 해보았다. 그런데, UWP 앱은 윈도 기반의 모든 플랫폼에서 실행이 되어야하기 때문에, PC의 윈도 시스템에 접근하는 것은 물론 외부 명령 실행 조차 안되는 기초적인 문제가 발생했다. 또한 Chrome을 사용하지 못하고 무조건 Edge를 사용해서 Web View를 구현해야하는 것 또한 문제라고 할 수 있다. 몇가지 테스트를 하다가 포기하고 Python으로 Windows Service를 만들어서 처리하기로 결정했다. 

https://docs.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/web-view

https://docs.microsoft.com/ko-kr/xamarin/xamarin-forms/user-interface/webview?tabs=vswin


python에서 윈도 메시지 Hooking하기

https://github.com/pywinauto/pywinauto/blob/master/examples/hook_and_listen.py

https://pywinauto.readthedocs.io/en/uia/code/pywinauto.hooks.html

https://docs.microsoft.com/en-us/windows/desktop/winmsg/using-hooks


python에서 외부 명령을 실행 시키는 방법은 다음과 같다.

https://hashcode.co.kr/questions/336/%EC%99%B8%EB%B6%80-%EB%AA%85%EB%A0%B9%EC%96%B4%EB%A5%BC-%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%9C%BC%EB%A1%9C-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0

https://stackoverflow.com/questions/1685157/specify-working-directory-for-popen

subprocess.Popen takes a cwd argument to set the Current Working Directory; you'll also want to escape your backslashes ('d:\\test\\local'), or use r'd:\test\local'so that the backslashes aren't interpreted as escape sequences by Python. The way you have it written, the \t part will be translated to a tab.

So, your new line should look like:

subprocess.Popen(r'c:\mytool\tool.exe', cwd=r'd:\test\local')


1. 크롬을 키오스크 모드로 실행한다. 크롬 실행시에 arguments로 URL과 --kiosk 옵션을 실행하도록 한다.

http://blog.daum.net/_blog/BlogTypeView.do?blogid=0NpvP&articleno=353&categoryId=0&regdt=20150708161357

"C:\Program Files\Google\Chrome\Application\chrome.exe" http://www.daum.net -kiosk


https://stackoverflow.com/questions/22927536/how-to-open-google-chrome-using-python-and-pass-in-arguments/22927616

import os
os.system('taskkill /im chrome.exe') 

os.system('start chrome "https://www.youtube.com/feed/music" --kiosk')


Python에서 WebDriver나 ChromeDriver로 크롬을 키오스크 모드로 실행하는 방법이 있기는 하지만 위 방법하고 뭔가 차이가 있다. 온갖 옵션을 찾아봤는데 만족스러운 결과를 만들지 못한다.

https://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.chrome.options

https://sites.google.com/a/chromium.org/chromedriver/home

https://www.ericdlarson.com/misc/chrome_command_line_flags.html


2. 크롬 키오스크 모드로 실행을 하면, 터치 스크린의 경우 멀티 터치가 되어서 줌인/줌아웃이 실행된다. 이를 막아 주어야 한다.

윈도 메시지 중에 키보드와 마우스 이벤트 메시지를 무력화 시켜도 크롬 내부의 버튼 클릭이나 제스쳐 등은 동작한다. 아마도 윈도 표준 메시지 방식이 아닌 예외적인 구현을 한 것 같다.

https://stackoverflow.com/questions/22999829/disable-chrome-pinch-zoom-for-use-in-kiosk

We've had a similar problem, it manifests as the browser zooming but javascript receiving no touch event (or sometimes just a single point before zooming starts).

We've found these possible (but possibly not long-term) solutions:

1. Disable the pinch / swipe features when using kiosk mode

If these command-line settings remain in Chrome, you can do the following:

chrome.exe --kiosk --incognito --disable-pinch --overscroll-history-navigation=0
  • --disable-pinch - disables the pinch-to-zoom functionality
  • --overscroll-history-navigation=0 - disables the swipe-to-navigate functionality


크롬 자체의 좌우 제스쳐는 막는 방법이 없어서 최초에 로딩 페이지만 존재해서 좌우 제스쳐 자체가 먹지 않도록 하는 것이 정답인 듯하다.

https://productforums.google.com/forum/#!topic/chrome/PaMriZC-Kuo

https://social.msdn.microsoft.com/Forums/en-US/b1767764-dc29-4dbc-bddb-1f73f154d809/getting-wmtouch-messages-in-callwndproc?forum=tabletandtouch

https://docs.microsoft.com/en-us/windows/desktop/wintouch/getting-started-with-multi-touch-gestures


3.  마지막으로 윈도 10의 시스템 제스쳐를 막아야 한다. 이것은 Python 프로그램으로 통제하기가 쉽지 않은 것 같아서 그냥 설정을 변경해버렸다.

https://answers.microsoft.com/en-us/windows/forum/windows_10-other_settings/how-to-disable-touchscreen-gestures-on-windows-10/3ff7654e-c90e-41d7-b2d1-1dfbba0812fd?auth=1

not possible on windows 10 home editions, this is the price you pay for a 'free' operating system !

the official method to disable edge swipes ( which we use for our epos application ) is as follows, although it only works on windows 10 pro and related operating systems. i found it works on windows 10 iot.

gpedit.msc
Local Computer Policy
 Computer Configuration
  Administrative templates
   Windows Components
    EdgeUI
     Allow edge swipe = Disabled

Reboot


동료들이 크롬보다 chromium이 가볍고 더 좋다고 해서 chromium을 사용해봤다.

https://chromium.woolyss.com/download/

https://chromium.googlesource.com/chromium/src/+/master/docs/windows_build_instructions.md


chromium은 KIOSK 모드로 실행할 때, 계속 상단바에 뭐가 뜬다. 관리자 모드로 콘솔을 실행해서 3개의 환경 설정을 해주면 해결 된다.

https://stackoverflow.com/questions/21276763/google-api-keys-missing-warning-message-when-using-chromium-portable

I needed to get rid of this message too, so I just took what mormegil suggested but applied it to a batch script that launches Chromium.

My below sample batch file will launch Chromium into KIOSK mode but you can just remove the --kiosk if you don't need that.

set GOOGLE_API_KEY="no"
set GOOGLE_DEFAULT_CLIENT_ID="no"
set GOOGLE_DEFAULT_CLIENT_SECRET="no"

"C:\chromium\ChromiumPortable_49.0.2593.0.paf\App\Chromium\32\chrome.exe" --kiosk

I did it this way since I don't want to set those environment variables to affect other instances of Chromium but rather just the one that I'm launching with my batch script.