简体   繁体   English

C#从另一个进程关闭子窗口

[英]C# Close child window from another process

I'm writing an application that latches on to another, which I don't have the source code for, but there's a certain thing that makes it display a .NET Framework exception message. 我正在编写一个可以锁定到另一个应用程序的应用程序,我没有该应用程序的源代码,但是有某些事情可以使它显示.NET Framework异常消息。

I can detect with my code when it will open, and I want to get its handle and close it. 我可以用我的代码检测它何时打开,并且我想获取它的句柄并关闭它。 Sometimes this child window takes the title from the main window, so I can't rely on that to find its handle. 有时,此子窗口从主窗口获取标题,因此我不能依靠它来找到其句柄。

An image of the child window in question: 相关子窗口的图片:

图片

Ok, I solved it. 好的,我解决了。 It turns out that the GetForegroundWindow() was returning the correct handle, however, since sometimes the exception window takes the title from the parent I was getting tripped up. 事实证明,GetForegroundWindow()返回的是正确的句柄,但是,因为有时异常窗口会从父级获取标题,所以我被绊倒了。

The solution is to wait until the number of windows changes using EnumWindows, then get the handle of the foreground window and close it. 解决方案是等到使用EnumWindows更改窗口数后,再获取前景窗口的句柄并关闭它。

new Thread(() =>
{
    int pid = Program.GetHelperProcess().Id;
    int lastCount = -1;
    while (true)
    {
        int newCount = WinUtil.GetWindowCount(pid);
        if (lastCount != -1 && lastCount != newCount)
        {
            break;
        }
        lastCount = newCount;
        Thread.Sleep(30);
    }
    WinUtil.CloseWindow(WinUtil.GetForegroundWindow());
}).Start();

WinUtil.cs WinUtil.cs

class WinUtil
{
    [DllImport("user32.dll")]
    public static extern IntPtr GetForegroundWindow();

    private delegate bool EnumWindowsProc(IntPtr hWnd, int lParam);

    [DllImport("user32.dll", SetLastError = true)]
    private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

    [DllImport("user32.dll")]
    private static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam);

    [DllImport("user32.dll")]
    private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

    [DllImport("user32.dll")]
    private static extern int GetWindowTextLength(IntPtr hWnd);

    [DllImport("user32.dll")]
    private static extern bool IsWindowVisible(IntPtr hWnd);

    [DllImport("user32.dll")]
    private static extern IntPtr GetShellWindow();

    public static int GetWindowCount(int processId)
    {
        IntPtr hShellWindow = GetShellWindow();
        int count = 0;
        EnumWindows(delegate (IntPtr hWnd, int lParam)
        {
            if (hWnd == hShellWindow) return true;
            if (!IsWindowVisible(hWnd)) return true;

            int length = GetWindowTextLength(hWnd);
            if (length == 0) return true;

            uint windowPid;
            GetWindowThreadProcessId(hWnd, out windowPid);
            if (windowPid != processId) return true;

            count++;
            return true;
        }, 0);
        return count;
    }

    public static string GetWindowTitle(IntPtr hWnd)
    {
        int textLength = GetWindowTextLength(hWnd);
        StringBuilder outText = new StringBuilder(textLength + 1);
        int a = GetWindowText(hWnd, outText, outText.Capacity);
        return outText.ToString();
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

    private const UInt32 WM_CLOSE = 0x0010;

    public static void CloseWindow(IntPtr hwnd)
    {
        SendMessage(hwnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM