我有一个从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
以管理员身份运行所有内容(创建服务,发布项目,启动服务等)。
我还在某处读过,增加Service Manager等待服务启动的时间可能会有效。我添加了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}");
});
}
}
}
答案 0 :(得分:2)
您看到的错误是来自Windows的通知,即您已启动的服务在合理的时间(30秒)内未完成启动。
这种情况正在发生,因为您已经在应用程序的公共Main()方法中获得了服务的逻辑,这不是您想要的Windows服务。
Windows服务包含一些支持该服务的结构。通常在服务的Main()中发生的一切是加载服务,但实际上并没有启动它。该服务包括事件处理程序,以支持响应标准服务操作,例如启动,停止,暂停,继续以及在系统关闭时进行处理。
所有Windows服务都具有这种结构有点复杂,必须根据操作系统的规范进行构建。虽然可以手动构建Windows服务,但是很难让所有的管道都正确,因此更容易让Visual Studio帮助你。
构建Windows服务时最简单,最直接的方法是让VS在创建新的Visual Studio项目时创建Windows服务项目。新项目将包括您从一开始就需要的大部分所有必要的管道和服务功能。
当然,您可以手动构建服务,但实际上没有理由。如果您确实需要按照手动构建的路径进行操作,则至少需要执行以下操作(一个警告 - 我是从内存中执行此操作,并且一段时间后我移动到VS 2017,所以这可能不完全正确):
将Windows服务组件添加到项目中。为此,在解决方案资源管理器中右键单击您的项目,然后选择&#34;添加&#34;。在出现的菜单中,选择&#34;组件...&#34;。在出现的对话框中,选择&#34; Windows服务&#34;。一句忠告,在按下之前给文件一个有意义的名字&#34;添加&#34;按钮。
添加Windows Service组件后,右键单击它并设置其属性。
要对OnStart,OnStop,OnPause,OnContinue和OnShutdown事件处理程序进行编程,请右键单击Windows服务设计空间(或右键单击解决方案资源管理器中的文件),然后选择&#34;查看代码& #34;
关于构建Windows服务还有很多事情需要了解,这里没有空间。我建议找一些关于这个主题的好文档,并在你在这个领域做很多事情之前研究一下,因为在这里做错了会对运行你服务的机器产生很大的影响。看看MSDN: Walkthrough: Creating a Windows Service Application in the Component Designer。它应该有助于更彻底地解释这一点。
答案 1 :(得分:1)
所以我打开了事件查看器以获取有关我收到的错误的更多信息。我收到了导致错误的FileNotFoundException。这让我感到惊讶,因为从Visual Studio运行服务或从命令行运行完全正常 - 可以找到该文件。有问题的文件位于工作目录中。我将文件的路径硬编码(而不是使用相对路径)到我的File.OpenText方法,它工作。因此,由于某种原因,相对路径不适用于Windows服务。
答案 2 :(得分:0)
尝试修复.SetBasePath(env.ContentRootPath)
:https://github.com/dasMulli/dotnet-win32-service/issues/54