c# ManagedInstallerClass.InstallHelper blocks service executable - c#

I am trying to do some kind of Installer where i need to install a WinService.
What I currently do is adding the Service.exe as Resource to my Installer Project, then write all bytes of it to a specific folder.
After successfully writing the file to a specified folder, i install the service using ManagedInstallerClass.InstallHelper
The problem i've with it now is that the ManagedInstallerClass.InstallHelper is somehow locking the Service executable, so i cannot delete/overwrite the file (from outside or inside the program), because it's blocked while the Installer Application is running, beginning from first ManagedInstallerClass.InstallHelper call on the Service file.
Here is my code which causes this problem.
private void button1_Click(object sender, EventArgs e)
{
try
{
UninstallAndStopServiceIfExist("RDPBFP_Service");
}
catch (Exception)
{
MessageBox.Show("Service not running, so cannot stop it!");
}
Thread.Sleep(1000);
//File.Delete(#"C:\RDPBFP\RDP-Bruteforce-Protector_Service.exe");
Directory.CreateDirectory(#"C:\RDPBFP");
File.WriteAllBytes(#"C:\RDPBFP\RDPBFP_Service.exe", Properties.Resources.RDPBFP_Service);
try
{
ManagedInstallerClass.InstallHelper(new string[] { #"C:\RDPBFP\RDPBFP_Service.exe" });
}
catch (Exception i_ex)
{
MessageBox.Show(i_ex.Message);
}
//StartService("RDPBFP_Service");
}
So it works fine at first time running it, but second time running it crashes at File.WriteAllBytes.
The service is not running, Windows clearly tells me it's used by my Installer Application when trying to delete it from Windows Explorer.
I'd really appreciate an beginner(which i am) friendly explanation why this happens the way i do it and in best case a solution. I found this post but this did not worked for me.
Thanks in advice.
PS: I know there are Setup Projects and more convenient/professional things, but thats not what i need/want

Well i am now installing it via cmd Process and sc create, still wonder why the InstallHelper wont release the file after installed successfully

Related

Windows services don't work on server but work local after DLL update

I have an problem with update Windows Services that running in server. I change only DLL but when i want to start it server just crash with error 1053. Event Viewer in windows show some more error :
Exception Info: System.TypeInitializationException.
I was almost sure that i just do something wrong in my code but to be sure i run this service local ( on my own laptop ) and there is no any issue service start proper. On server i have same DLL as local ( copy paste ). Have You any idea how to resolve this issue ? I need end this server fast.
private static void Main()
{
try
{
var dlls = new string[] { "Service.DataAccess", "SomeDll.Info", "SomeDll.Detail", "SomeDll.Some" };
new AssemblyLoader(dlls).Load();
XmlConfigurator.Configure();
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[] {new Service_SRV()};
ServiceBase.Run(ServicesToRun);
}
catch(Exception e)
{
RecordError(e);
throw;
}
}
I just change DLL name but there are proper no type errors. At end i want to add that i read this topic : Error 1053: the service did not respond to the start or control request in a timely fashion
Nothing helped, it's still working on the local computer, but not on the server. What sort of problem might make that local it work and on server not ?
Check whether you have mentioned any file paths in app.config file or any hardcoded file paths in your code.
If that is the case, you may need to update the path the server machine.
Did you add your new DLL to the GAC?
Otherwise your dll neeed to be in the same directory as your console application.
Maybe in a subfolder named bin.
Also, did you compile for the same version of the framework? Does the used framework exist on the server?

Windows Service not working when installed, works fine in Debug mode; crashes on Moving/deleting files

I created a windows service which watches a directory. When a file is dumped into it, it takes the data and puts it into a database. Then this file is moved to another directory and deleted. It works fine in debug mode. But when i install it on my computer it stops after throwing the data into the database and the file in question is neither moved or deleted. I suspect a permission issue is involved. I tried to create a event log:
public Service1()
{
InitializeComponent();
if (!System.Diagnostics.EventLog.SourceExists("MySource"))
{
System.Diagnostics.EventLog.CreateEventSource(
"MySource", "MyNewLog");
}
eventLog1.Source = "MySource";
eventLog1.Log = "MyNewLog";
}
So i have three questions.
(1) What could be causing my service to work as described in debug but fail when installed on my computer.(2) I have initiated a event log as shown above. But do i need to add other code to record the event of my service stopping. I presume this would be done in a 'override onShutdown' method.(3) Finally when my service stops, i want to look at the event log. But i do not know how to do this, is in administrative tools? stored as a file on some directory?
Here is edit to this post in lieu of the grateful advice given below.
try
{
File.Move(e.FullPath, finalString);
File.Delete(e.FullPath);
}
catch(Exception q)
{
EventLog.WriteEntry("MySource", q.ToString(), EventLogEntryType.Error);
using (StreamWriter w = new StreamWriter(ConfigurationManager.AppSettings["fmd"], true))
{
w.Write(DateTime.Now.ToString("dd-MM-yyyy_hh-mm-ss"));
w.Write(q.ToString());
}
}
As per suggestion i put a try-catch around the file move and delete plus i added a OnShutdown method:
protected override void OnShutdown()
{
using (StreamWriter w = new StreamWriter(ConfigurationManager.AppSettings["ond"], true))
{
w.Write("stop OnShutdown");
}
//EventLog.WriteEntry("MySource", message, EventLogEntryType.Error);
}
I do not know how to pass any system error message to the shutdown method, so any advice appreciated. When i installed my modified code as a service, it again stopped before moving or deleting the files. Neither of my two logs accessed by a stream recorded anything. Plus the event viewer showed nothing either?
You can write as following,
if (!EventLog.SourceExists("MySource"))
EventLog.CreateEventSource("MySource", "Application");
EventLog.WriteEntry("MySource", message, EventLogEntryType.Error);
to view the event log messages, Goto Administrator Tools -> Event Viewer and look for the source you have created. or Just simply type eventvwr in run window.
When Services installed, it works under SYSTEM User account where service might not have access to some resources. Please put logs and see where exactly the issue is.
If you service installed in your development machine, use attach to process option under DEBUG Menu in Visual Studio to find out.
What could be causing my service to work as described in debug but fail when installed on my computer?
Permissions. The service is likely running under LocalSystem or Network Service if you didn't provide a different identity.
I have initiated a event log as shown above. But do i need to add other code to record the event of my service stopping. I presume this would be done in a 'override onShutdown' method?
Yes, you're assumption is correct.
Finally when my service stops, i want to look at the event log. But i do not know how to do this, is in administrative tools?
Just hit Windows Key+R to get the Run dialog and type eventvwr.
Well i found the reason for all the commotion. I eventually found some logs in the event viewer. They were listed in Administrative events in custom logs. There were three error logs: .Net runtime; Application error & Service Control Manager. In '.Net Runtime' the stack showed a unhandled exception for system.windows.forms. I stupidly included a pop up box in my release version. But even when i commented this away; i got a error. So i went back and found other message boxes, primarily in try catch statements. Removed these and solved the issue.

Not able to run the .exe file created from c#

I have created a Windows form application using C# in visual studio 2010 connecting the database in SQL server . After all my development is done i copy the exe file generated in my machine and pasted in another machine and try to execute it but it is not working .
i can see the process started in task manager but it was closed after 5 seconds . I even tried creating the setup for this application and installed in that machine still i am facing the same issue .
But in my machine it is working perfectly in the both the ways . can any one help me in finding where i went wrong .
Thanks in advance
As you don't provide the error, the answers and comments you are getting are educated guesses.
You should check the event viewer for errors...
This will let you learn what is going on. If you can't fix it, add this info to your question.
As you are not posting exception message, probably you re not properly catching exceptions. Just to be sure surround your main function in a Try/Catch.
In Catch, write some code to dump message exception into a file, or even better use Log4Net. For simplicity just add some code to write to a file now. Something like:
static void Main()
{
try
{
//Your code
}
catch (Exception ex)
{
//Write ex.Message to a file
using (StreamWriter outfile = new StreamWriter(#".\error.txt"))
{
outfile.Write(ex.Message.ToString());
}
}
}
PS: If it is a console application you can survive with Console.Write
Perhaps you have some referenced assemblies that you did not copy along with the application itself.
OR, the connection string is not valid when run from that other machine (if you worked with a local SQL db, or on a network or whatever and it's not accesible on that other machine)
OR, you don't have rights to run it on that other machine.

I have a simple c# executable on a network drive that I update daily, but can't if people leave it running/open on their machine

What is the easiest way to make it so people can run it locally instead of a shortcut pointing to the network drive?
I figure have them run it locally always, and have it check for updates on startup, maybe create a text document (on the network drive w/ the executable) with the latest version number in it that I update with each version, and it reads it w/ streamread on application startup, and if the latest version number was greater than the executable running, it would prompt a message dialogue, and ask to update to latest version and if yes, it would copy it off the network drive...I am not sure how to make it copy the latest version and overwrite itself while the application is running, without making a separate executable...I just want to keep it very simple and I feel like there must be a way.
In a failed attampt, I created a filewatch that monitored the directory of the network drive, and when a file was inserted w/ the file name "terminate" it would close the instance of the program on all running machines and let me update the file :) ...Network security however would not allow this function to run, and it would get an error on startup unless the program was run locally, which deletes the whole purpose of allowing people to keep a shortcut on their desktop pointing to the file.
Edit, for now I thought it would be fun to have a timer and have it shutdown every night at 7:00 PM. Any time after that is when I work on it 90% of the time.
private void Form1_Load(object sender, EventArgs e)
{
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.timer1.Interval = 30000;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
this.timer1.Start();
}
private void timer1_Tick(object sender, System.EventArgs e)
{
DateTime t1 = Convert.ToDateTime(DateTime.Now.ToShortTimeString());
DateTime t2 = Convert.ToDateTime(("7:00 PM"));
if (t1.TimeOfDay.Ticks == t2.TimeOfDay.Ticks)
{
this.Close();
// /DateTime.Now.ToShortTimeString();
}
The easiest way to get this onto people's machines is potentially an xcopy deployment and a shortcut created using a log-in script? This would be a network admin task.
Alternatively, ClickOnce deploy it. This will be hosted in a web page and handles application updates. It's also easy to install.
It will not be able to update itself, as you say, the process will lock the file. If you choose to do this manually, you will need a surrogate executable to handle the update. Paint.NET does this when it updates itself.
To the user, the existence of this exe can be kept silent - you could hold it as a resource of the main exe and write it out to file only during updates. After an update, the update exe could be deleted by the main exe again.
I would think you might want to deploy an application that copies the "latest" version of the executable to the local machine and then launches it locally.
so basically a little batch
cp <path/to/remote> <path/to/local>
<path/to/local>
Have them run that one their local machines rather than running the exe from the network drive.
You will simply have to update the network drive. The next time they run the app, it'll get the latest version and then locally run it.

Installing a Windows Service from a separate GUI - how to install .config file along with it?

I have written a GUI (call it MyGUI) for ClickOnce deployment on any given client site. That GUI installs and configures a Windows Service (MyService), using the method described here by #Marc Gravell. Here's my code, run from inside MyGUI, which contains a reference to MyService:
using (var inst = new AssemblyInstaller(typeof(MyService.Program).Assembly, new string[] { })) {
IDictionary state = new Hashtable();
inst.UseNewContext = true;
try {
if (uninstall) {
inst.Uninstall(state);
} else {
inst.Install(state);
inst.Commit(state);
}
} catch {
try {
inst.Rollback(state);
} catch { }
throw;
}
}
Take note of that first line: I'm grabbing the assembly for MyService, and installing that. Now, trouble is, the way I've done the deployment, I'm effectively referencing the service's EXE file from the GUI's app folder. So now the service fires up and starts looking for stuff in the MyService.config file, and can't find it, because it's living in someone else's app folder, with only the GUI's MyGUI.config file present.
So, how do I get MyService.config to be available to the service?
Ah well, my first attempt at testing the ClickOnce deployment told me that ClickOnce apps cannot be run as Admin, which means I also can't install any Windows Services. So I guess with this answer I've kind of un-asked the question... and I have to re-think my architecture... (sigh)...

Categories

Resources