この記事の目的
この記事では、
UWPでGlobal Hookが機能するかについての検証結果をまとめること
を目的としています。
本題
★きっかけ
WPFでGlobalHookを使ったツールを作成しました。
作ったツールは、以下の機能を有しています。
1)GlobalHookを使って、ユーザー操作(マウスクリックやキーダウンなど)イベントを取得する。
2)イベントをきっかけにスクリーンショットを取得する。
3)エクセルファイルに2)で取得したスクショを時系列順に貼り付ける。
主に、何かのアプリのテストを手動で実行し、そのエビデンスを作成するときや、
何かの作業(特にGUIで操作するもの)を行うとき、その操作手順を記録するとき
に利用することを目的としたツール*1となっています。
このツールの配布の方法を考えたとき、GitHubからダウンロードするより、
UWPのほうが便利かと思い、WPF→UWPへつくりかえようと考えました。
UWPへのつくりかえにあたり、大きな問題となったのは、
・スクリーンショットの取得
・エクセルファイルの出力
・GlobalHookを使ったユーザー操作イベントの取得
です。
ということで、3つ目のGlobalHookが機能するかについて調べ始めました。
調べ始めてすぐに、StackOverFlowにて、GlobalHookがUWPで使えないという回答を見つけました。
stackoverflow.com
(自分が正しく議論が理解できていたら)
UWPではGlobalHookの選択肢はないということになります。
使えないってどういうことか・・・
コンパイルが通らないレベル?
実行時にエラーになるレベル?
という疑問があったので、どんなふうに”使えない”のか実際にサンプルを作って試してみることにしました。
★実装
UWPの画面自体はとてもシンプルで、
テキストブロックが1つだけある画面を作成しました。
テキストブロックの名前は"Sample"です。
画面が準備できたので、コードビハインドの実装をしていきます。
Hook時の操作を実装するメソッドを以下のように定義します。
以下の例では、マウスの左クリックイベントを拾うように定義します。
void MouseHook_LeftButtonDown(GrobalHooks.MouseHook.MSLLHOOKSTRUCT mouseStruct) { //TEXT BLOCKに実行時間を表示させる this.Sample.Text = DateTime.Now.ToString(”yyyyMMdd-HHmmss.ffffff”); }
次に、Hookのイベントを登録する処理を定義します。
public void InitializeHooks() { // register events mouseHook.LeftButtonDown += new GrobalHooks.MouseHook.MouseHookCallback(MouseHook_LeftButtonDown); //開始 mouseHook.Install(); keyboardHook.Install(); }
InitializeHooksメソッドを画面クラスの初期化時に呼び出します。
public MainPage() { this.InitializeComponent(); this.InitializeHooks(); }
★動作確認!
実行したところのイメージは以下のようになります。
※初期表示時は”AAA”と表示しています。
クリックすると、フックしたイベントが実行され、時刻を更新します。
表示形式は、yyyyMMdd-HHmmss.ffffffです。
とりあえず・・・・
動いた(´▽`)
なんやかんやでUWPでもGlobalHookは動作することがわかりました!
★問題
しかし、そう簡単にはいかないようです(´・ω・`)
フックしたイベントは、UWPのアプリウィンドウの領域だけでしか発生しませんでした。。。
つまり、ウィンドウの領域外の部分での操作はフックできません。。。
これでは、ツールの目的を達成することができません。。。
上記の動作が本当だとしたら、考えられる対応としては、
UWPアプリを全画面表示させ、背景を透明にする
ことでしょうか( ゚Д゚)
そこまでいったら、グローバルフックではなく、画面のクリックイベントを拾えばよいですねw
まとめ
GlobalHookはUWPでも動作することが確認できた。
ただし、UWPのウインドウの中の操作に限る。←これが問題。。。
これがStackOverFlowでいわれていた”使えない”の理由なのだと感じました。
UWPだけでなく、フルスクリーンに対しての操作をフックしたい場合は
WPFやWindows Formsを利用する必要がありそうです(=_=)
*1:つまらないものですが、プレリリース版は以下のURLで公開しています。 github.com