使用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函数。
- TripleDES:指定密钥是’TripleDES’的已知弱密钥,无法使用
- ASMX webservice不返回JSON,只能使用application / x-www-form-urlencoded contentType进行POST
- 如何在ASP.NET 5 MVC中没有模型的情况下从查询中访问数据
- entity framework代码First MaxLength和FixedLegth(char vs varchar)
- 托管代码中是否可能存在内存泄漏? (特别是C#3.0)
- SQLBulkCopy的任何方式“插入或更新,如果存在”?
- 在Singleton上使用Dispose来清理资源
- 从xsd模式文件生成类时出错
- 如何在Windows Mobile上设置网络管理设置或使对话框显示在C#中?