【问题标题】:C# Close child window from another processC#从另一个进程关闭子窗口
【发布时间】:2018-05-10 02:08:28
【问题描述】:

我正在编写一个锁存到另一个应用程序的应用程序,我没有源代码,但有某种原因使它显示了 .NET Framework 异常消息。

我可以用我的代码检测它何时打开,我想获取它的句柄并关闭它。有时这个子窗口会从主窗口获取标题,所以我不能依赖它来找到它的句柄。

相关子窗口的图像:

【问题讨论】:

  • 首先,问题描述得不好,但是,如果我正确理解您的问题,您想关闭另一个应用程序的子窗口,对吗?然后在谷歌上快速搜索C# SendKeys(我可以看到你已经尝试过了,但你需要做更多的研究).. 用你尝试过的代码回到我们这里......我不喜欢这样你很幸运:)
  • @zackraiyan 刚刚编辑了问题,希望现在更清楚了。还添加了一些代码。虽然这不是我尝试过的全部。
  • 我想知道未处理的异常对话框是否真的是一个“子窗口”,或者只是框架弹出的东西。这可能会使事情复杂化。
  • @stuartd 我在窗口上使用了Spy++,它看起来就像一个普通的 Windows Froms 对话框。
  • @stuartd 根据我自动化 .NET 应用程序的经验,会弹出一些窗口,但不会作为子窗口弹出。如果我没记错的话,这样的错误窗口可能不是表单的子窗口。

标签: c# .net wpf


【解决方案1】:

好的,我解决了。事实证明,GetForegroundWindow() 返回了正确的句柄,但是,因为有时异常窗口会从我被绊倒的父级获取标题。

解决方法是使用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

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);
    }
}

【讨论】:

    猜你喜欢
    • 2015-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-24
    • 1970-01-01
    • 2017-02-21
    相关资源
    最近更新 更多