2
votes

I am trying to destroy a child window created by a third party application. I tried to use WinApi to make this happen but it seems that DestroyWindow(hwnd) doesn't do the trick. I indeed get a handle to work with but nothing happens, the child window remains. I tried to use CloseWindow(hwnd) just to verify the child window can be modified and yes, CloseWindow(hwnd) minimizes the Child Window but I want to close it.

This is my Code:

[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool DestroyWindow(IntPtr hwnd);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CloseWindow(IntPtr hWnd);

private static void CloseChildWindow();
{
  IntPtr _hwnd = IntPtr.Zero;

  if (WindowController.FindWindow(null, "System Alert") != IntPtr.Zero)
  {
    _hwnd = WindowController.FindWindow(null, "System Alert");
    DestroyWindow(_hwnd); //Returns error code 5: Access Denied
    CloseWindow(_hwnd); //Minimizes the window therefore _hwnd is correct
  }
}

Any ideas on what is happening or a workaround would be appreciated, thanks in advance.

EDIT1: Destroywindow returns code error 5: Access Denied. Any ideas on a workaround?

1
Have you checked if your DestroyWindow call returns an error code?Brandon
Error code returned Error Code 5: Access denied, looks like I can't destroy it for that reason, will update question.Omega_
That could be (and IIRC: is) because your calling application is not the application responsible for the creation of the window. You might need to get some sort of context/permission to do it. I'm not sure of the steps requiredBrandon
And actually, if you look at the Remarks section of DestroyWindow on the MSDN doc: "A thread cannot use DestroyWindow to destroy a window created by a different thread."Brandon
To close it p/invoke PostMessage + WM_CLOSE (or use UI Automation)Alex K.

1 Answers

1
votes

The documentation for the win32 API DestroyWindow is pretty clear:

A thread cannot use DestroyWindow to destroy a window created by a different thread.

You may be able to inject a DLL in the third party application, hooking the correct thread and then issuing the DestroyWindow call from here, but I will not recommand that, as it may have weird side effects (read: crash). Some applications don't react well when their windows are destroyed under their feet.

The proper way is probably to fake an user interaction, using regular Windows message (as WM_CLOSE), or SendInput, or UI Automation.

If the user has no way to close that window, you are out of luck.