web-dev-qa-db-ja.com

リモートデスクトップ上で実行する場合のSendKeysの代替?

SendKeysを介してアプリケーションにキーストロークを挿入するアプリケーションがあります。

残念ながら、SendKeysがリモートデスクトップで機能しないというよく知られた問題のため、リモートデスクトップ経由で実行している場合、アプリケーションは機能しません。

誰かが以前にこの問題を解決したことがありますか、またはそれを解決する方法について何か良い提案がありますか?

24
Cameron

SendKeysは、主に次の理由で適切ではありません。

  • キーはアクティブ/フォーカスされたアプリケーションにのみ送信できますが、アクティブなアプリケーションはキーが実際に送信されるまでの間に変更される可能性があるため、動作が保証されることはありません。
  • RDPおよび他の多くのライブラリ(DirectXなど)は、主にセキュリティ上の理由でそれらをブロックします。

より良い選択肢:

SendMessage を使用したサンプルコード:

HWND hwndNotepad = FindWindow(_T("Notepad"), NULL);
HWND hwndEdit = FindWindowEx(hwndNotepad, NULL, _T("Edit"), NULL);
SendMessage(hwndEdit, WM_SETTEXT, NULL, (LPARAM)_T("hello"));
9
Mrchief

私の場合、ハードウェアスキャンコードでWinAPIのSendInputを正常に使用していました。 SendKeysがcharsをスキャンコードに正しくマップしていないようです。

4
Vasily Nosov

デスクトップを使用前に常にログインさせる(または起動ごとに自動ログインするように構成する)ことで、RDPの問題を回避できます。

また、自動ログインを使用しても、自動化を実行したり、システムを管理したりするためにリモートデスクトップアクセスが必要な場合は、RDPではなくVNCを使用することをお勧めします。理由は、VNCがクロスプラットフォームであり、このRDPの問題に遭遇しないためです。 VNCは、実際のデスクトップ(RDPコンソールセッション0またはマシンの「ヘッド」)のリレーのように機能しますが、欠点は、一度に1つのリモートセッションのみです(または、すべて同じデスクトップ+キーボード+マウスを共有します)。 VNCは仮想マシンでも機能します。 (VMWare/Hyper-V/Xen)仮想マシンマネージャーソフトウェアからのRDPまたはローカル(RDP)アクセスの代わりにVNCを使用します。

VNCで注意する必要があるのは、デスクトップがアイドル状態またはスクリーンセーバーで自動ロックするように構成されていないことだけです。これにより、送信キーとGUI自動化の実行が停止する可能性があるため、必ず無効にしてください。スクリーンセーバーとモニターの省電力は問題ありません。自動ロックとパスワード保護はありません。

注:わかりませんが、VNCはデスクトップを「現状のまま」中継するため、アプリ/システムの観点からローカルで実行するのと同じであり、理論的にはシステム/アプリをだますこともできるはずです。 RDP経由のSendKeysは許可されません。 AutoIt + SendKeysにこのVNCメソッドを使用しても、VNCを介してアクティブに接続されていても、切断されていても問題はありません(実際のデスクトップではまだログインしているため、切断後も送信キー/自動化は機能し続けますが、VNCはそうではありません)アクティブ)。

3
David

私の場合、テスト自動化の一部としてsendkeysを使用していました。ビルドエージェントがリモートデスクトッププロトコルを介して実行されるビルドマシンでは機能しません。私はそれについて満足していませんが、自動ビルドの一部としてそのテストをスキップすることができました。

Win32呼び出しを使用してウィンドウメッセージを送信すると、うまくいく可能性があります。時間があれば、いつかそれを試すことができます。

とにかく、現在のコードがリモートデスクトップセッションで実行されているかどうかを確認するためのチェックは次のとおりです。

System.Environment.GetEnvironmentVariable("SESSIONNAME").StartsWith("RDP-")
1