[C#] Getting PID from window title

01/09/2013 12:15 iCraziE#1
I searched everywhere and can not find anything useful on this topic. Is this even possible?

I have multiple process. Each have the same process name, but different window titles.

I want to use the window title to find out the process ID.

Any suggestions? Thank you.
01/09/2013 12:43 Kraizy​#2
PHP Code:
for each p as process in process.getprocessesbyname("notepad")
   
msgbox(p.mainwindowtitle " - " p.id)
next 
01/09/2013 13:14 Lawliet#3
In C#^^

Code:
public int GetPidBy(string name)
{
      forech(var process in process.GetProcessesByName(name){
             return process.id;
      }
      return 0;
}
01/09/2013 13:28 Kraizy​#4
Ups nicht gesehen, dass im Titel C# stand..naja sollte trzdm nicht allzu schwer sein, ne kleine Schleife zu übersetzen.
01/09/2013 13:33 qkuh#5
Quote:
Originally Posted by Lawliet! View Post
In C#^^

Code:
public int GetPidBy(string name)
{
      fore[COLOR="Red"]a[/COLOR]ch(Process proc in [COLOR="Red"]P[/COLOR]rocess.GetProcessesByName(name){
             return proc.id;
      }
      return 0;
}
Wenn dann richtig :)
01/10/2013 00:05 »jD«#6
Thats not what he is asking. He's asking for the window title, not the process name which is just the EXE File name without the extension. Again you have you use a Win API and the one you are looking for is FindWindow. Kraizy​'s post is the right way to do it but there is arguably a faster way to do it if you have lots of processes running!

You should first use FindWindow then GetWindowThreadProcessId. Example follows:

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

[DllImport("user32.dll", SetLastError=true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

IntPtr hWnd = FindWindow(null, "Title of the Window!");
int processID = 0;
GetWindowThreadProcessId(hWnd, out processID);

MessageBox.Show("Process ID for Window is " + processID);
-jD
01/10/2013 00:32 Kraizy​#7
well, again vb.net but u should be able to translate it to c#:
PHP Code:
for each x in p as process in process.getprocessesbyname("notepad"where p.mainwindowtitle "Untitled - Notepad"
   
msgbox(x.id)
next 
Not sure if its 100% correct, I'm on my phone atm..also, if u r sure that there is only one same window title, u dont need to use a loop

@jD ur method is kinda overkill
01/10/2013 01:35 »jD«#8
Quote:
Originally Posted by Kraizy​ View Post
well, again vb.net but u should be able to translate it to c#:
PHP Code:
for each x in p as process in process.getprocessesbyname("notepad"where p.mainwindowtitle "Untitled - Notepad"
   
msgbox(x.id)
next 
Not sure if its 100% correct, I'm on my phone atm..also, if u r sure that there is only one same window title, u dont need to use a loop

@jD ur method is kinda overkill
You would need to use a loop. getprocessesbyname returns all processes with the friendly exe name. For example, I could have chrome.exe running and the "name" that I would use is getprocessesbyname("chrome"). However, I would need to loop through them all to find the one out of possible 100 processes that are running to find the single website title I was looking for, hence why you would need to loop.

EDIT: Sorry didn't see the call to "where". Still, chrome uses multiple child processes for each tab and each has the same main window title handle applied to them. FindWindow finds only the parent process to each child process.

ALSO, callig GetProcessesByName in a foreach or with a linq call on the end of it causes GetProcessesByName to be called each iteration of the loop. You are better storing it in a variable before using it in a foreach or a loop.

I just did some tests, the P/Invoke is almost 5x faster ^.^

-jD
01/10/2013 01:41 iCraziE#9
Hmm, that's not quite what i was looking for. But, i've come up with this now. How can i specify the process ID it shows in the message box now, in my script. Lets say for example I want to say getprocessbyid and use the value it got from my code here.

Code:
private void function1()
        {
            Process[] processlist = Process.GetProcessesByName("my process");

            string title = "title";
            string procID;
            
            foreach (Process process in processlist)
            {
                if (String.Equals(process.MainWindowTitle, title))
                {
                    procID = process.Id.ToString();
                    MessageBox.Show("This is the process ID: " + process.Id);
                    MessageBox.Show(procID);
                }
                else
                {
                    MessageBox.Show("Window not found");
                }                
            }
        }
01/10/2013 03:10 »jD«#10
Sorry, I don't exactly get what you are asking?

-jD
01/10/2013 04:55 iCraziE#11
Hmm, I think the code you posted before might work for me. I am going to try it right now. I didn't see it when I made my last post. But it looks good. Exactly what I was looking for I think.
01/10/2013 05:24 »jD«#12
Alright!

-jD