im trying to figure out how i can get a notification when the state of a Windows Service changes. First i tryied a timer that check the state every view seconds with the ServiceControl.State. I found this "NotifyServiceStatusChange" but no examples or something like that and dont know how to use that.
Or is there a other way?
Background information:
I have an application. The application has 2 buttons. Everytime the state of the service changes one of the buttons should be disabled. Like Service-State running then disable the "Start Service" button.
Have you had a look at the ServiceController Class? Something like this should get you started.
ServiceController sc = new ServiceController("ServiceName");
switch (sc.Status)
{
case ServiceControllerStatus.Running:
break;
case ServiceControllerStatus.Stopped:
break;
case ServiceControllerStatus.Paused:
break;
}
If you would like to avoid constantly polling on a timer, you could have a look at WaitForStatus. Have your background workers always waiting for a specified status to enable buttons, disable buttons or whatever.
This is a very basic example, but to answer your question about infinite loop - no. see my comments and debug step this, you will understand why.
ServiceController sc = new ServiceController("ServiceName");
for (;;)
{
// for pauses execution, waiting for stopped status.
sc.WaitForStatus(ServiceControllerStatus.Stopped);
// continues when stopped status signaled, disable button
// for waiting for running status.
sc.WaitForStatus(ServiceControllerStatus.Running);
//continues when running status signaled, enable button
// for will continue but wait for stopped status signal
}
This is why I recommended doing this check in a background worker or just something off of the main thread so that your entire application does not get jammed up while waiting for status changes.
If I understood it correctly, you have a windows service running in the background and another app that wants to be notified.
If that is the case, you will need to implement some form of communication between them.
Depending on your requirements, and where you are going to run the solution, you can use Message Queue (MSMQ for example) where you can subscribe/broadcast your messages. Another alternative it would be to user some Real Time Communication (like TCP/Socket, signalR or even using firebase to notify your app).
Related
Keep in mind, this is a Console App running .NET with C#. Also, I might later convert this into a service, but for now, I need to handle the shutdown while my Console App is running.
My system sometimes gets shutdown automagically by Windows Updates or by Kace Updates. This is irritating when my program is in the middle of doing long tests in the middle of the night and I'm not there to see it happen. I would like to be able to detect the system shutting down and delay it long enough for my tests to finish gracefully and allow me to gracefully exit my program keeping all my test data intact.
I've looked at various threads and can't seem to find a working solution. I've tried both of these:
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
Application.ApplicationExit += OnApplicationExit;
But neither of these events seem to get fired. I basically want to send an e-mail notification to myself when the shutdown is detected and pause the shutdown. Or at least log a message somehow...
I can simulate this behavior using (of all things) 'notepad.exe'. I just open notepad.exe, type some junk, and then attempt to ShutDown my computer. The computer tries to shutdown, and then shows a message that says it cannot shut down because 'notepad' is blocking it.
I would like MY program to block the shutdown (or at least delay it) the same way as 'notepad.exe' does it.
Any information, events, or other ideas that you may have would be very useful. Thanks in advance for your assistance.
This can help you:
https://www.meziantou.net/prevent-windows-shutdown-or-session-ending-in-dotnet.htm
When the user logs off or when he stops his machine, Windows quits all open applications. Some applications want to execute code before ending in order not to lose the current state (a document being written for example).
For this Windows sends a message to all applications:
WM_QUERYENDSESSION when closing the session
WM_ENDSESSION when shutting down the machine
Windows provides 3 methods:
ShutdownBlockReasonCreate
Indicates that the system cannot be shut down and sets a reason string to be displayed to the user if system shutdown is initiated ("I want to live" in the screenshot)
ShutdownBlockReasonDestroy
Indicates that the system can be shut down
SetProcessShutdownParameters
This function sets a shutdown order for a process relative to the other processes in the system
The final method determines the order in which Windows sends the WM_ENDSESSION and WM_QUERYENDSESSION messages to the applications. This is used in the case where an application A depends on an application B. The application A wishes to be informed before the application B that the machine is stopping to potentially block this stop. Thus application B remains alive as application A blocks the shutdown.
The priority is defined with an integer between 0 and 0x4FF. 0x4FF is the highest priority (called first), 0 is the lowest priority (last called). By default, applications have priority 280.
In the link there is also a code for WinForm that can be adapted.
Something like:
private const int WM_QUERYENDSESSION=0x0011;
private bool isShuttingDown=false;
protected override void WndProc(ref Message m)
{
if(m.Msg==WM_QUERYENDSESSION)
{
isShuttingDown=true;
}
base.WndProc(ref m);
}
I'm working on a web application which has multiple threads running which do stuff with sockets and the file I/O. So in the event of the application shutting down, I first want to finish these threads and clean them up.
I already found the following code, which works great in the event of a gracefull shutdown.
public class Startup
{
public void Configure(IApplicationBuilder app, IApplicationLifetime applicationLifetime)
{
applicationLifetime.ApplicationStopping.Register(OnShutdown);
}
private void OnShutdown()
{
// Do your cleanup here
}
}
But when you have an ungraceful shutdown the OnShutDown() method is not called.
In Forms you can detect all kinds of shutdown reasons with the following code:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
switch (e.CloseReason)
{
case CloseReason.ApplicationExitCall:
// The Exit method of the Application class was called.
break;
case CloseReason.FormOwnerClosing:
// The owner form is closing.
break;
case CloseReason.MdiFormClosing:
// The parent form is closing.
break;
case CloseReason.None:
// Unknown closing reason.
break;
case CloseReason.TaskManagerClosing:
// The application is being closed from the TaskManager.
break;
case CloseReason.UserClosing:
// The user is closing the form through the UI.
break;
case CloseReason.WindowsShutDown:
// Windows is closing the application because it is shutting down.
break;
}
}
Is there anything like this in ASP.Net Core 2.0 to detect any kind of shutdown in stat of only graceful shutdowns?
Event handling is predicated on a successful exit. If you do something like a hard reboot or your application crashes, there's no opportunity to handle anything because it's already gone. That's sort of the point: it was forced to exit, so it can't do anything.
That said, the issue here is either not actually an issue or a design problem. First, if the process exits, the threads go with it. There's nothing to "cleanup". Socket handles and such are just pointers in memory, they too go with the process.
If the process is hanging, that's a different story. In that situation, it can hold on to resources, since it's still technically running. However, then, the true issue is fixing whatever is causing the process to hang, not figuring out how to release resources when it does.
Bear in mind that a web server is designed to quickly respond to incoming requests. It should be an almost instantaneous process. It's not designed to chew on requests for a while, doing a bunch of work. If you need to do things like connect to sockets and such, that should very likely be offloaded into an external process, like a console application, windows service, etc. Then, your web application can simply hand off work to this and move on. You can provide an endpoint to check for status, progress, etc., and use that via SignalR or AJAX long-polling to update the client about the progress of the work/notify them when it's done.
In my ASP MVC 5 app I have this database related operation that I've to perform once in month maybe and it takes about 30 - 60 minutes.
I start this action like this:
Repository dbForCategories = new Repository();
dbForCategories.Database.CommandTimeout = 60000;
var t = Task.Factory.StartNew(async delegate
{
var crs = new ProductCategoryRelationsSetter(dbForCategories, categoryService);
crs.AddProductsCategoriesRelations(oneLineTree);
}, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
After about 5 minutes of working in background Im getting logged out of application. I think that the app resets because some static variables Im using are reset.
In elmah i don't have any errors. I put my code in Try Catch block.
Only hope in you guys:)
As #David mentioned, it's probably best to go the Windows Service route:
Write the item to a database table
Let a Windows Service poll the table every month (or however often you need it to).
If it finds a new item in the queue, let the Windows Service perform the operation.
Why not do Background threads in ASP.NET?
The server may recycle Application pool at some point and will not know to wait for your Task on a separate thread. (Discussed in this SO question)
.NET 4.5.2 onward. You can fire and forget short tasks
For interest sake you can use HostingEnvironment.QueueBackgroundWorkItem (see here) and the server will respect the background item and not recyle the App pool while it's busy, BUT ONLY for up to 90 seconds. anything longer and Windows Service is your best bet.
HostingEnvironment.QueueBackgroundWorkItem(ct => yourAsyncWork(ct));
Hangfire is wonderful for stuff like this.
https://www.nuget.org/packages/Hangfire/
I am using quartz.net as a windows service to schedule my jobs. My jobs are long running and I need to terminate them gracefully if quartz service stops (either someone manually stops/restarts it or windows shutsdown/restarts; it doesn't matter). Is there any Quartz shutdown event which I can handle in my Jobs? Also does Quartz have a startup event which I can handle to set some startup values in my database? I am using c# for my Jobs.
If you get this code-base:
https://github.com/quartznet/quartznet/tree/master/server/Quartz.Server
Alot of the work is already done.
You should debug the code.
But ashga is correct.... IScheduler.Shutdown(true) allows for a graceful shut down. Which means......it will try to finish up any already-running jobs.
If you use Control-Panel to "Stop Service".........it will probably call the graceful method (I'm guessing, I don't know for sure)........so if the graceful-stop ends before the Control-Panel-Service-Shutdown(timeout) occurs....it will go fine.
If the "graceful shutdown" takes longer than the Control-Panel-Service-Shutdown(timeout)....you'll get a windows message akin to "Your service did not shut down in a timely manner".
........
If you're using an in-memory datastore (Quartz.Simpl.RAMJobStore)...there isn't much you can do on a service-restart.
If you're using an ADO net datastore ("Quartz.Impl.AdoJobStore.JobStoreTX")...then there is some "pick up from where I left off" stuff.......that's a deeper issue to look into.
"Misfire" would be one of the terms to look at.
If you un-gracefully-stop with an in-memory datastore (Quartz.Simpl.RAMJobStore).....it's basically the same as if you turned the power off on your computer........when it starts again, it won't know about any "state".
Have you tried calling IScheduler.Shutdown(true) when your application shuts down?
should allow a graceful shutdown :)
In my windows phone7(Silverlight) Application I have to display a message box asking, the user to confirm(Yes/No) before exit from the application [on device back button click].
The problem is I have to use a custom messagebox(using a popup) to get user confirmation, and I have no way to get exit from the application.(No method found which will exit the application like dispose() or close()).
if I didn't have to use a custom messagebox, the on the Device back key press event "OnBackKeyPress" I would have use the following logic and done my work
MessageBoxResult res = MessageBox.Show("Do you want to Exit?", "Exit", MessageBoxButton.OKCancel);
if (res == MessageBoxResult.OK)
{
if (NavigationService.CanGoBack)
{
while (NavigationService.RemoveBackEntry() != null)
{
NavigationService.RemoveBackEntry();
}
}
}
else
{
e.Cancel = true;
}
The problem is I need to use the custom messagebox and done this work. Same problem arise if need to implement a button to exit the application with out using the device back button.
I found in several posts suggesting to throw an exception and make this done. Following are some of them
http://mobile.dzone.com/articles/windows-phone-mango-sample-3
http://imaginativeuniversal.com/blog/post/2010/08/22/How-to-Quit-a-WP7-Silverlight-Application.aspx
I don't think that this is a good practice and also not sure if the windows market place will certify this way. Would like to hear the thoughts of once who have experienced this issue, and any suggestion to Achieve this(Terminate the application). Thanks inadvance....!!!!
If you want to submit to the Marketplace you've got a couple of problems because of the following certification requirements:
5.2.4.2 Pressing the Back button from the first screen of an application must close the application.
5.2.2 A Windows Phone application is closed and terminated by the OS when the user navigates away from the application. When an application is started after being closed, its launch time must meet the requirements in Section 5.2.1 – Launch Time
5.2.3 A Windows Phone application is deactivated when the user presses the Start button or if the device timeout causes the lock screen to engage. A Windows Phone application is also deactivated with it invokes a Launcher or Chooser API.
This is a couple instances where you simply can't display a message box.
And technically using an exception to termniate the app is a violation:
5.1.2 The application must handle exceptions raised by the .NET Framework and not close unexpectedly. During the certification process, the application is monitored for unexpected closure. An application that closes unexpectedly fails certification. The application must continue to run and remain responsive to user input after the exception is handled.
As a developer, part of your job is communicating to users about requirements that are unrealistic or unreasonable.
Sorry, no way to do this. Before mango update you could Clear the back stack, then programmatically trigger the Back button. but as of SDK 7.1 (wp7.5) we can no longer do this.
My recommendation is to create a custom Exception type ApplicationXExitException and throw that to exit the app. The reason for the custom type is so that when you pull your exception logs from the marketplace, you'll know the ones that were indeed unintended exceptions crashing the app, vs your exception to intentionally exit the app.
You can hook an event raising after your custom messagebox closes. Event arguments will keep information about user's choice. Depending on that you will decide whether to exit app or not.