c# GetProcessByName返回1进程时,多个正在运行

本文关键字:运行 GetProcessByName 返回 进程 | 更新日期: 2023-09-27 18:04:52

我正在编写一个程序,允许用户单击一个链接,该链接将打开一个infopath表单,并为它们自动填充一些字段。

但是,由于我无法访问表单源代码来查找字段变量名,因此我必须通过使用SendKeys向表单发送"'t"来输入信息,以到达适当的字段。这意味着窗口必须有焦点。所以我使用:

[DllImport("user32.dll", SetLastError = true)]
static extern bool SetForegroundWindow(IntPtr hWnd);

为了把窗户带到前面。由于某种原因,SetForegroundWindow抛出一个合适的,如果同一进程的多个窗口是打开的,我试图给一个进程的焦点…即使我自己创建了进程,并且确信我发送了正确的窗口,它也会产生错误消息:

Process has exited, so the requested information is not available.

(这是我刚刚打开的进程。)

基本上我的代码如下:

Process[] ps = Process.GetProcessByName("InfoPath");
if (ps.Length != 0)
{
    for(int i = 0; i < ps.Length; i ++)
        ps[i].Close();
}
Process infoPath = new Process();
infoPath.StartInfo.FileName = "InfoPath.exe";
infoPath.StartInfo.Arguments = "TemplateLocation.xsn";
infoPath.Start();
try{
    BringToFront(infoPath);
}catch (Exception e)
{
    // handle failure
}
SendKeys.SendWait("'t't't't");
SendKeys.SendWait(information);

Where BringToFront is:

private void BringToFront(Process pTemp)
{
    try
    {
       SetForegroundWindow(pTemp.MainWindowHandle);
    }catch(Exception e)
    {
       //fails here saying that the process has exited, so the requested information is not available.
       throw e;
    }
}

我得到的问题是GetProcessByName只返回最近打开的InfoPath进程。即使我有5个或6个正在运行,它也只返回最近打开的一个并关闭它。

基本上我要找的是以下两种情况之一:

1)获取GetProcessByName以实际返回infopath进程的完整列表

2)找出SetForegroundWindow是如何失败的,当我发送它一个进程,我刚刚打开。

c# GetProcessByName返回1进程时,多个正在运行

  1. 如果你没有绑定GetProcessByName并且可以使用WMI,那么这个主题可能会有所帮助:我如何通过编程找到哪个用户拥有哪个进程?基本上,使用查询"Select * from Win32_Process"来枚举所有进程并按可执行文件进行过滤。
  2. 显然,SetForegroundWindow需要提升权限才能继续。您可以使用这里描述的方法:UAC窗口在顶部

所以可能发生的情况是infopath为UI窗口生成一个新进程,父进程退出。因此,您立即打开infopath.exe,但返回的进程ID不是最终的UI进程。如果你想获得一个特定的UI窗口,你最好通过窗口标题进行搜索。在这里,User32.dll有一个方法可以帮助你:

    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr FindWindow(IntPtr className, string lpWindowName);

你可以传递IntPtr。0到className