是否可以确定.Net核心控制台应用程序是否在用户交互模式下运行?
在.Net的早期版本中,可以测试Environment.UserInteractive
以查看用户是否有权访问该应用程序。这似乎不存在于.Net核心中。
答案 0 :(得分:5)
.NET Core面临的问题不仅仅是经典的.NET Framework,而是定义了“用户交互”的方式。即使在“经典”.NET上,Environment.UserInteractive
仍然感到hacky,因为它依赖于system API call to query user object flags并测试描述为Window station has visible display surfaces
的标志。目前还不清楚在用于运行命令的无GUI的Windows nano服务器上,这应该在语义上意味着什么。
我的建议是确定您要测试的确切用例。例如,您可以使用Console.IsOutputRedirected
和Console. IsInputRedirected
测试附加的输入和输出流是否重定向。在非Windows系统上,可以调用isatty()
,但目前不能用作.NET API(您必须编写PInvoke代码)。如果您想确定您是否作为Windows服务运行,TopShelf checks if the process has been started by the service host。另一种方法是为特定用例添加额外的参数 - 例如如果要从脚本运行工具,请添加并检查--noninteractive
。
答案 1 :(得分:0)
补充Martin Ullrich's helpful answer:
如果您愿意将 user-interactive 定义为在当前用户可见的控制台/终端窗口中运行 ,则可以使用以下方法(C#),该方法应在所有受支持的平台上都可以使用:
注意: Visible 表示原则上可见的 ,即如果当前被遮盖或最小化,则可以使用户可见。
ngIf
注意:
在Windows上,所有控制台模式应用程序始终始终在控制台窗口中运行,无论该窗口是否可见。 P / Invoke函数声明检查与当前进程关联的控制台窗口(using System;
using System.Runtime.InteropServices;
namespace net.same2u.pg
{
static class Program
{
// P/Invoke declarations for Windows.
[DllImport("kernel32.dll")] static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")] static extern bool IsWindowVisible(IntPtr hWnd);
// Indicates if the current process is running:
// * on Windows: in a console window visible to the user.
// * on Unix-like platform: in a terminal window, which is assumed to imply
// user-visibility (given that hidden processes don't need terminals).
public static bool HaveVisibleConsole()
{
return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
IsWindowVisible(GetConsoleWindow())
:
Console.WindowHeight > 0;
}
static void Main(string[] args)
{
Console.WriteLine($"Running in visible console? {HaveVisibleConsole()}");
}
}
}
)(如果有)是否是可见窗口(在当前用户的桌面上GetConsoleWindow()
)。
在类似Unix的平台上,非GUI应用程序基本上不需要运行终端窗口,例如,从GUI应用程序启动此类应用程序不涉及终端。因此,假设如果终端窗口根本没有出现,则表示该窗口是可见的。 IsWindowVisible()
仅在存在终端窗口时包含正值。
答案 2 :(得分:0)
这可能会在将来的.NET Core版本(也许是5.0)中得到修复:
https://github.com/dotnet/runtime/issues/770和 https://github.com/dotnet/runtime/pull/1234
同时查看其他答案(例如Console.IsInputRedirected
应该可用于检测Windows Service上下文)。