. net Windows服务需要调用ServiceBase.Run()吗?

本文关键字:Run ServiceBase 调用 Windows 服务 net | 更新日期: 2023-09-27 17:50:43

我是Windows服务的新手,但我发现了一个奇怪的事件,我希望得到一些澄清。我有一个用c#编写的Windows服务,我安装并开始使用命令行(在stackoverflow上找到的伟大指令)。我的服务的主要方法是这样的:

    static void Main(string[] args)
    {
        if (args.Length == 0)
        {
            ServiceBase.Run(new MyServiceName());
        }
        else if (args.Length == 1)
        {
            const string name = "MyServiceName";
            Type type = typeof(MyAssembly);
            switch (args[0])
            {
                case "-install":
                    ServiceUtils.InstallService(name, type);
                    ServiceUtils.StartService(args, name);
                    break;
                case "-uninstall":
                    ServiceUtils.StopService(name);
                    ServiceUtils.UninstallService(name, type);
                    break;
                default:
                    throw new NotImplementedException();
            }
        }
    }

当我调试时,我总是发送一个参数(-install)到应用程序。因此,第一个if语句(if (args.Length == 0)永远不会被执行。这是预期的,我的服务安装和启动很好。然而,如果我删除if语句,只留下if (args.Length == 1)语句,我的服务安装正确,但它没有启动,我得到以下错误:

无法在计算机'.'上启动MyServiceName

我的问题是:为什么第一个if语句中的代码在我的应用程序中从来没有执行过?

以下是InstallService和StartService方法的支持代码(我也从stackoverflow获得):

    public static void InstallService(string serviceName, Type t)
    {
        if (IsInstalled(serviceName)) return;
        try
        {
            Assembly a = t.Assembly;
            using (AssemblyInstaller installer = GetInstaller(a))
            {
                IDictionary state = new Hashtable();
                try
                {
                    installer.Install(state);
                    installer.Commit(state);
                }
                catch
                {
                    try
                    {
                        installer.Rollback(state);
                    }
                    catch
                    { }
                    throw;
                }
            }
        }
        catch
        {
            throw;
        }
    }
    public static void StartService(string[] args, string serviceName)
    {
        if (!IsInstalled(serviceName)) return;
        Console.WriteLine("Service is installed.  Attempting to start service.");
        ServiceController sc = new ServiceController();
        sc.ServiceName = serviceName;
        if (sc.Status == ServiceControllerStatus.Stopped)
        {
            Console.WriteLine("Starting {0}: ", sc.ServiceName);
            try
            {
                sc.Start(args);
                sc.WaitForStatus(ServiceControllerStatus.Running);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }

. net Windows服务需要调用ServiceBase.Run()吗?

第一个if语句(if (args。长度== 0)永远不会被执行

这是不正确的,它被执行。通过ServiceController.Start()。您无法看到这一点,因为服务控制器再次启动了您的EXE,创建了另一个进程。这一次是服务进程,而不是控制台进程。一个没有附加调试器的。如果你删除了If语句,那么服务在启动后就会立即退出。服务控制器正确地报错了"Cannot start MyServiceName"异常消息

if (args.Length == 0)
{            
    ServiceBase.Run(new MyServiceName());
}

在服务控制器启动服务时运行,因为服务控制器没有向Main()传递任何参数。

如果你不做ServiceBase.Run(new MyServiceName()),那么你的服务将不会响应任何来自服务控制器的命令,你会得到你所看到的错误。

Main()仍然是应用程序的入口点。该进程作为一个独立的步骤启动,而不是启动内部的服务。

在同一个进程中运行多个服务实际上是可能的,而这种处理方式使之成为可能。这是……不仅是同一个exe程序,而且实际上是在同一个运行进程中。