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

3
我有一个小的控制台应用程序,输出一行信息。当我在控制台实例中运行程序时,由于命令提示符在程序完成后重新出现,我能够看到结果。但是,当我从“运行”窗口([Win]+[R])启动程序时,控制台窗口立即消失(因为我没有加入暂停功能,除非它不是由命令行启动,否则我不想加入)。那么,如何确定程序是从命令行还是直接启动的呢?

4
在程序末尾加上 Console.ReadLine();,这样无论程序如何运行,都可以读取输出。它会暂停程序,直到你再次按下 Enter 键。 - Bill the Lizard
4
当你通过命令行启动它时,这是不必要且令人烦恼的。 - LostPhysx
请查看这个SO问题 - Icemanind
2个回答

4
我认为没有内置的方法可以找到这个信息。但是,我认为你可以查找父进程并将其作为相当好的启发式方法。快速测试显示,当从Run(Win+R)或双击启动时,父进程是“explorer”。除了在VS中进行调试时,那时devenv将成为父进程,其他任何时间都可能是cmd或powershell。显然,如果有其他工具会启动该进程的实例的情况,您可能需要给出一个命令行参数来强制执行特定的行为。
你的代码应该像这样:
// 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();
    }
}

这正是我正在寻找的,但我使用 !...,“cmd”,... 来匹配除了 cmd 以外的任何内容。非常感谢。 - LostPhysx

2

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

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

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进行启动而不进行调试。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接