如何确定控制台应用程序是否从控制台 window 内启动?

How to determine whether an console application started from within a console window?

我有一个输出单行的小控制台应用程序。当我 运行 来自控制台实例的程序时,我能够看到结果,因为命令 pormpt 在程序完成后重新出现。但是当我从 "Run"-window ([Win]+[R]) 启动程序时,控制台 window 立即消失(因为我没有建立休息,我不'除非它不是由命令行启动的,否则不想中断构建。

那么如何确定程序是从命令行启动还是直接启动?

我认为没有任何方法可以通过编程方式确定控制台应用程序的启动方式。

如果您希望应用程序在这些不同情况下表现不同,那么我建议使用参数,例如

MyApp.exe /keepopen

代码:

static int Main(string[] args)
{
    // Test if argument was supplied:
    if (args.Any(a => a == "/keepopen"))
    {
        System.Console.ReadLine();
    }
}

如果您希望控制台在 Visual Studio 运行 时保持打开状态,我相信您可以使用 Ctrl-F5 启动而不进行调试。

我认为没有内置的方法可以找出这个问题。但是我认为您可以 look up the parent process 并将其用作相当好的启发式方法。快速测试显示,从 运行 (Win+R) 或双击启动时,父进程为 "explorer"。除了在 VS 中调试时,其他任何时候都可能是 cmd 或 powershell,然后 devenv 将成为父进程。显然,如果存在其他工具将启动进程实例的情况,您可能需要提供命令行参数以强制执行特定行为。

您的代码看起来像这样:

// Note: Adapted from Hans Passant's answer linked above.
private static string GetParentProcessName() 
{
    var myId = Process.GetCurrentProcess().Id;
    var query = string.Format("SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {0}", myId);
    var search = new ManagementObjectSearcher("root\CIMV2", query);
    var queryObj = search.Get().OfType<ManagementBaseObject>().FirstOrDefault();
    if (queryObj == null)
    {
        return null;
    }
    var parentId = (uint)queryObj["ParentProcessId"];
    var parent = Process.GetProcessById((int)parentId);
    return parent.ProcessName;
}

static void Main() 
{
    /*
       Program code here.
    */
    if (string.Equals(GetParentProcessName(), "explorer", StringComparison.InvariantCultureIgnoreCase)) 
    {
        Console.ReadLine();
    }
}