繁体   English   中英

C#SendKeys等待程序加载后再发送

[英]C# SendKeys Wait for Program to Load before sending

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

好的,那很长,我可以重新给...

问题:从C#检测何时加载了第三方程序(即,启动屏幕消失了,GUI已准备好与用户交互-这意味着我不能仅仅依靠Process是否在运行)。 另外,第三方程序没有命令行选项,否则我将使用密码作为参数来运行它。

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

注意:使用C#.NET 3.5控制台应用程序不会检测到我自己的表单的负载,而是第三方,否则这很容易(即form_loaded事件...)

感谢您查看我的问题,如果您需要更多详细信息或任何让我知道的信息。

更新

问题解决了! 我收到的两个答案相结合,为我提供了所需的解决方案。 因此,如果以后有人遇到这个问题,这就是我所做的工作。

因此,该程序会自动为您必须登录的某些客户端软件进行登录。 我的问题是该软件未提供许多其他程序提供的命令行参数选项或文档,因此您可以使用密钥文件或其他内容登录。 该程序还禁用了复制和粘贴操作,因此必须手动输入密码,如果您像我一样使用长时间的复杂密码且没有模式,那么这将是一个很大的麻烦。 所以我写这个程序对我和其他工作都是有益的。 我只是安排它在登录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...
}

尝试看一下: http : //www.acoolsip.com/a-cool-blog/science-and-technology/151-c-sending-commands-to-independent-windows.html

您可以检查窗口是否显示(使用链接),然后发送消息(也在链接上)

您可以在启动进程后使用Process.WaitForInputIdle进行检查,并等待其完全启动,这是一个简单的示例:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM