如何确定是否在Windows服务内启动?

mik*_*oro 5 c# windows-services

目前我正在通过以下方式检查它:

if (Environment.UserInteractive)
    Application.Run(new ServiceControllerForm(service));
else
    ServiceBase.Run(windowsService);
Run Code Online (Sandbox Code Playgroud)

它有助于调试一点,也可以使用可执行文件运行服务.但现在假设该服务需要与用户桌面进行交互,因此我必须在属性中启用"允许服务与桌面交互".这当然打破了这种检查方式.还有另外一种方法吗?

Geo*_*dze 8

此外,必须注意的是,即使它作为 Windows 服务运行,它也Environment.UserInteractive始终true.NET Core 中返回。

目前,最好的方法似乎是来自 ASP.NET Core 的这个

来源: .NET Core 2.2 .NET Core 3.1

在 .NET 5 中修复


Aar*_*ght 6

这不是完美的,但你可能会做这样的事情:

public static bool IsService()
{
    ServiceController sc = new ServiceController("MyApplication");
    return sc.Status == ServiceControllerStatus.StartPending;
}
Run Code Online (Sandbox Code Playgroud)

这个想法是,如果你在服务仍在启动时运行它,那么它将始终处于挂起状态.如果根本没有安装该服务,则该方法将始终返回false.它只会在服务正在启动的极不可能的极端情况下失败,并且有人试图同时将其作为应用程序启动.

我不喜欢这个答案,但我认为这可能是你能做的最好的.实际上,允许相同的应用程序在服务或应用程序模式下运行并不是一个好主意 - 从长远来看,如果将所有常用功能抽象到类库中并且只创建一个单独的服务应用程序,则会更容易.但是,如果由于某种原因,你真的真的需要有你的蛋糕和太吃它,你很可能结合IsService方法上面Environment.UserInteractive,以得到正确的答案,几乎所有的时间.


Yau*_*aur 6

已接受答案的问题是检查未安装的服务的状态会抛出异常。我正在使用的方法IsService如下所示:

    private bool IsService(string name)
    {
        if (!Environment.UserInteractive) return true;
        System.ServiceProcess.ServiceController sc = new System.ServiceProcess.ServiceController(name);
        try
        {
            return sc.Status == System.ServiceProcess.ServiceControllerStatus.StartPending;
        }
        catch(InvalidOperationException)
        {
            return false;
        }
    }
Run Code Online (Sandbox Code Playgroud)

这应该比仅仅检查更可靠Environment.UserInteractive


Ran*_*den 5

在 .NET Core 中,您可以使用Microsoft.Extensions.Hosting.WindowsServices NuGet 包中提供的WindowsServiceHelpers.IsWindowsService()静态帮助程序方法来确定应用程序是否作为 Windows 服务运行。

Install-Package Microsoft.Extensions.Hosting.WindowsServices

if (WindowsServiceHelpers.IsWindowsService())
{
    // The application is running as a Windows Service
}
else
{
    // The application is not running as a Windows Service
}
Run Code Online (Sandbox Code Playgroud)