C#Windows控制台应用程序如何判断它是否以交互方式运行

Jef*_*ard 25 c# user-interaction console-application

用C#编写的Windows控制台应用程序如何确定它是在非交互式环境中调用(例如从服务或作为计划任务)还是从能够进行用户交互的环境(例如命令提示符或PowerShell)调用?

Gle*_*den 38

要确定.NET应用程序是否在GUI模式下运行:

bool is_console_app = Console.OpenStandardInput(1) != Stream.Null;
Run Code Online (Sandbox Code Playgroud)

  • @Trafz请注意,“System.IO”是一个*命名空间*,此处引用的部分(“Console”)是在*mscorlib.dll*中实现的,因此您可能既没有额外的程序集可供引用,也没有运行时的多余绑定。 (2认同)
  • @00jt 有趣的是,你刚才提到了这一点——今天看到你的评论后,几乎立即在我的回归中出现了同样的问题(也在 VS 16.9.3 上)。肯定有什么事情发生了变化;正如你所提到的,这工作了很长一段时间,但显然调试器现在已经决定连接 *stdin*,这意味着也许这个长期存在的黑客聚会已经结束了...... (2认同)

Ars*_*yan 37

Environment.UserInteractive属性

  • 仅供参考:当选中"允许服务与桌面交互"选项时,"Environment.UserInteractive"对于服务返回true. (6认同)

Mic*_*tum 6

我还没有测试过,但是Environment.UserInteractive看起来很有前景.


Cai*_*ete 6

如果您要做的只是确定程序退出后控制台是否会继续存在(例如,以便您可以Enter在程序退出之前提示用户点击),那么您所要做的就是检查您的进程是否是唯一附加到控制台的进程。如果是,那么当您的进程退出时控制台将被销毁。如果有其他进程附加到控制台,那么控制台将继续存在(因为您的程序不会是最后一个)。

例如*:

using System;
using System.Runtime.InteropServices;

namespace CheckIfConsoleWillBeDestroyedAtTheEnd
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            // ...

            if (ConsoleWillBeDestroyedAtTheEnd())
            {
                Console.WriteLine("Press any key to continue . . .");
                Console.ReadKey();
            }
        }

        private static bool ConsoleWillBeDestroyedAtTheEnd()
        {
            var processList = new uint[1];
            var processCount = GetConsoleProcessList(processList, 1);

            return processCount == 1;
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern uint GetConsoleProcessList(uint[] processList, uint processCount);
    }
}
Run Code Online (Sandbox Code Playgroud)

(*) 改编自此处找到的代码。