web-dev-qa-db-ja.com

Windowsのロック画面の「背後」で何が起こりますか?

私はWindowsの自動化と監視に取り組んできました。

Windowsマシンの画面をロックするとどうなりますか?

現在Windows7を使用していますが、Vistaまたはサーバーバージョンに切り替えた場合の動作に大きな違いはありますか? APIを介してアクセスできるデスクトップはまだありますか?キーストロークとマウスクリックを特定のウィンドウに送信できることは知っていますが( ControlSend および ControlClick を介して)、「デスクトップ」自体がないようです。

誰かがこの全体に光を当てたり、トピックの概要を知ることができる読みやすい情報源を教えてくれませんか?

21
Plastefuchs

基本的に何が起こるかというと、Windowsが安全なデスクトップに切り替わり、現在のデスクトップになるため、入力がそれに関連付けられるようになります。

古いデスクトップは元の場所に残ります。デスクトップ上のすべてのHWNDは引き続き存在し、そのデスクトップに接続されているスレッドは、引き続きそれらのHWNDにアクセスしたり、場所を取得したりできます。メッセージを送信するスレッドがそのデスクトップ上にある限り、このデスクトップ上のウィンドウにメッセージを送信することはできます。

ただし、デスクトップは現在非アクティブであるため、入力を受け取ることはできません。 GetForegroundWindowはNULL(IIRC)を返し、入力が別のデスクトップの[スレッド]に属しているため、SendInputを使用できなくなります。その非アクティブなデスクトップ上のコントロールはフォーカスを受け取ることができません。

アプリまたはコントロールは通常、最初にフォーカスを取得せずにキーボード入力を受信することを期待しないため、フォーカスのないコントロールにキー押下メッセージを送信すると、予期しない動作が発生する場合があることに注意してください。 (これは、たとえば、WM_SETFOCUSで何らかの入力コンテキストを設定し、それをWM_KILLFOCUSでクリアするコントロールでは問題になる可能性があります。)

つまり、UIはまだ存在します。UIに対して特定のクエリを実行できますが、入力を送信することで通常のデスクトップのように自動化することはできなくなり、フォーカスや入力に関連するその他の機能が失敗する可能性があります。

私はAutoHotKeyにあまり詳しくありませんが、機能の名前と説明は、AutoHotKeyが基盤となるWin32 SendInputAPIに大きく依存していることを示唆しています。デスクトップが非アクティブの場合、これはキーボード入力ではまったく機能しません。

デスクトップがどのように機能し、winstation、ロックされたデスクトップなどとどのように関連するかについての合理的な概要については、 MSDNのデスクトップ記事 を確認してください。

デスクトップと自動化で過去に遭遇した問題の1つは、何らかの形式のユーザー入力自動化(マウス、キーボードシミュレーション)を使用する長時間実行テストを残し、誰かができるようにPCをロックする方法です。ただ通りかかって邪魔するだけではありません。 PCをロックすると、デスクトップは非アクティブになるため、自動化は機能しなくなります。スクリーンセーバーが作動すると、同様の問題が発生します。デスクトップが切り替わり、自動化が失敗します。

1つの解決策は、2台のPCを使用することです。メインとテストと呼びましょう。メインからリモートターミナルサービスクライアントをテストマシンで開き、テストマシンで自動テストを実行しますが、メインのターミナルサービスクライアントウィンドウから実行します。機械。ここでクールな部分:TSCウィンドウを最小化するか、メインマシンをロックする(またはスクリーンセーバーを起動させる)ことができ、仮想セッションはまだアクティブであると考えて機能し続けます-誰もそれを支払っていないというだけです注意。これは、アクティブデスクトップとの「接続された」セッションを作成する1つの方法ですが、メインマシンのロックされたデスクトップの背後で保護されているため、誰も干渉できません。

31
BrendanMcK

詳細はわかりませんが、ロック画面は別の「デスクトップ」と、おそらく別の「ウィンドウステーション」を構成していると思います(ウィンドウステーションは単なるデスクトップのコンテナであると理解しています)。ウィンドウステーションに関するMSDNセクションが役立つことを願っています: http://msdn.Microsoft.com/en-us/library/windows/desktop/ms687098%28v=vs.85%29.aspx

デスクトップにアクセスするには、そのデスクトップ上にあるスレッドから通常のWindowsAPIを使用する必要があります。デスクトップが別のウィンドウステーション上にない限り、SetThreadDesktopはおそらくCでそれを行う最も簡単な方法でしょう。

残念ながら、これは通常の特権アプリケーションではすでに困難であり、AutoHotkeyを使用するとさらに複雑になります。スレッドやプロセスの初期化を制御できないため、おそらく他のデスクトップで新しいプロセスを作成する必要があります(これは、AHKで使用できるラッパーがあるように見えるCreateProcess APIを使用して行うことができます)。デスクトップ名を指定します: http://www.autohotkey.com/forum/topic1952.html )。これを行うには、プロセスに特別な権限が必要です。管理者として実行するだけで十分かどうかはわかりません。

2
Vincent Povirk