【问题标题】:How to tell if method is called from Windows Service in .Net (managed) code如何判断方法是否从 .Net(托管)代码中的 Windows 服务调用
【发布时间】:2009-05-26 18:00:03
【问题描述】:

如何判断我在托管代码中编写的方法是从交互式应用程序还是从 Windows 服务调用的?

【问题讨论】:

    标签: windows service managed


    【解决方案1】:

    您想了解 Windows 服务的哪一部分?或者您不想了解交互式应用程序的哪个部分?什么对你来说真正重要?


    每当我听到这样的请求时,几乎都是设计上的错误。我建议几个答案:

    1. 让调用者告诉你使用哪个格式化程序,或者
    2. 将格式化程序类的名称放入配置文件中。让所有格式化程序实现相同的接口。在运行时,第一次需要格式化程序时,创建配置文件中指定的格式化程序的实例,并通过公共接口调用它。
    3. 不要重新发明轮子。使用 System.Diagnostics 中的类,事实上,它的配置很像我的 #2。

    代码对调用它的上下文敏感几乎总是一个错误。

    【讨论】:

    • 这里是上下文:我有一个正在编写的库,可以从控制台应用程序、gui 应用程序或 Windows 服务调用。如果我是从服务调用而不是从控制台或 GUI 应用程序调用,我想定制一些日志记录信息以以特定方式格式化。我只需要知道我是否在服务下运行的是/否答案。
    • 甜蜜的僵尸耶稣,使用 log4net 并通过 .config 文件配置日志记录。
    【解决方案2】:

    我想我可能已经弄清楚了(至少这可以满足我的需要——您的里程可能会因您尝试做的事情而有所不同)。有一个悬挂在 Environment 对象上的属性,称为“UserInteractive”。它会告诉您是否在可以访问桌面的上下文中运行。

    【讨论】:

      【解决方案3】:

      至少有两种方法可以做到这一点:

      1. “System.Reflection.Assembly.GetCallingAssembly().FullName”将返回调用您的代码的程序集的名称。
      2. “Environment.StackTrace”将返回调用您的代码的完整堆栈跟踪。您应该会在字符串中看到您的调用方法名称。

      【讨论】:

      • 是否有关于获取调用方法或程序集的名称的方法,我可以使用它来确定它是否是 Windows 服务?我的库将在客户代码的上下文中运行,因此我无法提前知道我的调用上下文是什么。如果调用堆栈中有一些方法名称可以用来判断我是否在 Windows 服务下运行,那可能会有所帮助。
      【解决方案4】:

      您可以定义两种不同的记录器:一种用于交互式应用程序,另一种用于 Windows 服务。并让客户使用配置文件选择他想使用的记录器。如果客户端选择了错误的记录器或忘记配置,您也可以使用默认记录器。 我认为将日志记录和格式化消息等功能设置为可配置应该是一个更好的主意。

      【讨论】:

        【解决方案5】:

        不知道是否有内置的可能性,但请查看 System.Diagnostics.Process 类。除其他外,它还有一个GetService() 方法,也许这会对您有所帮助。如果失败,StartInfo 成员可能包含有用的信息。

        如果不介意使用PInvoke,可以获取当前进程的父进程。如果它在 NT AUTHORITY\SYSTEM 帐户下运行并且它的名称是 service.exe,那么当前进程(很可能)是一个服务。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-14
          • 1970-01-01
          • 1970-01-01
          • 2010-09-19
          • 1970-01-01
          • 2011-02-05
          相关资源
          最近更新 更多