Determine if .Net core console application is running in user interactive mode

Viewed 4799

Is it possible to determine if a .Net core console application is running in user interactive mode?

In previous versions of .Net it was possible to test Environment.UserInteractive to see if the user had access to the application. This doesn't seem to exist in .Net core.

4 Answers

To complement Martin Ullrich's helpful answer:

If you're willing to define user-interactive as runs in a console/terminal window visible to the current user, you can use the following approach (C#), which should work on all supported platforms:

Note: Visible means visible in principle, i.e., can be made visible by the user if currently obscured or minimized.

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()}");
    }
  }
}

Note:

  • On Windows, all console-mode applications always run in a console window, whether that window is visible or not; the P/Invoke function declarations check if the console window (GetConsoleWindow()) - if any - associated with the current process is a visible window (IsWindowVisible(), on the current user's desktop).

  • On Unix-like platforms, non-GUI applications fundamentally don't need a terminal window to run, and launching such an application from a GUI app, for instance, does not involve a terminal. Therefore, the assumption is that if a terminal window is present at all, it implies that that window is visible; Console.WindowHeight only contains a positive value if a terminal window is present.

Another option is to check a process session id: for services it's always 0. So you can use the following snippet:

// Environment.UserInteractive is not working on NET Core 3.1
if (Process.GetCurrentProcess().SessionId != 0) 
{
    service.RunAsConsole(args);
}
else
{
    ServiceBase.Run(service);
}
Related