Related:
07000
07001
07002
我想构建一个控制台应用程序,这通常是从命令行运行的。
但是,当从资源管理器中双击(而不是从cmd.exe提示符运行)时,我希望该程序不显示控制台窗口。
我想避免这个:
alt text http://i36.tinypic.com/1088p5s.jpg
可能吗?
编辑我猜另一种方式来问,是否可以让程序知道如何被调用 – 无论是通过双击还是通过命令行?
我在.NET上工作,在Windows上。
编辑2:从this Old New Thing blog post我学到了一些好东西。这是我现在所知道的
在Windows中,EXE文件被标记为GUI或非GUI。使用csc.exe,这是使用/ target:winexe或/ target:exe选择的。在执行该过程的第一条指令之前,Windows内核将设置执行环境。那个时候,如果EXE被标记为GUI,那么内核将进程的stdin / stdout设置为NULL,如果非GUI(命令行),内核创建一个控制台,并将进程的stdin / stdout设置为安慰。
启动该过程时,如果没有stdin / stdout(== / target:winexe),则立即返回。所以,从cmd.exe启动一个gui应用程序,您将立即将您的cmd提示回来。如果有一个stdin / stdout,如果从cmd.exe运行,那么父cmd.exe等待进程退出。
“立即返回”很重要,因为如果您编写一个GUI应用程序来附加到其父级控制台,则可以执行console.writeline等。但是cmd.exe提示符是活动的。用户可以键入新的命令,开始一个新的进程,等等。换句话说,从winexe,只需使用AttachConsole(-1)附加到父控制台就不会将其“变成”一个控制台应用程序。
在这一点上,我认为允许应用程序使用控制台(如果从cmd.exe调用)的唯一方法,如果双击,则不使用它,是将exe定义为常规控制台exe(/ target: exe),并在启动时隐藏窗口(如果适用)。你仍然会看到一个控制台窗口短暂出现。
我还没有想到如何知道是从explorer还是cmd.exe启动,但是我越来越近了
解答
不可能构建不显示控制台窗口的控制台应用程序。
可以构建一个非常快速隐藏其窗口的控制台应用程序,但不会如此快,因为窗口不会出现。
现在,要确定是否从资源管理器启动了控制台应用程序,有些建议您查看正在运行的控制台
(mgb’s answer和KB article 99115):
int left = Console.CursorLeft; int top = Console.CursorTop; bool ProcessWasRunFromExplorer = (left==0 && top==0);
这将告诉您进程是否在其自己的控制台中启动,而不是它是否是explorer。浏览器中的双击将会执行此操作,但是来自应用程序中的Start.Process()也将执行相同的操作。
如果要以不同的方式对待这些情况,请使用此方法来了解父进程的名称:
System.Console.WriteLine("Process id: {0}",Process.GetCurrentProcess().Id); string name = Process.GetCurrentProcess().ProcessName ; System.Console.WriteLine("Process name: {0}",name); PerformanceCounter pc = new PerformanceCounter("Process","Creating Process Id",name); Process p = Process.GetProcessById((int)pc.RawValue); System.Console.WriteLine("Parent Process id: {0}",p.Id); System.Console.WriteLine("Parent Process name: {0}",p.ProcessName); // p.ProcessName == "cmd" or "Explorer" etc
要在进程启动后快速隐藏窗口,请使用以下命令:
private static readonly int SW_HIDE= 0; [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern Boolean ShowWindow(IntPtr hWnd,Int32 nCmdShow); .... { IntPtr myHandle = Process.GetCurrentProcess().MainWindowHandle; ShowWindow(myHandle,SW_HIDE); }
如果您生产winexe(WinForms应用程序),并且可选地在AttachConsole(-1)的情况下附加到父控制台,则不会得到相应的常规控制台应用程序。对于winexe,父进程(如cmd.exe)将在启动GUI应用程序后立即返回到命令提示符。换句话说,命令提示符处于活动状态并准备好进行输入,而刚刚启动的进程可能会发出输出。这是令人困惑的,可能仅适用于调试winforms应用程序。
这对我有用
或者我认为官方的方法是检查父进程是cmd.exe还是explorer.exe