简体   繁体   English

如何在不挂起控制台应用程序的情况下从工作线程调用Windows PostMessage函数?

[英]How can I call the windows PostMessage function from a worker thread without hanging the console application?

The issue recreated in code: 在代码中重新创建了该问题:

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

I'm trying to cancel Console.ReadKey() by calling PostMessage from a worker thread. 我试图通过从辅助线程调用PostMessage来取消Console.ReadKey() This works when I run the code under Debug >> Start Debugging mode. 当我在“调试” >>“开始调试”模式下运行代码时,此方法有效。

However, when I run the code under Debug >> Start Without Debugging mode it hangs? 但是,当我在Debug >> Start Without Debugging模式下运行代码时,是否挂起? Any responses/solutions are greatly appreciated. 任何答复/解决方案,我们将不胜感激。

Raymond Chen has written a nice blog post titled "You can't simulate keyboard input with PostMessage" . Raymond Chen撰写了一篇不错的博客文章,标题为“您无法使用PostMessage模拟键盘输入” You may want to review this, before continuing with your approach. 在继续您的方法之前,您可能需要检查一下。

Having that said, the immediate issue may be that you must use the GetConsoleWindow function (from Kernel32.dll) to get a handle to your own console window. 话虽如此,当前的问题可能是您必须使用GetConsoleWindow函数(来自Kernel32.dll)来获取自己的控制台窗口的句柄。 Because, as other have already commented, your process does not really own the window (it belongs to the associated conhost.exe process). 因为,正如其他人已经评论过的那样,您的进程并不真正拥有该窗口(它属于关联的conhost.exe进程)。

Given that, the following code sort of "works": 鉴于此,以下代码将“起作用”:

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

But then, this approach is probably not the right approach to achieve what you want (cancelling a Console.ReadKey , as you state). 但是,这种方法可能不是实现所需目标的正确方法(如您声明的那样取消Console.ReadKey )。

See this for a way to use a timeout instead. 请参阅以获取使用超时的方法。

暂无
暂无

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

相关问题 如何删除单独的工作线程 function 并创建一个线程 - How can I remove seperate worker thread function and create a thread 我可以在混合控制台和 WinForms 环境中保持工作程序和 GUI 分离而没有跨线程异常吗? - Can I keep worker and GUI separate without cross thread exceptions in mixed Console and WinForms environment? 我可以在userControl中使用线程来防止应用程序运行时挂起吗? - Can I use thread in userControl to prevent hanging while application is running? 如何防止或恢复工作线程上的堆栈溢出? - How can I prevent or recover from a stack overflow on a worker thread? 我该如何处理容易导致当前线程挂起的呼叫 - How do I handle a call which is prone to hanging the current thread 如何从控制台应用程序调用正在运行的Winform应用程序的功能 - How to call a function of a running winform application from console application 如何从Windows Phone的工作线程中的UI线程获取值? - How to get values from UI Thread in a worker thread in Windows Phone? 线程池-如何从工作线程中调用主线程中的方法(带有参数) - Threadpool - How to call a method (with params) in the main thread from a worker thread 按下键后,如何使控制台应用程序调用函数? - How can I make my console application call a function when a key is pressed? 我可以通过Worker线程在静态类实例上调用静态方法吗? - Can I call static methods on a static class instance from a Worker thread?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM