tags:

views:

295

answers:

3

I have a C# application that uses the SendMessage pinvoke method to send a "close window" message (WM_CLOSE / 16) to various windows outside the application. This works great, except when the window in question is a Windows Explorer window. I do not get an exception, but the window does not close.

Here's the signature:

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
    internal static extern IntPtr SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

Is there a different message that I need to send to Windows Explorer windows? Or an alternate way to accomplish this?

A: 

It may be a security feature. There used to be many viruses that would WM_CLOSE Windows Explorer to prevent you from exploring and deleting the virus files. My guess is that you can't pinvoke close Task Manager anymore either, although that's just a guess.

Robert Harvey
A: 

One way to close explorer is to find the explorer.exe process via Process.GetProcesses(), then calling Kill() on the process. However, I suspect Windows has some built-in mechanism to restart explorer if it is killed.

A better question might be, why do you need to close explorer?

Judah Himango
If you end-task the last instance of Explorer, Windows will usually restart it, but not always (at least on my Windows XP machine).
Robert Harvey
Interesting idea, but I'd like to avoid that. The app is a task switcher that gives the user the option to close the application instead of switching to it, so I want the close operation to be safe.
James Sulak
+1  A: 

an alternative solution would be to use PostMessage win API call instead of SendMessage, below is an example which worked fine for me (I'm using winXP sp3):

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.Dll")]
public static extern int PostMessage(IntPtr hWnd, UInt32 msg, int wParam, int lParam);

private const UInt32 WM_CLOSE          = 0x0010;

...

    IntPtr hWnd = FindWindow("ExploreWClass", null);
    if (hWnd.ToInt32()!=0) PostMessage(hWnd, WM_CLOSE, 0, 0);

differences between PostMessage and SendMessage api call are described here: http://msdn.microsoft.com/en-us/magazine/cc301431.aspx

serge_gubenko
Thanks, this works perfectly. Informative link, too.
James Sulak