发送前C#SendKeys等待程序加载
长话短说,我试图在电脑启动时自动化一些事情。 我以为我会编写一个C#控制台应用程序来执行此操作,然后将其添加到Windows中的计划任务以在启动时执行。 我的问题是一个程序,它需要一个密码,并没有选择通过命令行打开。 因此必须手动输入。 我的想法是从KeePass数据库中检索我的密码,并使用SendKeys输入密码并登录到程序。 我遇到的问题是加载所需的时间; 我无法检测GUI界面何时加载并准备好用于SendKeys。 有什么方法可以检测到这个? 我假设我所需要的是“Process”类,因为那是我用来运行程序的。 还要注意,当我使用Process.Start()运行可执行文件时,程序会创建另一个登录进程,但它没有关联的窗口,我可以使用Windows API调用看到。
好吧,那很长,我可以重新上限......
问题:从C#中检测何时加载了第三方程序(即启动画面消失,并且GUI已准备好用于用户交互 - 这意味着如果进程正在运行或不运行,我不能只依靠它)。 此外,没有命令行选项的第三方程序,或者我会运行密码作为参数。
目标:要使用SendKeys来自动输入密码,但我的程序必须等待第三方应用程序完成加载。
注意:使用C#.NET 3.5控制台应用程序不检测加载为我自己的形式,但第三方,否则这将是容易的(即form_loaded事件...)
谢谢你看我的问题,如果你想要更多的细节或任何让我知道的。
更新 :
问题解决了! 我收到的两个答案结合起来,给了我想要的解决方案。 所以如果任何人稍后会遇到这个问题,这就是我所做的工作。
所以这个程序会自动登录一些你必须登录的客户端软件。 我的问题是,该软件没有提供许多其他程序提供的命令行参数的选项或文档,因此您可以使用密钥文件或其他东西登录。 该程序还禁用了复制和粘贴功能,因此需要手动输入密码HAS,如果您像我一样使用密码,那么这是一个很大的麻烦,复杂的密码无法使用。 所以我写了这个程序,为了我的利益以及其他人的工作; 我只是安排它在登录到我的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/en-us/library/xb73d10t%28v=vs.71%29.aspx
尝试看看:http://www.acoolsip.com/a-cool-blog/science-and-technology/151-c-sending-commands-to-independent-windows.html
你可以检查窗口是否显示(使用链接),然后发送消息(也在链接上)
链接地址: http://www.djcxy.com/p/63593.html