共用PCで利用者のログをとるため、Powershellで疑似的に画面をロックするコードを書いています。
Inputboxが表示されており、そこにパスワードを入力すると、Inputboxが消えます。
- Inputboxに入力するパスワードは「pass」です。
- 10秒間マウスが動かなければInputboxが再度ポップアップします。
- InputboxでEnter空打ちやEscapeでスクリプトを終了します。
→下記コードではコメントアウト(スクリプトを終わらせるには強制終了させる)
- 10秒経過しなくても、Escapeを押すと、意図的にInputboxを出すことができます。
→ここが問題
PowershellのコンソールがアクティブなときはEscapeが効きますが、
他のアプリが前面にあるとEscapeが効きません。
他のアプリが前面にあってもEscapeが効くようにしたいです。
以下、処理の骨組みだけにしたコードです。
SleepAndWaitKey関数の仮想キーコード判定がおかしいわけですが、
どう解決したらよいのかわからないでおります。
実行環境はWindows10で、.ps1ファイルを右クリックから「Powershellで実行」しています。
# Microsoft.VisualBasicアセンブリを有効化 [void][System.Reflection.Assembly]::Load( ` "Microsoft.VisualBasic, Version=8.0.0.0, ` Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a") $rawui = $host.UI.RawUI [void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") $keyMap = [Windows.Forms.Keys] function SleepAndWaitKey($sec) { $LimitTime = (Get-Date).AddSeconds($sec) #指定時刻(10秒後)までループ While ((Get-Date) -lt $LimitTime) { while ($rawui.KeyAvailable) { $keyinput = $rawui.Readkey("NoEcho,IncludeKeyUp,IncludeKeyDown") if ($keyinput.VirtualKeycode -eq $keymap::Escape) { #Escが押されたら[画面ロック]に戻る return $true } } Start-Sleep 0.5 } return $false } while (1) { $input = [Microsoft.VisualBasic.Interaction]:: ` InputBox("パスワード", "画面ロック") if ($input -eq "") { #break #画面ロック終了 } elseif ($input -ne "pass") { continue #パスワード不一致 → 画面ロック } while (1) { #待機前のマウス位置 $Position = [System.Windows.Forms.Cursor]::Position $LastMousePosX = $Position.x $LastMousePosY = $Position.y #指定秒数待機 If (SleepAndWaitKey(10) -eq $true) { break } #待機後のマウス位置 $Position = [System.Windows.Forms.Cursor]::Position #マウス位置が変わらない → [画面ロック] If (($Position.x -eq $LastMousePosX) ` -And ($Position.y -eq $LastMousePosY)) { break } } }
ぜひお知恵を貸してください。
> 他のアプリが前面にあってもEscapeが効くようにしたいです。
キーボードフックしなければいけないので PowerShell では困難です。
PowerShell の本質はシェルで、その本分は他の実行コマンドを組み合わせるグルー言語です。大量のボンドをこねて箱を作るより、木の板をボンドで張り合わせて作る方が簡単です。難しいことは C# で行うのが良いと思います。
AutoHotkeyで、エスケープが押されたらPowershellのコンソールをアクティブにしてEscapeキー入力を流し込むようにすればいいんじゃないでしょうか。
Zuishin様、ご返信ありがとうございます。キー入力を監視する以外にうまい方法がないか検討します。
ku__ra__ge様、ご返信ありがとうございます。そもそもAutoHotkeyだけで全部やれそうですよね。フリーソフトを気軽にインストールできない環境なので、最初からWindows10に入っているPowershellで何とかできないか試行錯誤しております。
この記事が参考になると思います。
https://qiita.com/nicco_mirai/items/513ae714d3d9c688cdab
上記URLはPowerShellからVB.NETを通じてWindowsAPIを呼び出してキーボード入力を別の入力に化けさせるというジョークプログラムですが、このコードからキーボード入力を検知する箇所を抜き出せば他のアプリが前面にあってもEscapeを検知して処理を実行することができると思います。
うまく行った場合、自己回答でEscapeを検知して処理を実行するコードを書き込んでもらえると後でこの質問を参照する人が助かると思います。
ku__ra__ge様、ご返信ありがとうございます。
ご教示いただいたページを含め、Win32APIを研究中です。FindWindowでコンソールを探してShowWindowで非表示にする別懸案には成功しており、最後の懸案がキー入力のフックです。
回答1件
あなたの回答
tips
プレビュー