how can i generate exe from windows service file - c#

I had created a Lib Project with a class inherits ServiceBase but when I run the solution i'm not getting the EXE file?
public class Scheduler : ServiceBase
{
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[] {new Scheduler()};
Run(ServicesToRun);
}
}

First, make sure that your project type is Windows Application, which is recommended for windows services.
What you did is not enough in order to install and start your service. You cannot yet install your service. You have to provide an installer class which can then be used by InstallUtil to register your service.
You can see an example of this in the ServiceProcessInstaller class documentation.
After that, build your service again and install it by running in a command window the following:
"%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe" "YourServiceExeName.exe"
You will then be able to see your service in the services snap-in.

Why not creating a project of type Windows Service ? and the installation part is already mentioned by the coon, but you need all the service exe path, not juste the service name.
Good luck

Related

.NET Framework 4.8 Environment.UserInteractive always returns true regardless if it was started in a service or not

I'm writing a program that can be ran as both a console app and as a service. Right now, it's basically:
static void Main(string[] args)
{
if (Environment.UserInteractive)
{
// Console App
// contains code that causes an error when ran as a service
}
else
{
var servicesToRun = new ServiceBase[]
{
new HostManagerService(logger)
};
ServiceBase.Run(servicesToRun);
}
}
However, the Environment.UserInteractive always returns true. I know that this is true because when I try to run the program as a service, I run into an error because this runs the console app version of the code instead of the service version. Does anyone know why this could be the case?
EDIT: To run it as a service, I find the .exe file and run, "myprogram.exe -i" in my command prompt to install the .exe as a service and then in the Services window, I right click and press start (with Allow service to interact with desktop disabled).

Cannot Start the C# application in visual Studio 12 [duplicate]

I want to debug a Windows service but it pops an error message saying
Cannot start service from the command
line or a debugger. A windows service
must be installed using
installutil.exe and then started with
the Server explorer, windows services
Administrative tools or the NET start
command.
I don't really have any idea about this error.....
Before a Windows Service can run, it has to be "installed" first using installutil. EG:
C:\installutil -i c:\path\to\project\debug\service.exe
Then you can open up the list of Services to start it. EG:
Right click 'My Computer'
Click on 'Manage'
Open up 'Services and Applications'
Click on 'Services'
Find your service in the list and right-click on it
Click on 'Start'
Once it has started, you can go into Visual Studio, click on 'Debug', then click on 'Attach to Process'.
Another technique is to add this line to your OnStart() method in the service:
System.Diagnostics.Debugger.Launch();
When you do that, it'll prompt you to pick an instance of Visual Studio to debug the service in.
You can alter the assembly's startup mode based on whether you're in DEBUG mode (usually inside Visual Studio but not necessarily) or RELEASE mode (when it runs as a service in production):
Change this:
static class Program
{
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new MyService()
};
ServiceBase.Run(ServicesToRun);
}
}
to that:
static class Program
{
static void Main()
{
#if(!DEBUG)
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new MyService()
};
ServiceBase.Run(ServicesToRun);
#else
MyService myServ = new MyService();
myServ.Process();
// here Process is my Service function
// that will run when my service onstart is call
// you need to call your own method or function name here instead of Process();
#endif
}
}
The technique is taken from this article and the credit is for the article's author, Tejas Vaishnav. I copied the code fragments here because SO favors full answers rather than links that might disappear some time.
To prevent this error occurring and allow the service to run outside of the usual service controller you can check the Environment.UserInteractive flag. If it is set you can run the service with output to the console instead of letting it run to the ServiceBase code that returns that error.
Add this to the start of Program.Main(), before the code that uses ServiceBase to run the service:
if (Environment.UserInteractive)
{
var service = new WindowsService();
service.TestInConsole(args);
return;
}
As the OnStart and OnStop methods are protected in your service you need to add another method to that class which you can run from Main() and calls those methods for you, such as:
public void TestInConsole(string[] args)
{
Console.WriteLine($"Service starting...");
this.OnStart(args);
Console.WriteLine($"Service started. Press any key to stop.");
Console.ReadKey();
Console.WriteLine($"Service stopping...");
this.OnStop();
Console.WriteLine($"Service stopped. Closing in 5 seconds.");
System.Threading.Thread.Sleep(5000);
}
Finally, make sure the output is a console application in the project's properties.
You can now run the service executable like any other and it will start as a console. If you start it from Visual Studio the debugger will attach automatically. If you register it and start it as a service it will run properly as a service without any changes.
The only difference I've found is that when running as a console application the code does not write to the event log, you might want to output anything you would normally log there to the console as well.
This service debugging technique is one of those explained on learn.microsoft.com
There is a nuget package made to solve this problem: install-package WindowsService.Gui
What does the package do?
It helps by creating a Play/Stop/Pause UI when running with a debugger attached, but also allows the windows service to be installed and run by the Windows Services environment as well. All this with one line of code! What is Service Helper Being someone who writes Windows Services a lot, it can be frustrating to deal with the headaches involved in debugging services. Often it involves tricks, hacks, and partial workarounds to test all of your code. There is no "just hit F5" experience for Windows Services developers.
Service Helper solves this by triggering a UI to be shown if a debugger is attached that simulates (as closely as possible) the Windows Services Environment.
The github project is here: https://github.com/wolfen351/windows-service-gui
How to use?
The easiest way to get Windows Service Helper in your project is to use the NuGet package ServiceProcess.Helpers on the NuGet official feed.
Simply make a few changes to the typical code in the "Program.cs" for your application:
using System.ServiceProcess;
using ServiceProcess.Helpers; //HERE
namespace DemoService
{
static class Program
{
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
//ServiceBase.Run(ServicesToRun);
ServicesToRun.LoadServices(); //AND HERE
}
}
}
Disclosure: I'm the maintainer of this project
Note: The UI is optional
Another reason can be that the solution configuration is in Release mode in place of Debug mode
Please check if you are in "DEBUG" or "RELEASE" mode. I got this error when I was trying to debug the service in "RELEASE" mode. When I changed that to "DEBUG", everything worked fine.
This is after you have correctly installed the service as suggested by other people above.

Log4net works for a console app but not a windows service

I am having an issue with log4net. I am working on a service application which I have been developing as a console app with DLL's. The dll's are self contained and the console app just calls a start method on the service to allow me to quickly swap out for a windows service for deployment. (don't have rights to install a service on my dev box but have full admin on the server, its a security nightmare where I work so don't ask).
When starting the console app on the server log4net functions just fine. When starting the windows service I get this error in the log4net log:
log4net: repository [log4net-default-repository] already exists, using repository type [log4net.Repository.Hierarchy.Hierarchy]
no configuration section <common/logging> found - suppressing logging output
I am also using quartz in another part of the project so Common.Logging.dll is in the folder but adding the config sections for Common.Logging to use log4net did not fix the issue. From what I can see the only difference between the console app and service is the output type. Both the console app and the service have the same packages.config whicn only include log4net and the same references which only reference the log4net dll and the main project dll.
Any help tracking down where to look would be greatly appreciated.
EDIT: I am using the same app.config for both the console app and the windows service named the proper program.exe.config.
So after trying several things I replaced the Windows Service template project with a standard console app. Using the code from here https://stackoverflow.com/a/7764451/3302585
(Copied in case the link dies)
public static class Program
{
#region Nested classes to support running as service
public const string ServiceName = "MyService";
public class Service : ServiceBase
{
public Service()
{
ServiceName = Program.ServiceName;
}
protected override void OnStart(string[] args)
{
Program.Start(args);
}
protected override void OnStop()
{
Program.Stop();
}
}
#endregion
static void Main(string[] args)
{
if (!Environment.UserInteractive)
// running as service
using (var service = new Service())
ServiceBase.Run(service);
else
{
// running as console app
Start(args);
Console.WriteLine("Press any key to stop...");
Console.ReadKey(true);
Stop();
}
}
private static void Start(string[] args)
{
// onstart code here
}
private static void Stop()
{
// onstop code here
}
}
and adding a service installer (http://msdn.microsoft.com/en-us/library/system.serviceprocess.serviceinstaller.aspx to understand what was going on then copying the Initialize Component code from the Windows Service Template project for the service installer) the project now runs as expected.
I am still not sure what is happening as the code appears 98% the same but if I had to guess it would be some sort of difference that is not obvious to a beginner to the differences between the Console App template and the Windows service template.

Service did not start within a timely fashion - c# windows service

I have a Windows service which I can install on my local machine using installutil no problem.
Now, this service has to be installed on a server. I copy all files to the server and run the same command, set the service to log on as a local user account and when the service starts I get an error saying "logon failed" - okay so perhaps the user account is the issue.
So I change the service log on as to local system account. I start the service and I am told "The service did not respond to the start or control request in a timely fashion".
So I googled and tried various solutions but to no avail. So I got to thinking maybe it was something in the OnStart method which broke (even though I have logging calls which never logged). So I removed all code from the OnStart event and still the service would not start, I got the "timely fashion" error.
So where am I at? I believe it could be due to the references I have defined in the project. To test this I created a new Windows service template from VS2012 with no references (other than the default ones) and I can start the service. No issues.
So my question is what could be causing this? In my project the references point to locations which do not exist on the server, however the directory where the service resides has all the referenced DLLs.
Edit:
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
namespace RetrieveAndProcessSecurityLogs
{
static class Program
{
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new LogService()
};
ServiceBase.Run(ServicesToRun);
}
}
}
LogService.cs
public partial class LogService : ServiceBase
{
public LogService()
{
InitializeComponent();
this.ServiceName = "Retrieve and Process Security Logs";
this.CanPauseAndContinue = true;
this.CanStop = true;
}
protected override void OnStart(string[] args)
{
//...
}
protected override void OnStop()
{
//...
}
Edit: The installed .NET version on the server is v4.0, however in the app config file for the project there is this line:
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
Could the 4.5 part be the issue?
Edit2: Bottom line: if I reference a DLL, I get the timely fashion error. If I have no extra DLL reference defined the service starts.
Sorry for the story.
Andrew
For future reference to anyone who encounters this issue, the issue was one of the references was built against .NET FW 4.5 and on the server where the service was being installed had .NET FW 4. My machine had 4.5.

Installing .net windows service with lib folder

I would like to create a setup for my windows service.
The dlls of my windows service are placed in /Lib/ folder.
I added an installer class to the service.
And added a custom action on the setup project.
The problem is that when I try to install the service - it fails with the error:
Error 1001. Unable to get installer types in ...
This error happens because the dlls are not in the same directory as the service .exe.
I am using probing in the service config and install util doesn't recognize that probing..
I wanted to find a work around for that problem and tryed in many ways to create
the service using service controller(sc.exe). Trying to run it as a custom action using cmd.exe.
Etc..
This should be a common problem..did anybody find a proper solution for that?
I've had the same problem, and none of the options suggested in this post or MSDN helped. I figured another solution:
By using Reflector on InstallUtil.exe, I discovered that InstallUtil is merely a thin wrapper for calling System.Configuration.Install.ManagedInstallerClass.InstallHelper(args) inside a try/catch block (it also sets the current thread's UI culture and displays the copyright). ManagedInstallerClass.InstallHelper itself resides in the System.Configuration.Install.dll assembly, accessible to everyone.
Thus, I simply modified the Program.Main method of my service to allow installation. See the quick-and-dirty code below:
static class Program
{
static void Main(string[] args)
{
if (args != null && args.Any(arg => arg == "/i" || arg == "/u"))
{
// Install or Uninstall the service (mimic InstallUtil.exe)
System.Configuration.Install.ManagedInstallerClass.InstallHelper(args);
}
else
{
// Run the service
System.ServiceProcess.ServiceBase[] ServicesToRun;
ServicesToRun = new System.ServiceProcess.ServiceBase[]
{
new MyService()
};
System.ServiceProcess.ServiceBase.Run(ServicesToRun);
}
}
}
You can do the same, or create your own version of InstallUtil.
You should bind to the AppDomain.AssemblyResolve event and do your custom loading in the event handler.
A sample can be found in the first answer to this SO question.
in your config you can add probing path - it's a hint to the runtime where to look for an assembly
http://msdn.microsoft.com/en-us/library/823z9h8w%28v=vs.80%29.aspx

Categories

Resources