检测代码是否作为服务运行

时间:2009-01-05 18:55:53

标签: .net windows-services

.NET库是否有办法检测它是否作为服务运行?

我的图书馆可以以任何一种方式运行。但是当它作为服务运行时,开发人员需要调用另一个方法来指示事实或某些功能无法正常工作。我希望我的库处理日志记录,如果在没有调用该方法的服务中使用它,则会写一个警告。

9 个答案:

答案 0 :(得分:12)

在通过intellisense,调试器和文档进行大量搜索之后,我们无法找到任何严格可靠的内容。有可能获得当前进程ID并尝试找出该进程是否已向SCM注册,但是当.NET提供了获取所有服务的集合的方法时,它们的进程ID不在可用信息中。可以将进程名称与服务名称进行比较,但不一定可靠。

然而,有两件事情相对容易检查,并且可能足以满足您的需要,如果不完全是“这段代码是作为服务运行吗?”

System.Environment.UserInteractive :(正如斯蒂芬马丁所说)如果这是真的,它就不能成为一种服务。大多数非服务(也不是设备驱动程序)的进程都会说真的。某些控制台应用程序在非交互式环境(例如构建过程的一部分)中运行时可能会说错误。

System.Diagnostics.Process.GetCurrentProcess().SessionId :(我认为这与皮埃尔相同)如果不是0,则不是作为服务启动的。大多数正常的应用程序都不会在会话0中(如皮埃尔和斯蒂芬所指出的那样,有一些不那么正常的例外)。最大的问题是如何在XP等旧版操作系统下运行。 XP和Windows 2000显然在会话0中运行服务,但正常的应用程序也将在会话0中运行。 XP的某些配置(例如,不在域中)允许同时进行多个用户会话,并且它们每个都获得不同的会话ID,但是第一个会话ID为0,因此在Vista之前检查不是那么有效。

因此,根据您实际需要区分的内容,这些检查中的一项或两项可能对您有用。

答案 1 :(得分:5)

尽管您可以使用Environment.UserInteractive进行猜测,但实际上没有任何方法可以判断您的库是否在服务上下文中运行。

但通常,库不应该依赖于它的应用程序上下文。库应该为应用程序提供服务,如果它需要不同的参数,具体取决于它的调用方式,它应该要求应用程序提供这些参数。

您的图书馆可能不会严格根据其是否托管在服务中而采取不同的行为,而是提供有关您的图书馆需要通知的服务环境或用户的一些信息。申请应告知图书馆必要的条件或信息,图书馆不应自行猜测。

编辑:如果可以的话,我会就你的问题发表评论。如果必要,使用重载方法和/或如果没有提供所需的所有信息则完全失败。

答案 2 :(得分:2)

您应该检查您是否在会话零点运行(至少如果您的目标是Vista)。您可以使用WTSRegisterSessionNotification,如下例所示:

  [DllImport("kernel32.dll")]
  private static extern int WTSGetActiveConsoleSessionId();

答案 3 :(得分:2)

快速而又脏的方法是将命令行开关应用于 HKLM \ System \ CurrentControlSet \ services \ MyService \ ImagePath 下的注册表中的条目,然后在主函数中检查该开关

然后您知道是否是由services.exe启动的。是的,这是一个黑客攻击。

答案 4 :(得分:2)

派对有点晚了,但是如何使用ServiceController.GetServices获取服务列表并检查进程的ID?

(“如何运行Windows服务进程ID?”:http://social.msdn.microsoft.com/Forums/en/netfxbcl/thread/a979351c-800f-41e7-b153-2d53ff6aac29

答案 5 :(得分:2)

您可以添加Microsoft.Extensions.Hosting.WindowsServices NuGet程序包并使用WindowsServiceHelpers.IsWindowsService()帮助程序方法。

对于Linux,您可以使用Microsoft.Extensions.Hosting.SystemdSystemdHelpers.IsSystemdService()方法。

答案 6 :(得分:1)

一种方法是查看应用程序的用户上下文。如果您看到它作为“SYSTEM”用户运行,那么您将作为服务运行(或至少具有服务级别权限)。

答案 7 :(得分:1)

0xA3到this question的答案实际上包含用于查询SCM的C#代码,就像Rob Parker在他的回答中描述的那样。

答案 8 :(得分:1)

似乎我参加聚会有点晚,但是话题似乎很流行。 作为服务运行时,有趣的区别在于,在应用程序启动时,当前文件夹指向系统目录(默认为C:\windows\system32)。在任何现实情况下,其用户应用程序几乎都不会从系统文件夹启动。

因此,我使用以下技巧(c#):

protected static bool IsRunAsService()
{
    string CurDir = Directory.GetCurrentDirectory();
    if (CurDir.Equals(Environment.SystemDirectory, StringComparison.CurrentCultureIgnoreCase))
    { 
         return true; 
    }

    return (false);
}

更多详细信息,请访问:https://stackoverflow.com/a/60174944/8494004