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.
Related
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.
I'm new to c#. Antivirus deleted the mySolutionName.exe file out of the /debug directory and now I cannot execute my code. I'm concerned that anything I do may make the issue worse.
When I press F5 I get an error of:
CS2012 C# Cannot open for writing --> C:\Users\me\source\repos\MyApp\MyApp\obj\Debug\MyApp.exe''
Can someone please tell me how to rebuild the file so that I can continue developing?
after your edit:
Your program is probably still running outside of the debugger.
You need to use the task-manageer to kill all instances of MyApp.exe if this doesnt solve your issue a reboot should do the trick as well
So why is this happening?
Most liky your application is somewhere stuck on a blocking function or in a never ending loop. maybe there is even a seperate thread still operating that you forgot to close. We lack some information to tell yout that for sure. But to find out what is happening you can close your window while running in debugger mode and see if the application properly closes. if it doesnt you can hit pause and see where the program is stuck and resolve this issue by ending the task/loop/whatever in your OnClosing function of your window.
A good way to solve this issue is looking which process currently accesses the file.
A tool to do that is Microsoft SysInternals Process Explorer. It has a feature called "Find handle or DLL ..." which can be accessed by Ctrl+F.
The result will show the process which accesses the file. You can then judge whether it's Antivirus or something else that prevents you from writing to the file. If possible, you can then take an action in that program to release the file.
Example: a program is accessing my powerpoint presentation, which has the term "Schulungen" in its file name.
Process Explorer figures out: it's open in Powerpoint.exe, so I can simply close the file in Powerpoint - problem fixed.
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.
I'm developing a program in c# im stuck with this issue.
I want to show dialog box which refers to a particular directory.
I know that there is OpenDialogFolder and SaveDialog, but I don't want to save or open any files what I want is just to open a specific directory dialog box.
Like this screenshot:
It looks like you just want to open a copy of Windows Explorer. You can do that by simply calling Process.Start() and specifying just a folder path with no filename:
Process.Start(#"C:\Temp\");
The default behavior of the Windows shell, given a command like this on the command line (or a shortcut or a Run command) is to open Windows Explorer to show the contents of the specified path.
Now, Windows Explorer is an external process, which you are launching and then letting it do its thing. It therefore won't behave exactly like a modal dialog box, like preventing the dialog losing focus to another window. However, you can mimic the "can't do anything else with the application" behavior of a dialog by assigning the result of Process.Start (a Process) to a variable, then calling the WaitForExit() method on that Process with no parameters. This will block the application's main thread until the user closes the Explorer window you opened. It's not perfect; by blocking the thread, the application will not respond to any requests to draw itself or do any other basic things that even a dialog-interrupted window will still do, and you can still technically "activate" the window you used to launch Windows Explorer which will bring it in front of Windows Explorer. The Explorer window can also be minimized (something dialogs don't normally allow) and there isn't much you can do to prevent that.
i am trying to write a program that close explorer then runs another program.
i am getting a problem when trying to close explorer using the following code:
foreach (Process p in Process.GetProcesses())
if (p.MainModule.ModuleName.Contains("explorer"))
p.Kill();
can somebody please let me know why it is doing this and provide a solution
CHEERS
p.s. this is not a malicous program, it is going to run a game that doesn't work properly when explorer is in the background
The problem is that you can have multiple versions of Explorer running at any one point in time... and you usually need at least one of them. The shell that hosts the Start Menu is actually an instance of Explorer. So if you close all instances of Explorer, you'll also be shutting down the main shell, which is not what you want to do.
However, the fastest way to do get all instances of Explorer and kill them is:
foreach (Process p in Process.GetProcessesByName("explorer"))
{
p.Kill();
}
There is a simple undocumented way to exit explorer cleanly, see also question Gracefully Exit Explorer (Programmatically). It is intended for developers working on shell extensions.
The procedure is different for Windows XP and Windows 7:
Windows XP:
Open the shutdown dialog (Start > Shutdown), then cancel the dialog pressing CTRL-SHIFT-ALT-ESC (or hold down CTRL-SHIFT-ALT and press the Button with the mouse).
Windows 7:
Open the Start menu and then hold CTRL-SHIFT while right-klicking into the empty area of the start menu, see screenshot. A context menu appears, where the second entry is 'Exit Explorer' (without CTRL-SHIFT the context menu has only one entry)
p.s. this is not a malicous program, it is going to run a game that doesn't work properly when explorer is in the background
Explorer is a critical Windows component. You should debug why you have problems when Explorer is running, and fix those.
Killing Explorer will cause severe problems for your users.