I'm working with Selenium in my .NET Application, when using quit() on either a Firefox or Chrome driver the browser processes do not close correctly however the WebDriver process gets closed. So when my Application terminates the remaining Firefox and Chrome processes remain opened in the background (as child processes to my Application).
Screenshot when running normally with Firefox Driver Running
After trying to using quit() and closing my application
I'm looking for a way to close the WebDriver and the browser processes with it (without using a lazy "kill all processes named 'chrome' or 'firefox'"), if this is not possible then a a way to terminate all child processes associated with my Application when it exits would work for me too.
The current solutions that are available makes use of ManagementObjectSearcher but this would not be ideal because it would not work with Linux (Mono) but only on Windows.
I've tried to close all Windows using close() before using quit() but the browser process still remains opened
I've tried to debug the statements to see if it's actually sending a quit command to the Web Driver and it is.
Since i am using a RemoteDriver that is connected to a DriverService, i am using quit() on the RemoteDriver before disposing of the DriverService.
I expect all browser processes including WebDrivers to be closed when i use quit() or at least have a solution to terminate all child processes associated with my application to be killed before exiting the Application. But only the web drivers get closed and the browser processes remain opened in the background.
Chrome when not in headless mode, does actually close the Window but the process remains opened.
Firefox when not in headless mode, does not close the Window at all. even when using close()
Example Code
// Creating the RemoteDriver with Options
var DriverService = ChromeDriverService.CreateDefaultService();
var DriverOptions = new ChromeOptions();
DriverOptions.AddArgument("headless");
DriverOptions.AddArgument("mute-audio");
DriverService.Start();
var RemoteDriver = new RemoteWebDriver(DriverService.ServiceUrl, DriverOptions);
// Quitting
RemoteDriver.Quit();
DriverService.Dispose();
Update
After testing the same code on Linux, the browser processes has closed as expected unlike the problem that i faced when using Windows 10. After some more searching i discovered that other people has faced the same issue, see this issue and it seems to either be a problem related to a Windows update or the WebDrivers (I'm using the latest drivers that are available and stable) However this issue has not been opened or mentioned in a while.
In conclusion, this problem is only on Windows and more specifically Windows 10. There is still no solution to this problem and it's out of the reach of Selenium and more towards a WebDriver issue. Still.
Update
This is an issue on Opera as well, a desirable workaround as i mentioned above would be to kill all child processes associated with your process. To those who keep saying "USE CLOSE BEFORE QUIT" is not a solution as i explained more than once what i have already tried and what the unexpected results were
The solution i mentioned above can be accomplished with "ManagementObjectSearcher" but since i made this post i have learnt that this issue is only reproducible on Windows and is out of reach from your code, Selenium and more to do with the WebDriver or Browsers themselves. So the solution is to only use ManagementObjectSearcher to kill child processes associated with your process if you are running on Windows, because this will not work on Mono. But you don't need to worry since i already explained that this issue is not reproducible on Linux, only Windows.
Thanks for the help.
This is what I use. It won't help in cases where the driver has crashed (it's Java):
boolean closecaught = false;
try
{
if (driver!=null) { driver.close(); }
}
catch (Exception e)
{
closecaught = true;
System.out.println(e.toString());
try {
driver.quit();
}
catch (Exception exce)
{
System.out.println("Exception quitting" + exce.toString());
}
}
if (closecaught)
{
}
else
{
try
{
driver.quit();
}
catch (Exception ex)
{
// don't worry it should close
}
Related
i have a strange problem with IE8 installed in xp. i was trying to launch IE using an System.Diagnostics.Process.Start method in c#. And i have a requirement to trap the exited event of the IE and do some operation. But i ended up in a rather strange problem where the IE immediately fires the exited event after launch.
this is the sample code
Process objProcess = Process.Start("IEXPLORE.EXE", "http://google.com");
if (objProcess != null)
{
objProcess.EnableRaisingEvents = true;
objProcess.Exited += new EventHandler(myProcess_Exited);
}
public static void myProcess_Exited(object sender, System.EventArgs e)
{
MessageBox.Show("You exited");
}
But the above code perfectly works when laucnching different process (ex:notepad) and it fires the exit event when i close the exe.
this only gives problem launching IE 8. Can someone clarify me what is the problem??
UPDATE
Most friends replied my post and saying why you can't just use an URL? why stick with IE?
here the reason
the ultimate aim of the app is to launch an URL from the windows application and will hide an exe when working on the IE. And show the exe after closing the IE.
Thanks
Most probably is that you have IE already running as a process, so when you try to launch it again as a new process it looks that there are IE running already, tells it that user initiated a new window (so the initial IE will create a "new" window rather than a new one) and exit.
Possible solution:
try starting the process with "-nomerge" command line option:
Process objProcess = Process.Start("IEXPLORE.EXE", "-nomerge http://google.com/");
Interesting observation: objProcess.ExitCode (for IE8 at least) will be equal to 0 if exited passing control to another instance, and 1 if it was actually closed by user.
If another instance of iexplore.exe is already running on the machine, new instances will connect to that and immediately exit. Also, it's possible that even in the case where iexplore is not running, the multiprocess architecture of Internet Explorer 8 has the parent launch child broker process and exit immediately.
But these answers are besides the point. You should not be launching Internet Explorer directly. If the user has configured another default browser, they will be unhappy that you are ignoring their preferences. Instead, why don't you try
System.Diagnostics.Process.Start("http://google.com");
directly and that will do the right thing. You won't be able to tell when the browser closed, but if the command has opened a new tab in an existing browser session for example, the browser close event will be meaningless to your application.
Maybe IEXPLORE itself launches a different process for the URL and ends the process you created? Like a fork on Unix?
I'm trying to start Chrome from WPF application using .NET framework 4.0 with code similar to the following:
var arg = string.Format("--app=\"{0}\" --window-size=1024,1000", "http://bing.com");
this._process = Process.Start("chrome.exe", arg);
this._process.WaitForExit();
// Perform relevant operations once the process completes/ exit
I'm opening chrome in app mode.
Case 1: When I have a no additional Chrome instance/window opened, WaitForExit blocks the control till the Chrome window created through code is closed - This is what I'm looking for.
Case 2: If I have a Chrome instance running already. Then it does not wait for the chrome instance created through code to exit and moves on to the next line. I want to have similar experience as in case 1, that is the control should be blocked until the user closes the chrome instance.
Is there anything extra I need to do get this working when I have multiple instances of Chrome already opened?
You can use Process.GetProcessesByName to get all opened chrome process,and invoke WaitForExit for each process
Process.Start(#"%AppData%\..\Local\Google\Chrome\Application\chrome.exe",
"http:\\www.YourUrl.com");
You can also try with dis
Process.Start("chrome", #"http://www.stackoverflow.net/");
i am trying to start a browser instance as a process from a c# code. then i want to kill the same instance of the browser. I tried finding the same instance with process id . But the process ids are different in task manager and the initial id which i got when i started the process.
what's the solution? why is this happening? Development enviorment is windows 7.
int ID= 0;
void Start()
{
ProcessStartInfo startInfo = new ProcessStartInfo("iexplore.exe");
startInfo.Arguments = "http://www.google.com";
Process ieProcess = Process.Start(startInfo);
ID= ieProcess.Id;
}
void Stop()
{
foreach (Process p in System.Diagnostics.Process.GetProcessesByName("iexplore"))
{
if ((p.Id == ID))
{
p.Kill();
}
}
This code will not work if IE is already launched. Close all IE browsers and then try to run the code. If it works then you may have to look for solution suggested in following link
similar post-
Process.kill() denied in Windows 7 32bits even with Administrator privileges
Why don't you add your code to the question? It'll make life easy for the people who are interested in helping you. If you get different PIDs, most probably there's something wrong with your code! (I'm just guessing without seeing what you have tried.)
Have a look at these questions as well.
1) Getting PID of process started by Process.start()
2) Programmatically kill a process in vista/windows 7 in C#
3) Process.kill() denied in Windows 7 32bits even with Administrator privileges
Adding the code makes it much easier to understand what the problem is and here's your problem.
IE creates more than one process for one instance of the program. (more details about it) That's why you get different PIDs (for the different processes).
What your code does is killing only one process of it (by the usage of if condition in the Stop() method!). So the remaining process may generate InvalidOperationException when you try to execute Start() again(starting the same process)!
So what your code should do is kill all the active iexplore processes. This can be done by simply removing the if condition of Stop() method.
foreach(Process p in Process.GetProcessesByName("iexplore"))
{
p.Kill();
}
Let me know whether this worked.
I have a similar issue, only I dont want to kill the IE process that I started, I want to bring it into focus.
I have one app that starts 5 IE windows.(not tabs, but unique windows)
I store the PIDs that I start each of the IE windows with.
At particular times, I want to be able to:
select a PID,
find the IE window related to that PID
bring it into focus (minimizing the others)
This worked using XP and IE6 (required for the environment)
Now when I am using Win 7 and IE 8, the PID that I stored is not found,
and thus I no longer have the ability to change the window in focus.
I have the following lines of code:
Process aProcess = Process.Start("ieexplorer", aDummyHTMLFilePath);
//I do nothing in between
aProcess.Kill();
This runs smooth if there are NO other IE windows open.
But if there is a window open, I get a System.InvalidOperationException on aProcess.Kill(); saying :
Cannot process request because the process has exited.
Also, I notice that in this case, aProcess.HasExited is true right after line 1 in the code above.
How can I smoothly close IE, even if there are other IE windows open?
When you start a new instance of Internet Explorer like you do it will try to see if Internet Explorer is already running. If that is true the URL is opened in the already running instance and the new instance exits immediately. This means that when you try to kill the process you started it has already exited voluntarily. However, you will see a new browser window or tab on your screen but that is being hosted by the existing Internet Explorer process.
I didnt get the same issues as you
I found that the following worked if the process was still running or not
Process p = Process.Start("notepad.exe", "");
Thread.Sleep(5000);
if (!p.HasExited) p.Kill();
It only complained IF the window had been closed. Hence the check
i have a strange problem with IE8 installed in xp. i was trying to launch IE using an System.Diagnostics.Process.Start method in c#. And i have a requirement to trap the exited event of the IE and do some operation. But i ended up in a rather strange problem where the IE immediately fires the exited event after launch.
this is the sample code
Process objProcess = Process.Start("IEXPLORE.EXE", "http://google.com");
if (objProcess != null)
{
objProcess.EnableRaisingEvents = true;
objProcess.Exited += new EventHandler(myProcess_Exited);
}
public static void myProcess_Exited(object sender, System.EventArgs e)
{
MessageBox.Show("You exited");
}
But the above code perfectly works when laucnching different process (ex:notepad) and it fires the exit event when i close the exe.
this only gives problem launching IE 8. Can someone clarify me what is the problem??
UPDATE
Most friends replied my post and saying why you can't just use an URL? why stick with IE?
here the reason
the ultimate aim of the app is to launch an URL from the windows application and will hide an exe when working on the IE. And show the exe after closing the IE.
Thanks
Most probably is that you have IE already running as a process, so when you try to launch it again as a new process it looks that there are IE running already, tells it that user initiated a new window (so the initial IE will create a "new" window rather than a new one) and exit.
Possible solution:
try starting the process with "-nomerge" command line option:
Process objProcess = Process.Start("IEXPLORE.EXE", "-nomerge http://google.com/");
Interesting observation: objProcess.ExitCode (for IE8 at least) will be equal to 0 if exited passing control to another instance, and 1 if it was actually closed by user.
If another instance of iexplore.exe is already running on the machine, new instances will connect to that and immediately exit. Also, it's possible that even in the case where iexplore is not running, the multiprocess architecture of Internet Explorer 8 has the parent launch child broker process and exit immediately.
But these answers are besides the point. You should not be launching Internet Explorer directly. If the user has configured another default browser, they will be unhappy that you are ignoring their preferences. Instead, why don't you try
System.Diagnostics.Process.Start("http://google.com");
directly and that will do the right thing. You won't be able to tell when the browser closed, but if the command has opened a new tab in an existing browser session for example, the browser close event will be meaningless to your application.
Maybe IEXPLORE itself launches a different process for the URL and ends the process you created? Like a fork on Unix?