C# 如何从工作线程调用windows PostMessage函数而不挂起控制台应用程序?

C# 如何从工作线程调用windows PostMessage函数而不挂起控制台应用程序?,c#,multithreading,visual-studio,pinvoke,C#,Multithreading,Visual Studio,Pinvoke,在代码中重新创建问题: class Program { private const int VK_ESCAPE = 0x1B; private const int WM_KEYDOWN = 0x0100; [DllImport("User32.dll")] private static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam); static void

在代码中重新创建问题:

class Program
{
    private const int VK_ESCAPE = 0x1B;
    private const int WM_KEYDOWN = 0x0100;

    [DllImport("User32.dll")]
    private static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

    static void Main(string[] args)
    {
        Task.Run(() =>
        {
            var hWnd = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
            bool hasSucceeded = PostMessage(hWnd, WM_KEYDOWN, VK_ESCAPE, 0);
            return;
        });

        Console.WriteLine("PostMessage works as expected in Debug >> Start Debugging mode.");
        if ((Console.ReadKey()).Key == ConsoleKey.Escape)
        return;
    }
}
我试图通过从工作线程调用
PostMessage
来取消
Console.ReadKey()
。当我在调试>>启动调试模式下运行代码时,这会起作用


但是,当我在Debug>>Start而不调试模式下运行代码时,它会挂起吗?非常感谢您的回复/解决方案

陈雷蒙写了一篇很好的博客文章,标题是。在继续您的方法之前,您可能需要回顾一下这一点

话虽如此,直接的问题可能是您必须使用函数(来自Kernel32.dll)来获取自己控制台窗口的句柄。因为,正如其他人已经评论的那样,您的进程并不真正拥有该窗口(它属于关联的
conhost.exe
进程)

有鉴于此,以下代码有点“有效”:

但是,这种方法可能不是实现您想要的目标的正确方法(如您所述,取消
控制台.ReadKey


查看使用超时的方法。

这里可能会发生各种各样的奇怪情况。控制台应用程序实际上没有主窗口-控制台子系统创建窗口,但它们属于主窗口,而不是运行在主窗口中的应用程序。正如Damien的评论所暗示的那样,如果我打印出
hWnd
的值,那么在调试器下运行时会得到一个非零值,在没有调试器的情况下运行时会得到一个0值。感谢所有的响应。我决定使用超时机制。
class Program
{
    private const int VK_ESCAPE = 0x1B;
    private const int WM_KEYDOWN = 0x0100;

    [DllImport("User32.dll")]
    private static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

    [DllImport("kernel32.dll")]
    internal static extern IntPtr GetConsoleWindow();

    static void Main(string[] args)
    {
        Task.Run(() =>
        {
            bool hasSucceeded = PostMessage(GetConsoleWindow(), WM_KEYDOWN, VK_ESCAPE, 0);
            return;
        });

        Console.WriteLine("PostMessage works as expected in Debug >> Start Debugging mode.");
        if ((Console.ReadKey()).Key == ConsoleKey.Escape)
            return;
    }
}