Technically Impossible

Lets look at the weak link in your statement. Anything "Technically Impossible" basically means we haven't figured out how yet.

1 Push Snap Ver 1.1 - ボタン一押しで、最前面Windowをキャプチャし画像ファイルを保存する。


Zoom Meetingsをはじめとするビデオ・コミュニケーションが、日常利用において何も例外的な存在ではない時代となった。それはオンライン・ミーティングに限らず、大人数が出席する、いわゆるカンファレンスでも用いられている。

カンファレンスの中には、プレゼンテーションを伴う講演でありながら、講演資料を配布しない場合がある。そのような講演中、「この画面はメモしておきたい!」と思った場面ですかさず、Print Screenキーを一押しすれば、指定のフォルダにキャプチャ画像が出力される。

実際のところ、すでに同様の機能を提供するフリーウェアが存在する。しかし、気付いたときには無反応、クラッシュしており、キャプチャしているつもりが全て無駄、というトラブルを度々経験した。

そのような必要性、事情を背景に自作したツールが「1 Push Snap」だ。

この投稿では、そのツールの使い方を紹介する。

1 Push Snap

github.com
このツールはオープンソースで作成しており、C#で記述している。
実行には.NET Framework 4.8を必要とする。

使い方


実行ファイル「1PushSnap.exe」を実行すると、タスクバーにアイコンが表示される。右クリックすると、コンテキスト・メニューが表示される。

  • Information


キャプチャ画像(JPEGファイル)が出力されるフォルダを確認できる。
ユーザー・フォルダ(%userprofile%)をデフォルトの保存先としている。これはメニュ「Save To...」で変更できる。

  • Save To...


キャプチャ画像を保存するフォルダを指定する。

もし画像ファイル出力時に、指定したフォルダが存在していなかった場合は、強制的にユーザー・フォルダへ画像出力する仕様だ。エラー表示ではなく、あくまでも画像ファイルを出力することを最優先としている。

  • Start


このツールはキーボード・イベントを監視する。メニュー「Start」で監視を始める。

監視状態では、アイコンの色が黒からオレンジへ変化する。この状態でPrint Screenキーを押下すると、そのときの最前面Windowがキャプチャされ、その画像が指定のフォルダへ保存される。

  • Stop


キーボード・イベントの監視を中止する。メニュー「Stop」で監視を止める。
監視しない状態では、アイコンの色がオレンジから黒へ変化する。

  • Close

ツールを終了する。

余談-Ver 1.0からの進歩

Ver 1.0は他のフリーウェアと同じ問題を抱えていた。何のエラーもないまま、アプリケーションが落ちているのだった。Ver 1.1の目的は、この問題を解決することだった。

問題の原因は、キーボード・イベントの監視処理コンポーネントの所在が、ガベージコレクションによって解放されてしまうことだった。解法後に該当処理を呼び出すと、Null参照によってアプリケーションが落ちてしまうのだ。

Application: 1PushSnap.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.NullReferenceException

ここまでたどり着くのに、かなり回り道した。
スクリーンキャプチャを目的としない、文書作成などのタイプ中にアプリケーションが落ちていることに気付いた。最初に考えたのは、キーボード・イベント監視のために呼び出しているWin32 APIに無用な負荷をかけているのではないか、と言うことだった。
この部分の処理を並列化してみたのだが、問題は解決しなかった。

前述のイベントログを参照し、Null参照の発生に気付いた。Win32 APIとの連携においてポインタを用いており、それらがガベージコレクションされないように対応したのだが、それでも問題は解決しなかった。

仕方なく、問題発生までVisual Studioデバッグモードで動かし続けて見ることした。そして捕らえたのが次の異常だった。処理連携ではなく、処理そのものを指し示すポインタがガベージコレクションされていたのだった。

マネージド デバッグ アシスタント 'CallbackOnCollectedDelegate'
A callback was made on a garbage collected delegate of type '1PushSnap!OnePushSnap.KeyHook+delegateHookCallback::Invoke'. This may cause application crashes, corruption and data loss. When passing delegates to unmanaged code, they must be kept alive by the managed application until it is guaranteed that they will never be called.

この問題の解決と同時に、キーボード・イベント監視も並列化されており、Ver 1.0と比べれば、マイナー・チェンジ版(つまりバージョン0.1分)程度は進歩している。

次回以降の対応予定
  • キーボード・イベントの監視、中断をボタン操作で切り替える。
  • JPEG以外の出力画像フォーマットに対応する。