17

I'm using following code to iterate over a list of browsers executable paths and start each of them:

foreach (var browser in browsers)
{
    var proc = new Process();
    proc.StartInfo.FileName = browser.ExecutablePath;
    proc.StartInfo.Arguments = "http://google.com";
    proc.Start();
    proc.WaitForExit();
    Console.WriteLine(proc.ExitCode.ToString());
    proc.Close();
}

What is should do is: it should open browser window with google.com loaded and stop the application until the window is closed. And it works fine for both IE and Firefox, but fails with Chrome.

For Chrome proc is in Exit state just after launching the browser, when the window is still active and visible.

I tried using some of chromium command line switches, including --new-window and --single-process but with no success.

Question is, how can I force Google Chrome to run in the process it is started in, so it would be possible to wait until window is closed?

Update

Just to clarify the question:

  • I know why it does not work - it's because Chrome uses multiple processes for different things, like different tabs, plug-ins, etc.
  • I tried to find the correct process looking on process tree, but found nothing.
  • I can't just take the latest process created by chrome, because it may be the process created for a pluging the page requires, not the page itself.
MarcinJuraszek
  • 124,003
  • 15
  • 196
  • 263
  • Notice that Chrome creates a seperate process for every tab, unlikely IE and Firefox runs tabs within seperate threads. – mehmet mecek Oct 23 '13 at 22:29
  • Chrome uses several processes to run everything. There was a discussion on this over at super user: http://superuser.com/questions/461552/why-are-there-multiple-chrome-instances-running-even-though-i-only-have-one-wind – broke Oct 23 '13 at 22:32
  • Assuming that the process of opened tab is a child process of the process you started, I tried to find child processes of proc by using the code here [http://stackoverflow.com/questions/7189117/find-all-child-processes-of-my-own-net-process-find-out-if-a-given-process-is] but didnt work, sorry... – mehmet mecek Oct 23 '13 at 23:50
  • @Mecek I tried the same and found nothing. Looks like chrome always have one *master* process which handles all other, no matter how you open new window/tab. See my update at the end of the question. – MarcinJuraszek Oct 24 '13 at 01:39
  • What do you expect to happen if Chrome is already open? Are you trying to detect when all tabs related to a site are closed or Chrome itself in its entirety? – Basic Oct 26 '13 at 18:41
  • I need to know when all related tabs (means the one opened by the process and all opened from that site e.g. by javascript code) are closed. I also need a way to kill these tabs when needed. – MarcinJuraszek Oct 26 '13 at 19:07
  • 1
    You can't make this work with the Process class. You'd have to write a Chrome extension. – Hans Passant Oct 26 '13 at 21:44

3 Answers3

10

If you want to open/close entire Chrome window:

Chrome by default is constantly running in background because of its default settings. Change this option to unchecked:
Settings > Show advanced > System > 'Continue running background apps when Google Chrome is closed'

So you have to make sure Chrome is closed before you run it again by your code. That works for me.


If you want to open/close related tabs only:

Chrome have one 'mother process' and some child processes. The problem is that if you run chrome using your code you are trying to create new instance of 'mother process' but the existing one won't let you do it. She'll instantly kill your new process and create her own child instead. That's how it works...

So, all you need is figure out how to run another 'chrome mother process' and prevent the previous hug from killing her ;P

I figure out this solution:
Run new chrome process with this parameter --user-data-dir="%temp%/random_name". This means that you are opening chrome with new user profile.

Advantages:

  • It works
  • Chrome is opening in new window
  • Chrome is closing when all related tabs are closed

Disadvantages:

  • Default settings (no bookmarks, etc) but you can copy them from default user profile directory

So, maybe you should look for sth in this direction...

Damian Drygiel
  • 17,900
  • 4
  • 35
  • 28
  • 1
    +1, I just posted a similar answer then noticed you've mentioned `--user-data-dir` already, so I deleted mine. Why are you saying the program needs to be run as administrator? It works for me without admin rights, as long as the path specified to `--user-data-dir` is unique and reachable without admin rights. Also, `--disable-extensions` and/or `--incognito` may help reducing the new profile footprint. – noseratio Oct 30 '13 at 04:38
  • @Noseratio When I was testing my solution It wasn't working without Admin rights but if it worked for you then it seems not to be a rule. Edit: Maybe you've just run Visual Studio as Admin and that's why it worked for you? – Damian Drygiel Oct 30 '13 at 14:15
  • All chrome extension processes have `--extension-process` argument. – Damian Drygiel Oct 31 '13 at 00:43
0

Another command line parameter that (sort of) works is --chrome-frame. It appears Chrome uses WinInet API when in this mode, because the IE history is available. I do like more the idea about using --user-data-dir with a unique temp folder, as proposed by @DamianDrygiel.

noseratio
  • 59,932
  • 34
  • 208
  • 486
0

You could find all the child processes of the Chrome process you run and then wait for them to finish.

There is a StackOverflow question that has some useful code: Find all child processes of my own .NET process / find out if a given process is a child of my own?. Also you might find this useful: Monitor child processes of a process.

Community
  • 1
  • 1
Igor Ševo
  • 5,459
  • 3
  • 35
  • 80