2012-05-22 70 views
0

长期以来,我试图在计算机启动时自动执行一些操作。我以为我会编写一个C#控制台应用程序来执行此操作,然后将其添加到Windows中的计划任务以在启动时执行。我的问题是一个程序,它需要一个密码,并没有选择通过命令行打开。因此必须手动输入。我的想法是从KeePass数据库中检索我的密码,并使用SendKeys输入密码并登录到程序。我遇到的问题是加载所需的时间;我无法检测GUI界面何时加载并准备好用于SendKeys。有什么方法可以检测到这个?我假设我所需要的是“Process”类,因为那是我用来运行程序的。还要注意,当我使用Process.Start()运行可执行文件时,程序会创建另一个登录进程,但它没有关联的窗口,我可以使用Windows API调用看到。C#SendKeys在发送之前等待程序加载

好了,这是很长,我可以重新盖...

问题: 从C#当第三方程序加载检测(即启动画面消失了,GUI准备用户交互 - 意义如果Process正在运行,我不能只依靠它)。 此外,第三方程序没有命令行选项,或者我只是将它作为参数运行密码。

目标: 要使用SendKeys来自动输入密码,但我的程序必须等待第三方应用程序完成加载。

注: 使用C#.NET 3.5的控制台应用程序 未检测出负载为我自己的形式,而是第三方,否则这将是容易的(即form_loaded事件...)

谢谢你看我的问题,如果你想了解更多细节或任何事情,请告诉我。

UPDATE

问题解决了! 我收到的两个答案合起来给我我想要的解决方案。所以如果任何人稍后会遇到这个问题,这就是我所做的工作。

所以这个程序自动登录一些你必须登录的客户端软件。我的问题是,该软件没有提供许多其他程序提供的命令行参数的选项或文档,因此您可以使用密钥文件或其他东西登录。该程序还禁用了复制和粘贴功能,因此需要手动输入密码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... 
} 

回答

0

你可以用过程检查。 WaitForInputIdle开始后的过程,并等待,直到完全启动,这里是一个简单的例子:

http://msdn.microsoft.com/en-us/library/xb73d10t%28v=vs.71%29.aspx

+0

谢谢你的建议,我接过了另一个项目,但现在我又回到了这个项目。我明天就会拍摄这张照片,看看它能否与我所拥有的一样。 – akagixxer

相关问题