I'm trying to run a Web API application as a Windows Service using OWIN. However, I get the following message, when trying to start the service:
The [ServiceName] service on Local Computer started and then stopped. Some services stop automatically if they are not in use by other services or programs.
For some reason my service doesn't understand that it should keep listening to http://localhost:9000
The VS solution consists of two projects: The Web API and the Windows service.
In the Windows service project I have:
static class Program
{
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service()
};
ServiceBase.Run(ServicesToRun);
}
}
public partial class Service : ServiceBase
{
private const string _baseAddress = "http://localhost:9000/";
private IDisposable _server = null;
public Service()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
_server = WebApp.Start<Startup>(url: _baseAddress);
}
protected override void OnStop()
{
if (_server != null)
{
_server.Dispose();
}
base.OnStop();
}
}
In OnStart the Startup refers to the Startup class in the Web API project:
public class Startup
{
public void Configuration(IAppBuilder builder)
{
var config = new HttpConfiguration();
config.Routes.MapHttpRoute("Default",
"{controller}/{id}",
new { id = RouteParameter.Optional });
builder.UseWebApi(config);
}
}
(It also contains some configurations for Unity and logging.)
I guess the installer part of the Windows service project is mostly irrelevant, though it could be useful to know that I have:
this.serviceProcessInstaller.Account = System.ServiceProcess.ServiceAccount.LocalService;
What I've tried:
To host the Web API using a console application and then host the console application as a Windows Service. But even though I included 'Console.ReadKey()', it simply stopped.
To follow this guide:
OWIN-WebAPI-Service
The weird thing is that I can get his service to work, but when I tried changing my code to match his set-up, I kept getting the same error.
Full source code:
github.com/SabrinaMH/RoundTheClock-Backend/tree/exploring_hosting
When you are getting 'service on Local Computer started and then stopped', generally means there's uncaught exception while starting the service. Take a look at Windows service on Local Computer started and then stopped error, for tips to look for that exception.
Based on what you described, my guess the issue is caused by the Startup class exists on a different project, have you tried to have the startup class within the window service project?
Also, the link from HStackOverflow (https://github.com/danesparza/OWIN-WebAPI-Service), shows a work-around approach to load controllers from different project, or dynamically resolve assembly into the current AppDomain. I guess that's also worth trying.
Hope this helps.
For that example OWIN-WebAPI-Service, you must install Package
Install-Package Microsoft.Owin.Host.HttpListener
Related
I am working with some sort a small RESTful layer to expose (to the internet) the local application data in a host machine.
It behaves like a typical web service that listens incoming request to a port. I wrote it with ASP .NET Core 3.1 with a tiny layer wrapper called Carter, it has also a DLL / COM Reference (used for querying the data).
I followed the following guides to configure it as a windows service, publish the service, and then to create it.
https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-5.0&tabs=visual-studio
https://dotnetcoretutorials.com/2019/12/21/hosting-an-asp-net-core-web-app-as-a-windows-service-in-net-core-3/
I did successfully created a service but it won't start and windows is showing this error dialog.
I am relatively new to .NET development and I am not sure what's wrong here or how to fix this.
Program.cs
namespace Adapter
{
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
public class Program
{
public static void Main(string[] args)
{
var host = Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>())
.Build();
host.Run();
}
}
}
Startup.cs
namespace Adapter
{
public class Startup
{
public Startup()
{
// load the env values during start up
new Env().Load();
}
public void ConfigureServices(IServiceCollection services)
{
// interface binding for dependency injection
services.AddSingleTonServices();
// carter and routing services
services.AddCarter();
services.AddRouting();
services.AddHostedService<Worker>();
}
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseEndpoints(builder => builder.MapCarter());
}
}
}
BTW My project is running correctly when you run or debug it in visual studio.
Any help or idea will be much appreciated.
Error 1053: The service did not respond to the start or control request in a timely fashion is the problem caused by the timeout after the particular request.
This error has many variants.You can read this article to try to solve:
[Fix] Error 1053: The service did not respond to the start or control request in a timely fashion
Alternatively, to resolve this issue, you can download the following registry fix for your operating system:
Windows Search “Error 1053” Fix for Windows 7
Windows Search “Error 1053” Fix for Windows 8.1
Windows Search “Error 1053” Fix for Windows 10
I want to be able to use the TopShelf debugging abilities of my service in Visual Studio.
A lot of the examples and documentation out there refer to creating a Windows Console project in Visual Studio first, and then adding TopShelf, OWIN, etc
However, in my case I already have a perfectly good and working Windows Service project called QShipsService.sln, etc... and it uses a simple Connected Service (admittedly to old SOAP legacy services).
Can someone please direct me or provide an example of how to use TopShelf, with an existing non-Console like project?
I found my own solution...
The assumption I made was the default Windows Service project defaulting to wanting to register the program as a service and kick off the OnOpen() and OnClose() methods, once the service is running.
In my case I wanted to re-use an existing service that was based on a Timer(), and it would kick in every 4 hours to call a SOAP call and return some data. What I didn't realise was the ServiceConfigurator was trying to call its own Open() and Close() methods.
So I commented out the OnOpen and OnClose methods and allowed the configurator to call my worker process via Open() method instead, which is what I was meant to have done the first time!
For the noobs out there like me, here is the code...
//using System.ServiceProcess;
using Topshelf;
namespace QShipsService
{
static class Program
{
static void Main(string[] args)
{
HostFactory.Run(
configure =>
{
configure.Service<QShipsService.QshipsService>(
service =>
{
service.ConstructUsing(s => new QShipsService.QshipsService());
service.WhenStarted(s => s.QStart());
service.WhenStopped(s => s.QStop());
});
//Setup Account that window service use to run.
configure.RunAsLocalSystem();
//add details and names about the service
configure.SetServiceName("QshipsService");
configure.SetDisplayName("QshipsService");
configure.SetDescription("QshipsService Windows Service to extract data from the QSHIPS SOAP service. Data is recorded and maintained inside the SPOT's database in POT-DB.");
});
//## USE THIS IF WE'RE NOT USING TOPSHELF !! ##
// //this loads and starts the QshipsService (see QshipsService.cs program)
// ServiceBase[] ServicesToRun;
// ServicesToRun = new ServiceBase[]
// {
// new QShipsService.QshipsService()
// };
// ServiceBase.Run(ServicesToRun);
}
}
}
I'm learning SF, and am now trying to build a console client to a stateless service.
tried to follow instructions here: https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-connect-and-communicate-with-services
and added this to my StatelessService class
public interface IMyService : IService
{
Task<string> HelloWorldAsync();
}
and a simple implementation
public Task<string> HelloWorldAsync()
{
return Task.FromResult("HELLO FROM SERVICE!");
}
The rest is unchanged.
In my Console app I have
IMyService helloWorldClient = ServiceProxy.Create<IMyService>(
new Uri("fabric:/RestGateway/StatelessGateway1"));
string message = await helloWorldClient.HelloWorldAsync();
The service deployed to my local cluster and seems to work fine (green button) but I get an Exception when calling helloWorldClient.HelloWorldAsync().
Any idea how I can fix this?
Don't forget to add a communication listener to your service like this:
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
yield return new ServiceInstanceListener(ServiceRemotingExtensions.CreateServiceRemotingListener(this, Context));
}
Note:
The call to CreateServiceRemotingListener creates a specific communication listener that can be used only from within the cluster. So, when talking from your dev machine to a service running on your dev cluster this will work. You can't talk to services running on different machines like this.
To access your cluster from the outside, you could use ServiceBus, WCF or OWIN for instance. (or something you build yourself)
I am working on an asp.net MVC-5 web project where i have to send daily email to all users. And i know there are 2 ways to achieve this:
Windows service
Sql server agent job.
I have decided to use Windows service. I am working on Express Version of Visual Studio 2013 for Web, so Windows service template is not present in it. After digging a lot i have created a windows service as console application in Visual Studio. Here's the code:
Service
public class FirstService : ServiceBase
{
public FirstService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
this.EventLog.WriteEntry("FirstService Service Has Started");
}
protected override void OnStop()
{
this.EventLog.WriteEntry("FirstService Service Has Stopped");
}
private void InitializeComponent()
{
this.ServiceName = "FirstService";
this.CanStop = true;
this.AutoLog = false;
this.EventLog.Log = "Application";
this.EventLog.Source = "FirstService";
}
}
Installer
[RunInstaller(true)]
public class MyServiceInstaller : Installer
{
private ServiceProcessInstaller FirstServiceProcessInstaller;
private ServiceInstaller FirstServiceInstaller;
public MyServiceInstaller()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.FirstServiceProcessInstaller = new ServiceProcessInstaller();
this.FirstServiceProcessInstaller.Account = ServiceAccount.LocalSystem;
this.FirstServiceProcessInstaller.Username = null;
this.FirstServiceProcessInstaller.Password = null;
this.FirstServiceInstaller = new ServiceInstaller();
this.FirstServiceInstaller.Description = "FirstService Service Template";
this.FirstServiceInstaller.DisplayName = "First Service";
this.FirstServiceInstaller.ServiceName = "FirstService";
this.FirstServiceInstaller.StartType = ServiceStartMode.Manual;
this.Installers.AddRange(new Installer[] { this.FirstServiceProcessInstaller, this.FirstServiceInstaller });
}
}
Main
static class Program
{
[STAThread]
static void Main()
{
ServiceBase.Run(new FirstService());
}
}
After this i have successfully installed this service using installutil.exe and can successfully start and stop service from Control Panel -> Administrative Tools -> Serivces.
Upto this everything is good.
Now as i mention earlier i want to use windows service in my mvc-5 application for sending automatic email to my application users, i have some questions:
How i will integrate Windows Service in my asp.net mvc-5 application?
How i will deploy the application to the server?
How i will install the windows service on my application hosting server?
Please suggest me any good tutorial which contains the example, if possible.
Thanks!
Let me suggest two more options:
Create a console application and use Task Scheduler to invoke it at a given time. This option is really simple.
Use Quartz.net. This option may be valid in case you are using a shared host environment.
I don´t understand what you mean by integrating windows service in your mvc application.
They are two different processes, so you need to implement any sort of communication between processes (e.g. through database, file, messaging, etc).
You can invoke a controller action using HTTPWebRequest / WebClient class, the controller action will send the mails to users.
2 & 3 : You need to follow the same steps as you did in the local development system.
Hope it helps
I have got few questions regarding creating windows service.
I have created a windows service.But Im getting an error reagrding that.
public partial class xyz : servicebase
{
public xyz()
{
InitializeCompoenent();
}
}
it couldn't resolve InitializeComponent().Does anybody any reason.
I have set it up out as console application instead of windows application.
You used the console application template? That's not right you would have to do allot of manual work like creating the InitializeComponent() method. The best solution is to create a new project using the Windows Service application template. For complete instructions see http://msdn.microsoft.com/en-us/library/zt39148a.aspx
On your project select Add->New item->Windows Service. Give a name to your service.
Now, imports the necessary code you were using from your console file (I'm guessing from the lack of information) to the service file.
So, now you will have a valid window service component in your project. You can remove the old console file.
Don't forget to modify the code in the main in Program.cs:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new YourService();
};
ServiceBase.Run(ServicesToRun);
}
}
If you want to run from the command-line for debugging purposes then check this out this answer.