【テクニカル・上級編】【レガシー操作】SendKeys メソッドを活用したGUIアプリの簡易自動操作とキー送信タイミングの極意 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

レガシーの深淵を制御せよ:SendKeysが奏でる「非同期」という名の不確実性を殺す技術

APIが存在しない。ドキュメントは霧散し、ソースコードは誰が書いたかも分からぬバイナリの塊。そんな「死に体」のレガシーアプリケーションを自動化せねばならない時、我々エンジニアに残された最後の聖域が `WScript.Shell` の `SendKeys` メソッドである。

だが、甘く見てはいけない。このメソッドは、OSのメッセージキューという「不確実性の極致」に対して、神頼みでキー信号を投げ込む原始的な手法だ。本稿では、SendKeysを単なる「キー送信」ではなく、精密な制御対象として扱い、システムを安定稼働させるための極限のアーキテクチャを伝授する。

1. なぜSendKeysは「裏切る」のか

SendKeysは、ウィンドウのメッセージループに対してキーボードイベントを注入する。しかし、以下の要因によりその挙動は非決定的となる。

  • フォーカスの奪い合い: WSHの実行中、ユーザーがマウスを触っただけでフォーカスは消失する。
  • 描画の遅延: アプリが描画更新を行っている間に次のキーを送れば、それは「虚空」に消える。
  • バッファの競合: OSがキー入力を処理する前に、次のキーを送ることで期待したショートカットが発動しない。

これを防ぐ唯一の解法は、「待機」の厳密な設計「Windows APIによるウィンドウ制御」の併用である。

2. 実践:高精度なウィンドウ制御とキー送信モデル

単なる `WScript.Sleep` は甘えである。OSのイベントをポーリングし、真にフォーカスが当たった瞬間を検知するラッパーを構築せよ。

‘ WScript.Shellを生成し、明示的に管理する
Dim objShell: Set objShell = CreateObject(“WScript.Shell”)

‘ ターゲットアプリを起動し、ハンドルを意識する
‘ 本来はAPIの FindWindow を使うのが正攻法だが、WSH単体でやるなら以下が限界ライン
objShell.Run “C:\LegacyApp\Legacy.exe”, 1
WScript.Sleep 2000 ‘ アプリの起動を待つための「初期ウェイト」

‘ 確実にフォーカスを当てるための制御
If objShell.AppActivate(“ターゲットアプリのタイトル”) Then
WScript.Sleep 500 ‘ フォーカス遷移の安定化を待つ

‘ 送信関数を呼び出す
Call SendKeySequence(objShell, “%F”, 500) ‘ Alt + F
Call SendKeySequence(objShell, “S”, 200) ‘ Save
End If

‘ メモリの明示的解放(VBScriptの原則)
Set objShell = Nothing

‘ 送信と待機をセットにした堅牢なラッパー
Sub SendKeySequence(obj, keys, delay)
obj.SendKeys keys
WScript.Sleep delay ‘ 連続送信時の「呼吸」を作る
End Sub

3. シニアのための「極限の最適化」戦略

1. 待機ロジックの抽象化

`WScript.Sleep` を直書きしてはならない。アプリのレスポンスに合わせて動的にウェイトを調整する、あるいは「特定のGUI要素が表示されるまで待機する」関数を実装せよ。APIの `GetForegroundWindow` を `GetObject(“winmgmts:…”)` 経由で呼び出し、ウィンドウのプロセスIDを監視するのがプロの仕事だ。

2. オブジェクトのライフサイクル管理

VBScriptの `Set obj = Nothing` を忘れることは、メモリリークの温床であり、特にWSHをタスクスケジューラで多重起動させる環境では致命的だ。`On Error Resume Next` を活用し、予期せぬクラッシュ時にも必ず解放処理が走る「クリーンアップ・セクション」を構築せよ。

3. レガシー環境特有の「罠」を潰す

  • IMEの誤作動: SendKeysを送る直前に、IMEがONになっていないかを確認せよ。勝手に日本語入力モードになっていると、SendKeysの文字列はすべて無視される。
  • 管理者権限の壁: WSHを実行するユーザーと、ターゲットアプリの権限が一致しているか。UIPI(User Interface Privilege Isolation)により、低権限のスクリプトから高権限のアプリへキー入力は送信できない。

4. 最後に:職人の矜持

SendKeysでの自動化は、現代の疎結合なAPI連携から見れば「泥臭い」作業かもしれない。しかし、動かぬ機械を力技で動かすことこそが、現場の保守運用を支えるチーフアーキテクトの真価だ。

このコードをただコピペするな。なぜそのウェイトが必要なのか、なぜそのウィンドウ指定なのか、現場のOSの挙動を観察し、その「リズム」をコードに落とし込む。そのプロセスこそが、君をただのスクリプトキディから「システムアーキテクト」へと昇華させる唯一の道である。

さあ、レガシーという名の迷宮を、一行のコードで支配せよ。

タイトルとURLをコピーしました