Search code examples
c#processsendkeys

C# GetProcessByName returning 1 Process when multiple are running


I'm writing a program that lets the user click a link that will open an infopath form and auto-populate some fields for them.

However, since I do not have access to the forms source code to find field variable names, I must enter the information via sending "\t" with SendKeys to the form to reach the appropriate field. This means that the window must have focus. So I used:

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

In order to bring the window to the front. For some reason, SetForegroundWindow throws a fit if multiple windows of the same process are open and I try to give a process focus... even when I created the process myself and am sure I'm sending the right window, it produces the error message:

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

(This is for the process that I just opened.)

Essentially my code is as follows:

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

The issue that I get is that GetProcessByName only ever returns the most recently opened InfoPath process. Even though I'll have, say, 5 or 6 running, it returns only the most recently opened one and closes it.

So basically I'm looking for one of two things:

1) Get GetProcessByName to actually return a full list of the infopath processes

or

2) Find out how SetForegroundWindow is failing when I'm sending it a process that I just opened.


Solution

    1. If you are not bound to GetProcessByName and can use WMI, then this topic may help: How do I find out what user owns what process programmatically?. Basically, use the query "Select * from Win32_Process" to enumerate all the processes and filter by executable.
    2. Apparently, SetForegroundWindow requires elevated privileges to proceed. You can use the approach described there: UAC Window On Top