Open Chrome from command line and wait till it's closed - c#

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.

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...

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.

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.

Related

Open Explorer.exe and raise event when exe is exited [duplicate]

I have a program that is opening an explorer window to a certain folder but i want to perform an action right after the explorer window is closed, but if I use the following code:
Process proc = Process.Start("explorer.exe", "D:\\");
proc.WaitForExit();
It is opening the explorer window as desired but the WaitForExit command has no effect and it just goes right past it.
Is there a different way of opening the explorer window that will be able to let me know when it is closed by the user?
The problem is explained pretty well at The Old New Thing:
The reason that WaitForSingleObject returns immediately is that Explorer is a single-instance program (well, limited-instance). When you open an Explorer window, the request is handed off to a running copy of Explorer, and the copy of Explorer you launched exits. That's why your WaitForSingleObject returns immediately.
He offers a couple solutions you could probably use (with some heavy use of PInvoke), like using something like this.
In the end it might just be easier for you to use some other type of file browser maybe from a C# library somewhere that you have more control over, rather than explorer.
Cannot regenerate the error. Just tried this:
Process.Start("explorer.exe", "D:\\").WaitForExit();
and it blocks the current thread and waits until I close the explorer windows. Make sure that you're not executing the command on another thread than the one you want to block. Also make sure that you set every instance of a window to start a new instance of explorer.exe via importing below .reg file:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer]
"DesktopProcess"=dword:00000001
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer]
"DesktopProcess"=dword:00000001
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\BrowseNewProcess]
"BrowseNewProcess"="Yes"
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\BrowseNewProcess]
"BrowseNewProcess"="Yes"
You'll need to restart your computer for this to take effect.

Closing a specific IE browser with process ID

I am currently developing a tool that will run automation test cases.
So at the moment, I wanted to make the test cases run concurrently by creating a new thread for each of the test case.
Thread playThread = new Thread(this.PlayMainConcurrent);
playThread.Start(main);
When the playThread is started, an IE browser will launch and perform the automation, and there will be a few IE browser launched together. I want to know is there any way to close a specific IE browser among the browser launched by process id?
What I have tried is using
playThread.Abort();
but this only exited the thread, not closing the browser.
Also, I have tried using Process.Kill()
foreach (var proc in Process.GetProcessesByName("iexplore"))
{
proc.Kill();
}
this did closes the ie browser, however i don't want it to close all my ie browser because i just one to kill only one specific browser.
Additionally, my project can only support .NET Framework 2.0 and are not able to update to newer one.
Thanks in advance.
The trick is to keep the reference of each process
// Start a procecss that opens a Notepad
Process myProcess = Process.Start("Notepad.exe")
// Close process by sending a close message to its main window.
myProcess.CloseMainWindow();
// Free resources associated with process.
myProcess.Close();
Microsoft Documentation

How to open two separate (default) browser windows instead of new tabs

I'm trying to use C# to open two separate browser windows side by side. I've tried using Process.Start(url) but that causes Chrome to open new tabs instead of new windows. This seems to work on IE, however I'd like to have code that can work with different types of browsers, namely: IE, Chrome, Firefox, and Safari. How do I detect the default browser and then open two separate windows side-by-side? Additionally, I want to be able to position the two windows next to each other, is that possible?
If you want to open new window in chrome instead of new tab, this code worked for me
Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = "chrome";
process.StartInfo.Arguments = <yoururl> + " --new-window";
process.Start();
This is more about the way that the browser is configured than how the process is called from C#. In both cases, the system simply calls the default program assigned to handle the URL. There may or may not be arguments to that command, but typically it will simply invoke chrome.exe <url> and from there, the chrome.exe process decides how to handle the parameter.
The only method I am aware of would be to examine the registry (under HKEY_CLASSES_ROOT\http\shell\open\command) and parse the string value. Once you know the specific browser, you may be able to control the presentation using command-line arguments. Of course, this is specific to Windows and may be a pain to manage.
If the browser does not support setting a geometry from the command line, you will need to use FindWindow and SetWindowPos (using P/Invoke) to manipulate the window locations.
I am not sure about your application, but would embedding a WebBrowser Control meet your needs? Then you would have total control of the presentation.

Open explorer window and wait for it to close

I have a program that is opening an explorer window to a certain folder but i want to perform an action right after the explorer window is closed, but if I use the following code:
Process proc = Process.Start("explorer.exe", "D:\\");
proc.WaitForExit();
It is opening the explorer window as desired but the WaitForExit command has no effect and it just goes right past it.
Is there a different way of opening the explorer window that will be able to let me know when it is closed by the user?
The problem is explained pretty well at The Old New Thing:
The reason that WaitForSingleObject returns immediately is that Explorer is a single-instance program (well, limited-instance). When you open an Explorer window, the request is handed off to a running copy of Explorer, and the copy of Explorer you launched exits. That's why your WaitForSingleObject returns immediately.
He offers a couple solutions you could probably use (with some heavy use of PInvoke), like using something like this.
In the end it might just be easier for you to use some other type of file browser maybe from a C# library somewhere that you have more control over, rather than explorer.
Cannot regenerate the error. Just tried this:
Process.Start("explorer.exe", "D:\\").WaitForExit();
and it blocks the current thread and waits until I close the explorer windows. Make sure that you're not executing the command on another thread than the one you want to block. Also make sure that you set every instance of a window to start a new instance of explorer.exe via importing below .reg file:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer]
"DesktopProcess"=dword:00000001
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer]
"DesktopProcess"=dword:00000001
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\BrowseNewProcess]
"BrowseNewProcess"="Yes"
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\BrowseNewProcess]
"BrowseNewProcess"="Yes"
You'll need to restart your computer for this to take effect.

Run firefox in background from C#

I run Firefox (default browser) from C# with the code:
System.Diagnostics.Process.Start(browser.Document.Url.ToString());
I want Firefox to run in the background, because every time is open a new tab, the Windows is focusing on the Firefox, and is annoying.
How can I control Firefox tabs, close them after a time ?
You can use a ProcessStartInfo to tell it to run hidden or minimized or whatever. Not sure how to programmatically manipulate FireFox but I'm sure there's an API.
var psi = new System.Diagnostics.ProcessStartInfo();
psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
psi.FileName = browser.Document.Url.ToString();
var proc = System.Diagnostics.Process.Start(psi);
//after a while...
proc.Kill();
Technically, you are not starting Firefox, you are executing a url.
I'm not sure exactly what Windows does, but in effect, that url is opened in the system's default browser, be it IE, FF or some other thing that might not even support tabs, so finding and killing Firefox is not really a solution if the url is opened in Opera.
Moreover, the Process.Start method returns null if no process is actually started by the call, so if Firefox is already running and just displays an additional tab, you will get a null as the result of the call.
So, I'm pretty sure this is impossible to do in a broad sence (any browser), and, unless Firefox has some sort of API for client-side management, not possible for that scenario either.
BTW, on my system (IE is the default browser), the WindowStyle property is not working as expected, as IE pops up to the front.
Rather than trimming the tabs, why not just kill the entire Firefox process and restart it periodically?
You won't be able to do this. First of all, I'm pretty sure running Firefox in the background won't stop it gaining focus when a new tab is opened. Second, it is difficult to control firefox programmatically. The only way to do what you want is to use a plugin like MozRepl. You could also try using selenium or your own JavaScript to control the browser behaviour. I needed to be able to open and close tabs in a shell script without using selenium or MozRepl, check out my question From a shell script open a new tab in a specific instance of Firefox

Categories