If I run this command:
C:\WINDOWS\explorer.exe "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\::{2227A280-3AEA-1069-A2DE-08002B30309D}"
from the Windows shell (via Windows+R), my printer and faxes open in a new explorer.exe process. (So I have 2 running explorer.exe processes.)
If i execute:
Process.Start(#"C:\WINDOWS\explorer.exe", #"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\" +
#"::{21EC2020-3AEA-1069-A2DD-08002B30309D}\" +
#"::{2227A280-3AEA-1069-A2DE-08002B30309D}");
from a C# program, my printer and faxes open too, but as an child process of the main explorer.exe process (the one running the Windows shell, including the taskbar, etc.).
What can I do to start a second explorer.exe process with the printer and faxes window from C#?
Initial thoughts - check your "Launch folder windows in a separate process" in Folder Options (Organize -> Folder & Search Options -> View tab). This is unchecked by default, hence "Check" this and try your C# code again.
I know this setting affects the ShellExecute function but I am not sure if .NET's Diagnostic namespace uses the same route.
ShellExecute(handle, "explore", , NULL, NULL, SW_SHOWNORMAL);
Second thoughts - a similar issue has been already discussed in stackoverflow and this post might give you some idea.
Start new process, without being a child of the spawning process
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 have a custom application running as a the shell (Windows 10 Enterprise) for a particular user - i.e. the user boots straight into this application.
However, I want to be able to provide access to the WiFi settings form. I have read that the way to do this is something like
Process.Start("ms-settings:network-wifi");
or
Process.Start("ms-availablenetworks:");
However, as far as I can tell, that relies on explorer running as the shell.
I've tried...
Process proc = new Process();
proc.StartInfo.FileName = #"c:\windows\explorer.exe";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.Arguments = "ms-availablenetworks:";
proc.Start();
All of the above work fine if I run in a normal environment, i.e. with explorer as the shell.
But for this user (with my custom shell application), I get an instance of explorer.exe running and displaying an error, Class not registered
I have also come across using LaunchUriAsync() but I don't think that would help me here, besides it's only available for Windows Store applications for what I've read, which this is not.
Well I managed to get this working
First start explorer on its own, then a second Process.Start() to run the settings page.
Unfortunately, when explorer.exe runs, it displays the taskbar which I don't want. (I had previously assumed I'd be able to hide it with a group policy setting or something but this doesn't appear to be the case).
But I suppose that's another question...
I have a strange behaviour when I try to start explorer.exe from c# like this:
ProcessStartInfo info = new ProcessStartInfo("explorer.exe", "E:");
info.WindowStyle = ProcessWindowStyle.Hidden;
Process process = new Process();
process.StartInfo = info;
process.Start();
Thread.Sleep(2000);
bool res = process.CloseMainWindow(); // InvalidOperationException -> already exited
process.Close();
process.WaitForExit(5000);
The problem is:
the exception seems correct, because at this point HasExited returns already true. Nevertheless in the taskmanager the created instance of explorer is still present.
So I dont understand what my call does. I had thought it would directly start an instance of explorer, but it seems not or the explorer works in some different way.
And my second question: how can I start and shortly after that stop a new specific instance of explorer programmatically?
Edit
to answer some questions:
explorer option Launch Folder Windows in a separate process is set to true
the created process.Id is not present in taskmanager. For example: the new explorer instance shown in taskmanager has PID 4968 while the debugger shows 10752 as ID of the created (and exited) process.
Edit: here a screenshot from taskmanager after ~12 debug runs
This may be down to the fact that the explorer.exe process in question HAS exited. Windows does some strange things with multiple explorer windows and it depends on the options you have set. By default, all windows end up running in a single process if I remember correctly.
What I would do is output the processid for the process you just generated:
Console.WriteLine($"{process.Id} has exited {process.HasExited}");
Then look at task manager to see if you can find the corresponding process. I would imagine that the HasExited is true so you won't find the process, but the window will have opened.
You may have to set process.EnableRaisingEvents to true to get a valid answer from process.HasExited, I can't recall of the top of my head.
Also check the setting in Explorer via Folder Options to see if you have Launch Folder Windows in a separate process enabled or not on the view tab.
IF you do find your process, you can always kill off that process and see if your windows closes. If it does, then it may be that the explorer.exe is not creating a main window handle which you can check using Spy++
Edited with more info
Further more, #Hans Passant mentioned above that shell windows work different. So what actually happens is this, explorer.exe (1234) contacts the root explorer.exe (321), which in turn then creates a new window (if Launch separate is false) or spawns a subprocess explorer.exe (3445). Your process explorer.exe (1234) having done its job, then exits. No window is ever created by your process so CloseMainWindow() will not find a window to close and errors.
How to close a specific explorer window
To do so you need to utilise ShellWindows, see Is there a way to close a particular instance of explorer with C#?
For reference the code used there was:
ShellWindows _shellWindows = new SHDocVw.ShellWindows();
string processType;
foreach (InternetExplorer ie in _shellWindows)
{
//this parses the name of the process
processType = Path.GetFileNameWithoutExtension(ie.FullName).ToLower();
//this could also be used for IE windows with processType of "iexplore"
if (processType.Equals("explorer") && ie.LocationURL.Contains(#"C:/Users/Bob"))
{
ie.Quit();
}
}
Note, you need to be careful that you aren't closing a window the user wanted open in the first place. Is there a reason to close the window?
The problem is in the notion of has UI Interface, As per definition:
Closes a process that has a user interface by sending a close message
to its main window.
However explorer.exe is far more complicated than a simple process with UI.
If for example you use another, application, more simple (e.g Notepad), no exception will be raised:
ProcessStartInfo info = new ProcessStartInfo("notepad.exe");
info.WindowStyle = ProcessWindowStyle.Maximized;
Process process = new Process();
process.StartInfo = info;
process.Start();
Thread.Sleep(2000);
bool res = process.CloseMainWindow(); // InvalidOperationException -> already exited
process.Close();
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'd like to be able to start a ClickOnce application from another executable. I know how to do this with the browser using Process.Start("http://PathToMyApp"). However, this is returning null for the Process. Therefore, I cannot check to ensure that the process has started or kill the process later.
How can I launch a click once application and get its Process Id and determine whether or not it launched successfully?
You have to find the shortcut for the ClickOnce application and do a process.start on that. Here's an example:
string shortcutName =
string.Concat(Environment.GetFolderPath(Environment.SpecialFolder.Programs),
"\\", PublisherName, "\\", ProductName, ".appref-ms");
process.Start(shortcutName);
where PublisherName and ProductName are those filled in on the Options dialog in the Publish tab for the application you want to start.
You can also pass arguments to a ClickOnce application if you start it this way, even if it's offline. Here is an article telling how to do that just in case you need that functionality as well.