启动Windows服务时出现错误1053(使用Visual Studio创建的exe文件)

7

我有一个在Visual Studio中创建的可执行文件,我希望能将其创建为服务(这样就不需要使用控制台窗口运行它了)。我发布该项目并使用以下方法创建Windows服务:

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

这项服务会如预期一样出现在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. 

我所做的事情:

在Visual Studio中将Debug更改为Release。

以管理员身份运行所有操作(创建服务、发布项目、启动服务等)。

我也曾在某个地方看到,增加服务管理器等待服务启动时间的长度可能会起作用。我添加了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}");
            });
        }
    }
}

请告诉我们更多关于你的服务的信息。你的OnStart事件处理程序应该尽快完成它的工作并退出,而且肯定应该在不到30秒的时间内完成。你是否正在OnStart处理程序中执行长时间运行的任务?也许可以发布一些代码吗? - STLDev
@STLDeveloper 我没有OnStart事件处理程序 - 我应该有吗?我有一个Startup.cs类,我已经添加到原始帖子中。我以前从未创建过Windows服务 - 根据我在网上看到的,似乎可以从可执行文件创建Windows服务。 - Roka545
1
是的,完全有可能,但必须遵循应用程序结构方面非常具体的一套指导方针。 - STLDev
1
你在网上看到的大多数可能是关于服务包装器的,例如srvany或nssm,它们是仅负责运行其他可执行文件的服务。这通常被概括为“将可执行文件作为服务运行”(有点误导性)。 - Harry Johnston
3个回答

5
你看到的错误是Windows的通知,意味着你启动的服务在合理的时间内(30秒)内没有完成启动。
这是因为你将服务逻辑放在了应用程序的公共Main()方法中,而这不是Windows服务所需要的。
Windows服务包括一些结构来支持服务。在服务的Main()中通常只加载服务,但并未实际启动它运行。服务包括事件处理程序以支持响应标准服务操作,例如启动、停止、暂停、继续,并处理系统正在关闭时的情况。
所有Windows服务都具有的这种结构有点复杂,必须按照操作系统的规格进行构建。虽然可以手动构建Windows服务,但很难正确处理所有管道,因此让Visual Studio在这里帮助你会更容易。
在构建Windows服务时,最简单和直接的方法是让VS在创建新的Visual Studio项目时创建一个Windows服务项目。新项目将从一开始就包括大多数必要的管道和服务功能。
当然,你可以手动构建服务,但实际上没有必要。如果你想走手动构建的路线,你至少需要执行以下操作(一个警告 - 我是根据记忆做的,而我已经移动到VS 2017一段时间了,所以可能不完全正确):
  • 在解决方案资源管理器中右键单击项目,选择“添加”,在出现的菜单中选择“组件...”。在出现的对话框中,选择“Windows 服务”,给文件起一个有意义的名称后,按“添加”按钮。

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

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

关于构建Windows服务,还有许多需要了解的内容,这里无法一一列举。我建议在此领域大量操作之前,先找到一些好的文档并学习,因为在此处出现错误可能会对运行您的服务的计算机产生相当严重的影响。请参考MSDN:使用组件设计器创建Windows服务应用程序的演示,它应该可以更全面地解释这个问题。


2

所以我打开了事件查看器,以获取有关我收到的错误的更多信息。我收到了一个FileNotFoundException,这导致了错误。这让我感到惊讶,因为从Visual Studio或命令行运行服务都可以正常工作 - 文件可以被找到。所涉及的文件位于工作目录中。我将文件的路径硬编码到我的File.OpenText方法中(而不是使用相对路径),它起作用了。因此,由于某种原因,相对路径在Windows服务中无法正常工作。


这里也是一样的 - 发生了一个错误,但 Windows 没有报告它,而是立即声明超时。我在这里说的是 hello world。我剥离了我的日志记录代码,所以我只有服务存根,一切都正常工作 - 即使是调试构建。 - Oderik
1
你在哪里找到了FileNotFoundException的日志?我正在事件查看器中查找,但只能看到“由于以下错误,无法启动MyService: 服务未能在预期时间内响应启动信号或控制信号。” - Maciejek

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接