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.
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?
when I run the following code, I expect to get the name of all processes running in the system, but in some other PCs than mine, there is a running process that is visible in the TaskManager but my app doesn't show it, I wanna know if I'm doing something wrong or there is any way to solve this, BTW my app is running as Administrator so that's not the problem. Thanks for your help.
foreach(Process Proc in Process.GetProcesses()) {
T += Proc.ProcessName + ", ";
}
Multiple OS services can be loaded within the same instance of the Service Host process (svchost.exe). GetProcesses does not identify those individual services; for that, use GetServices. Be sure to read the official docs.
Process.GetProcesses() does not return system processes. Services may also appear as svhost.exe.
For some reason, my C# program needs to restart with elevated privileges. I use the following code to achieve it:
private static void RestartForPermissionsFix()
{
ProcessStartInfo processInfo = new ProcessStartInfo();
processInfo.Verb = "runas";
processInfo.FileName = Assembly.GetExecutingAssembly().Location;
Process.Start(processInfo);
}
This works great.
After I "fix my privileges", I want to restart the program unelevated. I tried the same as above without the "runas", but it does not work. I assume the process being started from an elevated process automatically gets elevated. Any idea?
In order to launch a process at medium integrity from a high integrity process, I believe you would have to get the current process token using OpenProcessToken, duplicate it, remove the high integrity SID from the token using SetTokenInformation, and then use that token to create the new process using CreateProcessAsUser. This would be similar to this example, except rather than add the low integrity SID you'd have to remove the high integrity one. Note: I haven't tested this, so I'm not 100% sure it would work.
I suggest you leave the original unelevated process running, and have it wait for its elevated counterpart to finish (e.g. using Process.WaitForExit). Once that finishes, it can continue unelevated as before. This would be a lot easier and more foolproof.
I had the same problem with an application that I wanted to update automatically (The update program requires elevated privileges).
What I did was creating an external .exe that would start my updater program with elevated privileges, wait for it to exit, then restart my application with normal privileges.
I then embedded this .exe in my main application, and start this .exe just before leaving my application when I update it.
I am writing a program (Visual Studio 2010 in C# Windows Forms) which keeps track of multiple instances of the Remote Desktop Client (mstsc.exe - tested with Windows 7 version). I have been attempting to launch this program and grab its PID with the following code:
Process mstsc = Process.Start(mstscLocation, mstscConString);
int mstscProcessId = mstsc.Id;
DataRow row = openConn.NewRow();
row["RDP ID"] = mstscID;
openConn.Rows.Add(row);
This starts the client and returns an ID as it should. Problem is, if I try to terminate the PID with the following code, it fails to do so:
int rdpID = Convert.ToInt32(dgvOpenConnections.Rows[selectedIndex].Cells["RDP ID"].Value.ToString());
try
{
// kill off mstsc
Process mstsc = Process.GetProcessById(rdpID);
mstsc.Kill();
}
I have verified that the PID that is recorded from Process.Start is the same as is retrieved from the DataGridView (dgvOpenConnections) and placed into rpdID (try fails and hits catch as the original PID no longer exists). Furthermore, I have issued a "tasklist" at a command prompt after starting one instance of MSTSC.EXE and can verify that it changes PIDs (in this test, C# recorded 4288 but tasklist shows it running as 8172).
I cannot kill all MSTSC processes as I am trying to control more than one. Is there a way to trace down the second PID MSTSC appears to use? My guess is it either starts a second process and gets rid of the first or maybe this is a child process (although the PID that is return no longer exists after start).
How in C# can I ensure I have the right process ID to later monitor or kill a specific instance of the Remote Desktop Client?
This happens if you try to run mstsc from a 32-bit application in 64-bit Windows.
(Source: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/22c10140-a502-4aa1-98d3-3607b8b573e8/)
There are two versions of mstsc on a 64-bit Windows:
c:\windows\system32\mstsc.exe is a 64-bit version
c:\windows\syswow64\mstsc.exe is more or less a "redirect" that will open c:\windows\system32\mstsc.exe from a different process than your application.
I've had the same issue. My application started mstsc, the process immediately exited, and mstsc reappeared with a different parent process and different PID.
This happens because 64-bit Windows uses file system redirection to redirect calls to the 64-bit c:\windows\system32 executables to c:\windows\syswow64.
There are two solutions:
Recompile your application to 64-bit. Then your application will also use the 64-bit mstsc.
Disable file system redirection (see http://blog.tonycamilli.com/2005/07/disabling-wow64-file-system.html) and access the 64-bit mstsc from your 32-bit application.
I have only tried recompiling, and it worked. :-)
Edit:
If you don't want your users to use the right version (we're using ClickOnce deployment, so we'd rather send one link to everybody), here's a workaround:
If you're using an .RDP file for mstsc, just add a unique token to your file name. mstsc will be started with a command line like mstsc host_user_token.rdp.
Now, after you called Process.Start, do Process.WaitForExit with a short timeout (5s). If the process did not exit, you have the right object.
If the process did exit, do a little polling loop (100ms interval, 5s timeout) that checks for processes with your token:
var timeout = AppSettings.GetIntValue(
Constants.SettingsKeyProcessFinderTimeout, Constants.ProcessFinderTimeoutDefault);
int elapsedTime = 0;
Process process = null;
while (elapsedTime <= timeout)
{
process =
Process.GetProcessesByName("mstsc").FirstOrDefault(p => p.StartInfo.Arguments.Contains(guid));
Logger.TraceVerbose(
string.Format(
"Elapsed time: {0}; Found process with PID {1}", elapsedTime, process == null ? -1 : process.Id));
if (process != null)
{
break;
}
Thread.Sleep(SleepInterval);
elapsedTime += SleepInterval;
}
After that loop, if you still have process == null, there was some error (process was not found or never executed at all). If you have a Process reference, that's the "new" mstsc process.
I tried your example using Process Explorer, and I couldn't see a second or child process being created. From beginning to end the Remote Desktop Process was one and the same, and after being created I was able to kill the process using the same PID I saw in the beginning.
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?