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