Call Web Services from Windows Service - c#

I created a Web Service where I take data from a database and insert
them into a list of string type. This web service is called from a
Windows Service that receives the list and retrieving the data. To do
this I added the reference to the Windows Service, but I do not know
if I get the list from the Web Service correctly. This is the code of
the windows service:
RicDati ricdati = new RicDati();
var listas = ricdati.PrelevaDati().Count();
List<string> lista = new List<string>();
lista.AddRange(ricdati.PrelevaDati());
RicDati is the class of the Web Service, PrelevaDati is the name of the method

I think is more a matter of debugging your windows service, sometimes this could be very difficult but ic an suggest a workarround.
Practically you need to create a console application or windows that practically is going to create and call a windows service instance without even intall it on your computar, this practically feels like you're debugging a normal windows application.
this is a project that uses a winform to debug win services I'm more into a consolo (because I feel it's easier), but the concept is the same so you can take a look.
enter link description here
the main code practically is the following:
using System.ServiceProcess;
using ServiceProcess.Helpers;
namespace DemoService
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
//ServiceBase.Run(ServicesToRun);
ServicesToRun.LoadServices();
}
}
}

Before running it in a Service, run/debug the parts which are not service related in a console application.
Create a library project of your business processes which the service will use, but also the console application. This will contain the call to the webservices.
Test the process in the console without having the unknowns of a service.
Once the processes are working then run it in the service.

Related

C# Windows service won't start: "Cannot start service from command line or debugger"

Even though there are similar questions, I couldn't find any that solves mine. I have a simple program that runs as a service and I want to start it programatically. It's as simple as this:
private static void StartService()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new MyService()
};
ServiceBase.Run(ServicesToRun);
}
As expected, I can't just start my service without installing it. Windows gives me the following error message:
Cannot start service from command line or debugger. A windows service must first be installed using installutil.exe and then started with service explorer, Windows services administrative tool or NET start.
So far so good. So I went there and did just as the docs says:
installutil <my_project>.exe
The installation was successful and I can even start my service from Service Manager or net start. The only problem is: when I debug my application (via F5), Windows keeps showing me the exact same message: Cannot start service (...).
I've found a solution here that uses this:
public void onDebug()
{
OnStart(null);
}
Which allows me to run and debug my application normally, but I actually need it to run as a service and Windows refuses to start that way. Is there anything I'm missing?
It is not in your power to just start a Service like a normal programm. The Service must be registered with and started by the Service manager. That is one of the (many) rules of Windows services. And you have to repeat that for every new build.
As this and other Service related rules (no interactive sessions) can make developing them a Pain, a common approach is to develop them using a console application. I could not find my ideal example, but I found something like it:
https://alastaircrabtree.com/how-to-run-a-dotnet-windows-service-as-a-console-app/
Of course a better longterm plan might be to stop using Services alltogether and switch over to the Windows Task Scheduler. It depends heavily on what exactly you need this code to be able to do in practice.

How to integrate topshelf to an existing windows service project?

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);
}
}
}

Multiple service processes (System.ServiceProcess.ServiceBase) in one Windows Service

I've got two service processes (derived from System.ServiceProcess.ServiceBase)
MyService1 and MyService2.
I'm trying to run them both in the Main() of a Windows Service's Programm.cs.
static void Main()
{
ServiceBase[] servicesToRun = { new MyService1(), new MyService2() };
ServiceBase.Run(servicesToRun);
}
In the OnStart methods of both MyService1 and MyService2 I write to a log file so I can tell they are running.
The system builds fine and I can install the service.
But only MyService1 runs. MyService2 doesn't do a thing (i.e. no start-up log entry). When I change the order in the array:
ServiceBase[] servicesToRun = { new MyService2(), new MyService1() }
only MyService2 runs.
To try to get to the bottom of this, I'm using a little tool AndersonImes.ServiceProcess.ServicesLoader (https://windowsservicehelper.codeplex.com/) to get around the limitation that you cannot directly debug a windows service in Visual Studio. With this tool I can get both services MyService1 and MyService2 to start and run next to each other. But I still don't know why Windows is running only the first item in the ServiceBase[] servicesToRun array.
Any ideas?
I finally found the answer here: http://www.bryancook.net/2008/04/running-multiple-net-services-within.html. A well hidden resource, thanks 'bryan'! Hopefully this helps the next developer to save time...
The explanation there around ServicesDependedOn isn't quite matching what I see in my project though. It's not about starting them but making sure they are started. Check out https://msdn.microsoft.com/en-us/library/system.serviceprocess.servicecontroller.servicesdependedon%28v=vs.110%29.aspx as well. I don't need this because they do not depend on each other.

Running Windows Service Application without installing it

Whem I'm writing a Windows Service and just hit F5 I get the error message that I have to install it using installutil.exe and then run it.
In practice this means everytime I change a line of code:
compile
switch to Developer Command Prompt
remove old version
install new version
start service
That is very inconvenient. Is there a better way to do it?
The best way in my opinion is to use Debug directive. Below is an example for the same.
#if(!DEBUG)
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
// Calling MyService Constructor
new MyService()
};
ServiceBase.Run(ServicesToRun);
#else
MyService serviceCall = new MyService();
serviceCall.YourMethodContainingLogic();
#endif
Hit F5 And set a Breakpoint on your YourMethodContainingLogic Method to debug it.
I usually put the bulk of the service implementation into a class library, and then create two "front-ends" for running it - one a service project, the other a console or windows forms application. I use the console/forms application for debugging.
However, you should be aware of the differences in the environment between the debug experience and when running as a genuine service - e.g. you can accidentally end up dependent on running in a session with an interactive user, or (for winforms) where a message pump is running.
You can write this code in program.cs
//if not in Debug
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new MyService()
};
ServiceBase.Run(ServicesToRun);
//if debug mode
MyService service = new MyService();
service.OnDebug();
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
in MyService class
public void OnDebug()
{
OnStart(null);
}
You cannot run Windows Service as say another console or WinForms application. It needs to be started by Windows itself.
If you don't have infrastructure ready to use as #Damien_The_Unbeliever suggests (which is what I recommend as well) you can install the service from the debug location. So you use installutil once and point it to executable located in /bin/debug. Then you start a service from services.msc and use Visual Studio > Debug > Attach to Process menu and attach to the Windows service.
You can also consider using Thread.Sleep(10000) as the first line in the OnStart call, or Debugger.Break() to help you out to be able to attach before the service executes any work. Don't forget to remove those before the release.
You can use Environment.UserInteractive variable. Details of implementation here
Here's an easy way I use to debug Windows service applications without installing them, starting via Windows Service Control Manager, attaching to debuggers, etc. The following is in VB but hopefully you get the idea.
In this example, TestService's main class is named svcTest.vb.
Within Shared Sub Main() inside svcTest.Designer.vb, the default code looks something like this:
Dim ServicesToRun() As System.ServiceProcess.ServiceBase
ServicesToRun = New System.ServiceProcess.ServiceBase() {New svcTest}
System.ServiceProcess.ServiceBase.Run(ServicesToRun)
Comment everything out within Main() and add the following 2 lines of code.
Dim objSvc As New svcTest()
objSvc.OnStart(Nothing)
Now just set a breakpoint where you want to start debugging, hit F11 to step into the code, and then proceed as normal as if you were working with a standard desktop application. When you're finished debugging, simply reverse the changes made within Main().
This was done using Visual Studio Enterprise 2017 on Windows Server 2012 R2.

Question regarding creating windows service

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.

Categories