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是如何失败的,当我发送它一个进程,我刚刚打开。
- 如果你没有绑定GetProcessByName并且可以使用WMI,那么这个主题可能会有所帮助:我如何通过编程找到哪个用户拥有哪个进程?基本上,使用查询"Select * from Win32_Process"来枚举所有进程并按可执行文件进行过滤。
- 显然,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