我有一个progaram,既可以作为winform运行,也可以从命令行运行.如果从命令行调用它,我调用AttachConsole(-1)以附加到父控制台.
但是,在我的程序结束后,用户必须按Enter键才能返回标准命令提示符("c:\>").有没有办法避免这种需要?
谢谢.我可以将它包装在一个cmd文件中,以避免这个问题,但我想从我的exe中做到这一点.
小智 18
尝试在exe退出之前添加此行...
System.Windows.Forms.SendKeys.SendWait( "{} ENTER");
有点黑客,但是当我遇到这个问题时我能找到最好的.
抢
小智 8
这是解决 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());
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Rob L 的方法有点危险,因为它会向活动窗口发送 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;
}
Run Code Online (Sandbox Code Playgroud)
--剪断--
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);
}
Run Code Online (Sandbox Code Playgroud)
此解决方案基于此处找到的代码:
http://www.jankowskimichal.pl/en/2011/12/wpf-hybrid-application-with-parameters/
| 归档时间: |
|
| 查看次数: |
5865 次 |
| 最近记录: |