C#SENDKEYS送信前にプログラムがロードされるのを待ちます
-
13-12-2019 - |
質問
それで、長い話の短い、私のコンピュータが起動したときにいくつかのことを自動化しようとしています。私はこれを行うためにC#コンソールアプリケーションを書いてから、起動時に実行されるWindowsのスケジュールタスクに追加しました。私の問題は1つのプログラムであり、パスワードを必要とし、コマンドラインでオプションを開くオプションはありません。したがって、手動で入力する必要があります。私の考えは、keepassデータベースからパスワードを取得し、SendKeysを使用してパスワードを入力してプログラムにログインします。私が持っている問題は、ロードするのにかかる時間です。 GUIインターフェイスがロードされたときに検出する方法はありません。これを検出する方法はありますか?私が扱う必要があるのは私がプログラムを実行していたもの以来、 "Process"クラスです。また、Process.Start()を使用して実行可能ファイルを実行すると、プログラムはログインするための別のプロセスを作成しますが、Windows API呼び出しを使用して表示できるウィンドウはありません。
大丈夫だった、私は再キャップすることができます...
問題: C#からサードパーティ製プログラムがロードされたとき(すなわち、スプラッシュスクリーンが消去され、GUIがユーザの対話の準備ができている - プロセスが実行されているかどうかに頼ることができない場合)。 また、サードパーティのプログラムのコマンドラインオプションはありません。または、パスワードとしてパスワードを実行するだけです。
目標: パスワードの入力を自動化するためにSendKeysを使用するが、プログラムはサードパーティのアプリケーションがロードを終了するのを待つ必要があります。
ノート: C#.NET 3.5コンソールアプリケーションを使用する 自分の形の負荷を検出しないが、そうでなければこれは簡単になるでしょう(すなわち、Form_Loadedイベント...)
あなたがもう詳細を望んでいるなら、私の質問を見ていただきありがとうございます。
更新:
問題解決しました! 私が受け取った2つの答えは私に私が欲しかった解決策を私に与えるために組み合わされました。だから誰かが後でこれに遭遇したのであれば、ここに私がそれを作るためにしたことです。
だからこのプログラムは、ログインする必要があるクライアントソフトウェアのログインを自動化します。私の問題は、ソフトウェアが他の多くのプログラムを提供するコマンドラインのパラメータのオプションまたはドキュメンテーションではないということです。このプログラムはコピーアンドペーストを無効にして、パスワードを手動で入力しなければならないため、パソコンのようなパスワードを使用する場合は大きな痛みです。だから私は私の利益のためにこのプログラムを職場でも書いた。ログオン時に自分のWindowsマシンに実行するようにスケジュールし、クライアントソフトウェアを開き、自動的にログインを実行します。
//
// IMPORTANT Windows API imports....
//
[DllImport("user32.dll", SetLastError = true)]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint procId);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool SetForegroundWindow(IntPtr hWnd);
// When I get to this point in my code, I already had the password and window title...
string password = "password";
string title = "window title";
// This gets a handle to the window I want where "title" is the text in the title
// bar of the window as a string.
// This is a Windows API function that must be imported by DLLImport
// I had to get the handle this way because all I knew about the third party
// window was the title, not the process name or anything...
IntPtr hWnd = FindWindowEx(IntPtr.Zero, IntPtr.Zero, null, title);
// Now that I have a handle to the login window I used another windows API
// call to get the process ID.
// This windows API call gives me the Process ID as an out parameter and returns
// the thread ID of the window. I don't use the thread it, but maybe you can...
uint loginWindowProcId;
uint loginWindowThreadId = GetWindowThreadProcessId(hWnd, out loginWindowProcId);
// now I can just use .NET to find the Process for me...
Process loginWindowProcess = null;
if (0 != loginWindowProcId)
{
// get the process object
loginWindowProcess = Process.GetProcessById((int)loginWindowProcId);
// This right here is why I wanted the Process structure. It takes a
// little while for the client software to load and be ready. So here
// you wait for the window to be idle so you know it has loaded and can
// receive user input, or in this case keys from "SendKeys".
loginWindowProcess.WaitForInputIdle();
// I use yet another windows API call to make sure that the login window
// is currently in the foreground. This ensures that the keys are sent
// to the right window. Use the handle that we started with.
SetForegroundWindow(hWnd);
// Now send the password to the window. In my case, the user name is
// always there from my windows credentials. So normally I would type in the
// password and press ENTER to login. But here I'll use SendKeys to mimic my
// behavior.
SendKeys.SendWait(password); // send password string
SendKeys.SendWait("{ENTER}"); // send ENTER key
// Now the client should be logging in for you! : )
// IMPORTANT NOTE
// If you are using a console application like I am, you must add a reference to
// System.Windows.Forms to your project and put "using System.Windows.Forms;" in
// your code. This is required to use the "SendKeys" function.
//
// Also this code is just for my testing (quick and dirty), you will want to write
// more checks and catch errors and such. You should probably give the
// WaitForInputIdle a timeout etc...
}
. 解決
プロセスを開始した後にProcess.WaitForInputIdleで確認でき、完全に開始されるまで待ってください。これは簡単な例です。
http://msdn.microsoft。COM / ja-us / library / XB73D10T%28V= VS.71%29.ASPX
他のヒント
それを見てみてください:
ウィンドウが表示されているかどうか(リンクを使用)、次にメッセージを送信する(リンク上)