启动 Windows 服务时出现错误 1053(在 Visual Studio 中创建的 exe)

Rok*_*545 7 c# service windows-services visual-studio visual-studio-2015

我有一个从 Visual Studio 中的项目创建的可执行文件,我想用它来创建服务(这样我就可以在不需要控制台窗口的情况下运行它)。我发布该项目,并使用以下命令创建 Windows 服务:

sc create MY.SERVICE binpath= "C:\Program Files\Project\serviceProj\myService.exe 
Run Code Online (Sandbox Code Playgroud)

该服务按预期显示在 Windows 服务管理器中。但是,每当我尝试启动该服务时,它都会在大约 2 秒后失败,并给出以下错误:

Windows could not start the MY.SERVICE on Local Computer. 
Error 1053: The service did not respond to the start or control request in a timely fashion. 
Run Code Online (Sandbox Code Playgroud)

我做过的事情:

在 Visual Studio 中从调试更改为发布

以管理员身份运行一切(创建服务、发布项目、启动服务等)。

我还在某处读到增加服务管理器等待服务启动的时间可能有效。我添加了 Windows 注册表值来执行此操作,但不幸的是它不起作用。

从命令提示符启动服务通常只需要 2-3 秒即可启动并开始侦听请求,因此我不确定发生了什么。

任何帮助表示赞赏。

这是我的 Startup.cs 类:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Serialization;
using Microsoft.AspNetCore.Hosting.WindowsServices;
using System.Diagnostics;
using System.IO;
using Serilog;
using System.Linq;

namespace My.Service
{
    public class Startup
    {
        public static void Main(string[] args)
        {
            var exePath = Process.GetCurrentProcess().MainModule.FileName;
            var directoryPath = Path.GetDirectoryName(exePath);

            if (Debugger.IsAttached || args.Contains("--debug"))
            {
                var host = new WebHostBuilder()
                   .CaptureStartupErrors(true)
                   .UseKestrel()
                   .UseUrls("http://localhost:5002")
                   .UseContentRoot(Directory.GetCurrentDirectory())
                   .UseIISIntegration()
                   .UseStartup<Startup>()
                   .Build();
                host.Run();
            }
            else
            {
                var host = new WebHostBuilder()
                    .UseKestrel()
                    .UseUrls("http://localhost:5002")
                    .UseContentRoot(directoryPath)
                    .UseIISIntegration()
                    .UseStartup<Startup>()
                    .Build();
                host.RunAsService();
            }
        }


        public Startup(IHostingEnvironment env)
        {
            //Setup Logger
            Log.Logger = new LoggerConfiguration()
                .WriteTo.Trace()
                .MinimumLevel.Debug()
                .CreateLogger();
            // Set up configuration sources.
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json");
            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; set; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().AddJsonOptions(options =>
            {
                options.SerializerSettings.ContractResolver =
                    new CamelCasePropertyNamesContractResolver();
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime lifetime)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}");
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

STL*_*Dev 5

您看到的错误是来自 Windows 的通知,表明您已启动的服务尚未在合理的时间(30 秒)内完成启动。

发生这种情况是因为您的服务逻辑已填充在应用程序的公共 Main() 方法中,这不是您想要的 Windows 服务。

Windows 服务包含一些支持该服务的结构。服务的 Main() 中通常发生的所有事情都是加载服务,但实际上并没有启动它运行。该服务包括事件处理程序,以支持响应标准服务操作,例如启动、停止、暂停、继续以及系统关闭时的处理。

所有 Windows 服务都具有的这种结构有点复杂,必须根据操作系统的规范进行构建。虽然可以手动构建 Windows 服务,但要使所有管道都正确可能很困难,因此让 Visual Studio 在这里帮助您要容易得多。

构建 Windows 服务时最简单、最直接的方法是让 VS 创建一个 Windows 服务项目,以便在您创建新的 Visual Studio 项目时使用。新项目将包括您从一开始就需要的大部分必要的管道和服务功能。

当然,您可以手动构建服务,但实际上没有理由这样做。如果你确实想沿着手动构建的路径走下去,你至少需要执行以下操作(一个警告 - 我是凭记忆做这件事的,不久前我搬到了 VS 2017,所以这可能不完全正确):

  • 将 Windows 服务组件添加到您的项目中。为此,请在解决方案资源管理器中右键单击您的项目,然后选择“添加”。在出现的菜单中,选择“组件...”。在出现的对话框中,选择“Windows 服务”。一句建议是,在按“添加”按钮之前为文件指定一个有意义的名称。

  • 添加 Windows 服务组件后,右键单击它并设置其属性。

  • 要对 OnStart、OnStop、OnPause、OnContinue 和 OnShutdown 事件处理程序进行编程,请右键单击 Windows 服务设计空间(或右键单击解决方案资源管理器中的文件),然后选择“查看代码”。

关于构建 Windows 服务还有很多事情需要了解,这里无法一一介绍。我建议您在这个领域做很多事情之前找到一些关于该主题的好的文档并进行研究,因为在这里做错事可能会对运行您的服务的机器产生相当大的影响。查看MSDN:演练:在组件设计器中创建 Windows 服务应用程序。它应该有助于更彻底地解释这一点。