Reputation: 502
It is fairly easy to close a file explorer based on its window name, like this:
msWinHelper Class:
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string strClassName, string strWindowName);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
static uint WM_CLOSE = 0x10;
public IntPtr findWindow(string className, string name)
{
return FindWindow(className, name);
}
public void closeWindow(string className, string windowName)
{
SendMessage(findWindow(className, windowName), WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}
Main program:
msWinHelper.closeWindow(null, "WindowName");
However in some occasions this is not sufficient. Lets say I have two directories with the same subdirectories. If I open a subdir DIR1
from parent folder FOLD1
and another DIR1
from FOLD2
, window names become the same. Therefore code cannot determine which is the parent folder and would not necessarily close the one I want.
Is it possible to close an opened folder based on its full path?
Upvotes: 2
Views: 1750
Reputation: 175768
The shell has an automation interface that allows enumeration of explorer windows.
Add COM references to shell32.dll and shdocvw.dll then you can:
foreach (SHDocVw.InternetExplorer window in new SHDocVw.ShellWindows())
{
if (Path.GetFileNameWithoutExtension(window.FullName).ToLowerInvariant() == "explorer")
{
if (Uri.IsWellFormedUriString(window.LocationURL, UriKind.Absolute))
{
string location = new Uri(window.LocationURL).LocalPath;
if (string.Equals(location, @"C:\close\me", StringComparison.OrdinalIgnoreCase))
window.Quit();
}
}
Upvotes: 4
Reputation: 306
Most likely you'll need to do more than use FindWindow
because unfortunately it will always return only one of the Explorer windows (which may not be the one you're looking for).
If you want to persist with FindWindow
, one option you could do is change the Explorer setting options so that the full location path is shown in the title of the window (pretty sure from Windows 8 onwards, you can go to the View
tab and click on the Options
button to the far right to tick the Display the full path in the title bar
setting).
Once you have this option enabled, then you should be able to supply the folder path to FindWindow
for it to search for the matching window since it will have the full folder path in the title (assuming that the title bar with that folder path is unique). You may want to check that it is an Explorer window via GetWindowThreadProcessId
to get a process ID and use this PID with System.Diagnostics.Process.GetProcessById
and check "explorer" is returned in the property ProcessName
Alternatively you'll have to find the Address:
text from the control within the Explorer window itself to work out the exact folder location that the window is showing. Note: You will need to use a different call to find the other window if the address doesn't match the one you're looking for. So maybe something like this:
EnumWindows
to enumerate all top-level windows;GetWindowThreadProcessId
with each top-level window handle and with the returned process ID, use System.Diagnostics.Process.GetProcessById
and probably ProcessName
to check that it is an Explorer window;EnumChildWindows
to enumerate controls within the supplied parent window handle (strange name, but apparently all 'controls' are just 'windows' for winapi
);GetWindowText
to examine the text content for the control and check it matches the folder path you're looking for where it has Address:
as a prefix;Background on how to find about control details yourself: I usually use AutoIt's Au3Info
application to help find such information (also because I usually use AutoIt's scripting language to make a quick prototype for these kind of tasks). Use the 'Finder Tool' by dragging the circular 'aiming' icon over the target Explorer window and address control and release the mouse when you are ready to examine the information for that window/control. Here are some screenshots of what the tool shows when I run it under Windows 10 (details may differ slightly for a different version of Windows). PS: If you're not bound to C# and happy to learn AutoIt's scripting language, you could also try AutoIt for your task.
References:
Upvotes: 1