使用AttachConsole,用户必须按Enter键才能获得常规命令行

我有一个progaram,既可以作为winform运行,也可以从命令行运行。 如果从命令行调用它,我调用AttachConsole(-1)来附加到父控制台。

但是,在我的程序结束后,用户必须按Enter键才能返回标准命令提示符(“c:\>”)。 有没有办法避免这种需要?

谢谢。 我可以将它包装在一个cmd文件中,以避免这个问题,但我想从我的exe中做到这一点。

尝试在exe退出之前添加此行…

System.Windows.Forms.SendKeys.SendWait( “{} ENTER”);

有点破解,但是当我遇到这个问题时我能找到最好的东西。

Rob L’s的方法有点危险,因为它会将Enter发送到活动窗口。 更好的方法是实际将Enter发送到正确的进程(控制台)。

这是怎么回事

internal static class NativeMethods { [DllImport("kernel32.dll", SetLastError = true)] internal static extern bool AllocConsole(); [DllImport("kernel32.dll", SetLastError = true)] internal static extern bool FreeConsole(); [DllImport("kernel32", SetLastError = true)] internal static extern bool AttachConsole(int dwProcessId); [DllImport("user32.dll")] internal static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll", SetLastError = true)] internal static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId); [DllImport("User32.Dll", EntryPoint = "PostMessageA")] internal static extern bool PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam); internal const int VK_RETURN = 0x0D; internal const int WM_KEYDOWN = 0x100; } 

–snip–

  bool attached = false; // Get uppermost window process IntPtr ptr = NativeMethods.GetForegroundWindow(); int u; NativeMethods.GetWindowThreadProcessId(ptr, out u); Process process = Process.GetProcessById(u); if (string.Compare(process.ProcessName, "cmd", StringComparison.InvariantCultureIgnoreCase) == 0) { // attach to the current active console NativeMethods.AttachConsole(process.Id); attached = true; } else { // create new console NativeMethods.AllocConsole(); } Console.Write("your output"); NativeMethods.FreeConsole(); if (attached) { var hWnd = process.MainWindowHandle; NativeMethods.PostMessage(hWnd, NativeMethods.WM_KEYDOWN, NativeMethods.VK_RETURN, 0); } 

此解决方案基于以下代码构建:

http://www.jankowskimichal.pl/en/2011/12/wpf-hybrid-application-with-parameters/

好的,我没有解决方案,但似乎是因为cmd.exe没有等待启动的进程,而对于正常的控制台应用程序,cmd.exe会等待应用程序退出。 我不知道是什么让cmd.exe决定等待或不在应用程序上,正常的Windows窗体应用程序刚刚启动,cmd.exe不等待它退出。 也许这个暗示触发了某人! 我会在平均时刻深入挖掘。

Wout的

无论控制台窗口是在前台,后台还是最小化,这是解决Enter键问题的最安全的hack。 您甚至可以在多个控制台窗口中运行它。

 using System; using System.Runtime.InteropServices; using System.Threading; using System.Windows.Forms; namespace WindowsAndConsoleApp { static class Program { const uint WM_CHAR = 0x0102; const int VK_ENTER = 0x0D; [DllImport("kernel32.dll")] static extern bool AttachConsole(int dwProcessId); private const int ATTACH_PARENT_PROCESS = -1; [DllImport("kernel32.dll", SetLastError = true)] static extern bool FreeConsole(); [DllImport("kernel32.dll")] static extern IntPtr GetConsoleWindow(); [DllImport("user32.dll")] static extern int SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); [STAThread] static void Main(string[] args) { if (args.Length > 0) { // Do this first. AttachConsole(ATTACH_PARENT_PROCESS); Console.Title = "Console Window - Enter Key Test"; Console.WriteLine("Getting the handle of the currently executing console window..."); IntPtr cw = GetConsoleWindow(); Console.WriteLine($"Console handle: {cw.ToInt32()}"); Console.WriteLine("\nPut some windows in from of this one..."); Thread.Sleep(5000); Console.WriteLine("Take your time..."); Thread.Sleep(5000); Console.WriteLine("Sending the Enter key now..."); // Send the Enter key to the console window no matter where it is. SendMessage(cw, WM_CHAR, (IntPtr)VK_ENTER, IntPtr.Zero); // Do this last. FreeConsole(); } else { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); } } } } 

在退出可执行文件之前尝试调用FreeConsole函数。