我正在运行作为服务 [英] Am I Running as a Service

查看:191
本文介绍了我正在运行作为服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在写一点点引导$ C $下,可以在控制台中运行的服务。它基本上可以归结为调用的OnStart()方法,而不是使用ServiceBase的启动和停止服务(因为如果它不作为服务安装,它不运行应用程序,使得调试一场噩梦)。

I am currently writing a little bootstrap code for a service that can be run in the console. It essentially boils down to calling the OnStart() method instead of using the ServiceBase to start and stop the service (because it doesn't run the application if it isn't installed as a service and makes debugging a nightmare).

现在我用Debugger.IsAttached,以确定是否我应该使用ServiceBase.Run或[服务] .OnStart,但我知道这是不是最好的主意,因为有些时候最终用户想运行在一个控制台服务(见输出等实时)。

Right now I am using Debugger.IsAttached to determine if I should use ServiceBase.Run or [service].OnStart, but I know that isn't the best idea because some times end users want to run the service in a console (to see the output etc. realtime).

这是我怎么能确定Windows服务控制器启动任何想法,我,或者如果用户在控制台启动我? Apparantly <一href="http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/99c4594b-e6c9-424f-bfe1-c7261bba24d3/"标题=论坛主题> Environment.IsUserInteractive 是没有答案的。我想过用命令行的args,但似乎脏。

Any ideas on how I could determine if the Windows service controller started 'me', or if the user started 'me' in the console? Apparantly Environment.IsUserInteractive is not the answer. I thought about using commandline args, but that seems 'dirty'.

我总能看到周围ServiceBase.Run一个try-catch语句,但似乎很脏。编辑:尝试赶上不起作用

I could always see about a try-catch statement around ServiceBase.Run, but that seems dirty. Try catch doesn't work.

我有一个解决办法:把它在这里的所有其他有兴趣的堆垛机:

I have a solution: putting it up here for all the other interested stackers:

    public void Run()
    {
        if (Debugger.IsAttached || Environment.GetCommandLineArgs().Contains<string>("-console"))
        {
            RunAllServices();
        }
        else
        {
            try
            {
                string temp = Console.Title;
                ServiceBase.Run((ServiceBase[])ComponentsToRun);
            }
            catch
            {
                RunAllServices();
            }
        }
    } // void Run

    private void RunAllServices()
    {
        foreach (ConsoleService component in ComponentsToRun)
        {
            component.Start();
        }
        WaitForCTRLC();
        foreach (ConsoleService component in ComponentsToRun)
        {
            component.Stop();
        }
    }

编辑:有计算器上的另外一个问题在这里的家伙有问题的Environment.CurrentDirectory为C:\ Windows \ System32下的样子,可能是答案。我今天测试了。

There was another question on StackOverflow where the guy had problems with the Environment.CurrentDirectory being "C:\Windows\System32" looks like that may be the answer. I will test today.

推荐答案

如灰烬,我写的全部实际处理code在一个单独的类库组装,然后由Windows服务的可执行文件引用,以及一个控制台应用程序。

Like Ash, I write all actual processing code in a separate class library assembly, which was then referenced by the windows service executable, as well as a console app.

然而,存在的场合时,它知道如果类库在服务可执行或控制台应用程序的上下文中运行是有用的。我这样做的方式是体现在托管应用程序的基类。 (对不起,VB,但我想,下面可能是C#-ified很容易):

However, there are occasions when it is useful to know if the class library is running in the context of the service executable or the console app. The way I do this is to reflect on the base class of the hosting app. (Sorry for the VB, but I imagine that the following could be c#-ified fairly easily):

Public Class ExecutionContext
    ''' <summary>
    ''' Gets a value indicating whether the application is a windows service.
    ''' </summary>
    ''' <value>
    ''' <c>true</c> if this instance is service; otherwise, <c>false</c>.
    ''' </value>
    Public Shared ReadOnly Property IsService() As Boolean
        Get
            ' Determining whether or not the host application is a service is
            ' an expensive operation (it uses reflection), so we cache the
            ' result of the first call to this method so that we don't have to
            ' recalculate it every call.

            ' If we have not already determined whether or not the application
            ' is running as a service...
            If IsNothing(_isService) Then

                ' Get details of the host assembly.
                Dim entryAssembly As Reflection.Assembly = Reflection.Assembly.GetEntryAssembly

                ' Get the method that was called to enter the host assembly.
                Dim entryPoint As System.Reflection.MethodInfo = entryAssembly.EntryPoint

                ' If the base type of the host assembly inherits from the
                ' "ServiceBase" class, it must be a windows service. We store
                ' the result ready for the next caller of this method.
                _isService = (entryPoint.ReflectedType.BaseType.FullName = "System.ServiceProcess.ServiceBase")

            End If

            ' Return the cached result.
            Return CBool(_isService)
        End Get
    End Property

    Private Shared _isService As Nullable(Of Boolean) = Nothing
#End Region
End Class

这篇关于我正在运行作为服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆