C# GetProcessesByName 在多个 运行 时返回 1 个进程

C# GetProcessByName returning 1 Process when multiple are running

我正在编写一个程序,让用户单击 link,这将打开一个信息路径表单并为他们自动填充一些字段。

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

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

为了把window带到最前面。出于某种原因,如果同一进程的多个 windows 打开并且我尝试提供一个进程焦点,SetForegroundWindow 会抛出一个合适的......即使我自己创建了进程并确定我正在发送正确的 window,它会产生错误消息:

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);

BringToFront 在哪里:

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 只是 return 最近打开的 InfoPath 进程。即使我有 5 或 6 个 运行,它 return 只是最近打开并关闭的一个。

所以基本上我正在寻找以下两件事之一:

1) 获取 GetProcessByName 实际上 return 信息路径进程的完整列表

2) 了解当我向 SetForegroundWindow 发送我刚刚打开的进程时它是如何失败的。

所以可能发生的事情是 infopath 为 UI window 生成一个新进程并且 parent 进程退出。所以你瞬间打开infopath.exe但是返回的进程ID并不是最终的UI进程。如果您希望获得特定的 UI window,最好按 window 标题搜索。 User32.dll 这里有一个方法可以帮助你:

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

您可以将 IntPtr.Zero 传递给 className。

  1. 如果您未绑定到 GetProcessByName 并且可以使用 WMI,那么此主题可能会有所帮助:How do I find out what user owns what process programmatically?。基本上,使用查询 "Select * from Win32_Process" 来枚举所有进程并按可执行文件进行过滤。
  2. 显然,SetForegroundWindow 需要提升权限才能继续。您可以使用此处描述的方法:UAC Window On Top