简体   繁体   English

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

[英]Error 1053 when starting a Windows Service (exe created in Visual Studio)

I have an executable created from a project in Visual Studio that I would like to create a service with (so I can run it without the need of a console window). 我有一个从Visual Studio中的项目创建的可执行文件,我想使用该可执行文件创建服务(这样我就可以在不需要控制台窗口的情况下运行它)。 I publish the project, and create the Windows Service using: 我发布项目,并使用以下方法创建Windows服务:

sc create MY.SERVICE binpath= "C:\Program Files\Project\serviceProj\myService.exe 

The service shows up inside the Windows Services Manager as expected. 该服务将按预期显示在Windows Services Manager中。 However, whenever I try to start the service, it fails after about 2 seconds and gives me the following error: 但是,每当我尝试启动该服务时,它将在大约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. 

Things I have done: 我所做的事情:

Changed from Debug to Release in Visual Studio 从调试更改为在Visual Studio中发布

Run everything as administrator (creating the service, publishing the project, starting the service, etc.). 以管理员身份运行所有内容(创建服务,发布项目,启动服务等)。

I've also read somewhere that increasing the amount of time the Service Manager waits for the service to start may work. 我还在某处读到,增加服务管理器等待服务启动的时间可能会起作用。 I added the Windows registry value to do just that but unfortunately it did not work. 我添加了Windows注册表值来执行此操作,但不幸的是它没有用。

Starting the service from a command prompt usually only takes 2-3 seconds to startup and start listening for requests so I'm unsure of what is going on. 从命令提示符启动服务通常只需要2-3秒即可启动并开始侦听请求,因此我不确定发生了什么。

Any help is appreciated. 任何帮助表示赞赏。

Here is my Startup.cs class: 这是我的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}");
            });
        }
    }
}

The error you're seeing is a notification from Windows that the service you've started hasn't completed its startup within a reasonable amount of time (30 seconds). 您看到的错误是Windows发出的通知,表明您启动的服务尚未在合理的时间内(30秒)完成启动。

This is happening because you've got the logic for your service stuffed in your app's public Main() method, which isn't what you want for a Windows service. 之所以发生这种情况,是因为您已将应用程序的逻辑塞入了应用程序的公共Main()方法中,而这并不是Windows服务所需要的。

A Windows service includes a bit of structure to support the service. Windows服务包括一些支持该服务的结构。 All that typically happens in a service's Main() is to load the service, but not actually start it running. 服务的Main()中通常发生的所有事情是加载服务,但实际上并未启动它的运行。 The service includes event handlers to support responding to standard service actions, such as starting, stopping, pausing, continuing, and to handling when the system is being shutdown. 该服务包括事件处理程序,以支持对标准服务操作的响应,例如启动,停止,暂停,继续以及关闭系统时的处理。

This structure that all Windows services have is a bit complicated and must be built to the operating system's specifications. 所有Windows服务都具有的这种结构有点复杂,必须按照操作系统的规范进行构建。 While it's possible to build a Windows service manually, it can be difficult to get all the plumbing correct, and hence much easier to let Visual Studio help you out here. 尽管可以手动构建Windows服务,但可能很难正确设置所有管道,因此让Visual Studio在这里帮助您变得容易得多。

The simplest and most straightforward approach when building a Windows service is to let VS create a Windows service project for when you create the new Visual Studio project. 构建Windows服务时,最简单,最直接的方法是让VS在创建新的Visual Studio项目时创建Windows服务项目。 The new project will include most all the necessary plumbing and service features you'll need from the get-go. 新项目将包括您从一开始就需要的大多数必需的管道和服务功能。

Of course, you can build a service manually, but there's really no reason to. 当然,您可以手动构建服务,但实际上没有理由。 If you do want go down the manually built path you'll need to at a minimum perform the following actions (one caveat - I'm doing this from memory and I moved to VS 2017 a while back, so this might not be exactly right): 如果您确实想沿着手动构建的路径走下去,则至少需要执行以下操作(一个警告-我正在从内存中执行此操作,而我又移回了VS 2017,所以这可能并不完全正确) ):

  • Add a Windows Service component to your project. 将Windows服务组件添加到您的项目。 To do that, right-click on your project in the Solution Explorer and choose "Add". 为此,请在解决方案资源管理器中右键单击您的项目,然后选择“添加”。 In the menu that appears, select "Component...". 在出现的菜单中,选择“组件...”。 In the dialog that appears, choose "Windows Service". 在出现的对话框中,选择“ Windows服务”。 A word of advice, give the file a meaningful name before pressing that "Add" button. 提示一下,在按下“添加”按钮之前给文件起一个有意义的名称。

  • Once that Windows Service component is added, right-click on it and set its properties. 添加该Windows Service组件后,右键单击它并设置其属性。

  • To program the OnStart, OnStop, OnPause, OnContinue, and OnShutdown event handlers, right click on the Windows Service design space (or right-click on the file in Solution Explorer) and choose "View code". 要对OnStart,OnStop,OnPause,OnContinue和OnShutdown事件处理程序进行编程,请右键单击Windows Service设计空间(或在解决方案资源管理器中右键单击该文件),然后选择“查看代码”。

There are many more things to know about building Windows services, that there's not room for here. 关于构建Windows服务,还有许多要了解的事情,这里没有空间。 I suggest finding some good documentation on the subject and studying that before you do a lot in this space, as doing something wrong here can have a pretty drastic affect on the machine that's running your service. 我建议您在此领域做很多事情之前,先找到一些关于该主题的良好文档,并进行研究,因为此处做错了可能会对运行您的服务的计算机产生极大的影响。 Have a look at MSDN: Walkthrough: Creating a Windows Service Application in the Component Designer . 看看MSDN:演练:在组件设计器中创建Windows Service应用程序 It should help explain this much more thoroughly. 它应该有助于更彻底地解释这一点。

So I opened Event Viewer to get more information about the error I was receiving. 因此,我打开了事件查看器,以获取有关我收到的错误的更多信息。 I was receiving a FileNotFoundException which was causing the error. 我收到了导致该错误的FileNotFoundException。 This surprises me since running the service from Visual Studio or from the command line works perfectly fine - the file can be found. 这使我感到惊讶,因为从Visual Studio或从命令行运行该服务非常正常-可以找到该文件。 The file in question is located at the working directory. 有问题的文件位于工作目录中。 I hardcoded the path to the file (instead of using relative path) into my File.OpenText method and it worked. 我将文件的路径硬编码(而不是使用相对路径)到我的File.OpenText方法中,并且可以正常工作。 So, for some reason the relative path isn't working for the Windows Service. 因此,由于某些原因,相对路径不适用于Windows Service。

尝试修复.SetBasePath(env.ContentRootPath)https : //github.com/dasMulli/dotnet-win32-service/issues/54

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM