Please read - this is not a duplicate.
I have a Windows service that runs under the LocalSystem acct. I am in need of restoring certain files prior to shutdown. I am able to intercept the Shutdown action at which point I initiate my restore process but the shutdown happens before I am able to complete.
I have enabled Shutdown privileges, added calls to AbortShutdown (Win32) and several other (ie shutdown /a) options but they do not work. I believe it is because the shutdown or restart has already been initiated and I have read that these functions only stop a shutdown while it is scheduled.
My goal is to intercept the shutdown, abort it, complete my tasks and then shutdown. I just need more time and the amount of time is dependent on the number and size of files I have to restore.
I am open to any suggestion and appreciate your time and consideration.
Thanks!
This sounds more like something that can be done with windows batch files.
Your goal is untenable. On Windows, the user has control over the shutdown process. If the user wants to shutdown the machine, it's not up to your software to contravene the user's intentions.
The burden is on you to make sure that your software can deal with a shutdown, whenever it happens. This usually means making sure that file operations are as atomic as possible, or using a "hot journal" file to recover (on the next system startup) in the event that atomic operations can't be completed.
The files that you speak of, that you have to restore before shutdown, should be "restored" (hard to tell exactly what you mean here) as soon as any operations are finished on them. Without further details, it hard to discuss the specific approaches.
Related
Long story short, I need to create an application that monitor the sound volume on a computer. The computer's user must not be able to stop the application no matter what.
I'll need to make my app start on computer start up, so the user can't just restart it to enter his session without the application running. As of now I don't know precisely how to do it but with some research this shouldn't be a problem.
My biggest concern is if he just stops the process in the task manager. I guess that I can't avoid that programmatically ? Is there a way to just modify the session's right so that it can't stop processes in the task manager? Or any other solution I didn't think about ?
Or there is no way I can do that and I'll just have to trust my user not to ever stop the program in the task manager ?
Thanks in advance for your help. :)
PS : This will run on a computer in a student club that runs the music for the club and that anyone can access. There are chambers where people sleep the floors above so we don't want people to put the volume too loud. That's it. No malware or anything.
In general, the only programs that act like that are malicious (e.g. rootkits). If you think about it, you really wouldn't want programs to be able to act like that.
As others have indicated, the closest you'll get here is a Windows Service, which automatically starts with Windows. Average users won't know to stop it, but it's still possible to stop it manually for power users.
One work-around you could try is to periodically have it call a web service to verify that it's running. That way you could tell who might have uninstalled or stopped the service. (The problem, of course, is that they might just not have their computer on or something; you could have separate calls for "Start" and "Still On").
Alternatively, if this installed only on computers that are exclusively under your direct control, as others have indicated, you could configure things so that you need administrative access to stop the process. This option was addressed in the comments.
I'm not accusing you of malware - just wanted to illustrate how bad it would be if you could easily make a program that the user can "never stop".
So no you can't make a program that a computer-savvy person could never stop.
But from what I gathered....
Sounds like you want to make it a service. https://msdn.microsoft.com/en-us/library/d56de412(v=vs.110).aspx.
Another (easier I think) option is just to make a console app that starts up from the Task Scheduler http://www.c-sharpcorner.com/uploadfile/manas1/console-application-using-windows-scheduler/.
I am having one windows forms application which is designed to do specific tasks in background. Now I want to make sure that this application should be running all the time.
No one should able to close it. If some one closed it from Task Manager (Kill it) then it should restart it self.
I had couple of options for that. I have tried to make one window service which has timer and which can be check at every 1 minute that if process is not found then it will launch the process. But I have gone through couple of articles and they are saying that this is not nice idea. Is there any other way round to keeping alive my application in windows.
In my idea also if someone closes my service then also I can't detect if my WinForms application is closed or running.
What is best way to do so? I am ready to give highest privileges and I have thought that option as well that If someone kill process of my application then computer should be shut down it self.
Please share better idea to do so.
If you don't want the user closing your app, make it as difficult for him as possible:
launch it maximized
remove the frame of the window (and close, maximize,minimize buttons with it)
launch it TopMost
set ShowInTaskbar of your forms to false
ask 10 times "are you sure you want to exit???" :)
set e.Cancel to true in FormClosing event, etc...
About the Task Manager:
I think you can disable task manager altogether http://www.techulator.com/resources/3480-how-disable-task-manager-windows.aspx
Or you can hide the process (ugly and virus-like): How do I hide a process in Task Manager in C#?
Or you can sort-of make it harder to kill the process: Making an app/service such that trying to end/kill its process in Task Manager would result in "Unable to Terminate Process"
Then, if the user still manages to close your app, you can do what most people on the Internet consider a Very Bad Idea and start it from the service. As long as you are concious of the risks.
There are plenty of resource out there that tell you how to start an interactive app from the service (so evidently some people are doing it too), for example:
http://blogs.msdn.com/b/winsdk/archive/2009/07/14/launching-an-interactive-process-from-windows-service-in-windows-vista-and-later.aspx
you should know that it is impossible to prevent task manager not to close your application. and its not a proper idea to force the user.
But, if you insist I think the best way is through services with timer or thread whichever suits your solution to check its process and run it if not exists. and you didn't mention in your post that what was the reason of not using this method and why it is not a good method.
hope it helps you decide better.
I'm currently writing quite a simple app, but it makes a change to the OS which gets changed back when the program is closed.
The worry of course, is if the program crashes. I can do everything in my power to prevent it from crashing, or handling things if it does crash - but I can't stop someone from force closing the process (unless I can?)
Is there a way to catch that event and run just a very quick cleanup before the process exits?
I don't think there is anything you can do if your process gets killed - one approach would be to have your app spawn a helper process that is just there for this case. When your app terminates that process can detect that and "fix" the OS setting as desired before it shuts down itself - obviously this only would work if that other process doesn't get killed first.
You can hook UnhandledException. You can't stop the application terminating, but you can log or do some clean up. This allows you to handle the case of application crashes.
It terms of someone actually just killing the process there's nothing you can do about that.
Program defensively.
Write the original settings to a file. Delete the file when closing. When starting, check whether the file is there - if it is, your process was killed and you know what to return the settings to.
Programming 201 - the basics of transactions, applied to system settings wit hthe program runtime as transaction boundary.
If you don't mind a little interop to C or C++ code, and if you're running on Windows Vista or newer, you could make use of the Application Recovery and Restart APIs. These APIs tell Windows to intercept your process when something catastrophic happens, so that you can perhaps call a little cleanup code before Windows kills the process completely.
See http://msdn.microsoft.com/en-us/library/cc948909.aspx.
Some explanation: for a project I'm working on I have to write a program that is running in the background, detects changes to files, and uploads the modified files to a web service to make it available to others. Quite simple synchronization if it were not for the case when a user modifies a big file and decides to shutdown its computer right after the edit.
I could cancel the upload and wait for the next reboot to do the upload, but I can imagine the user downloading the file from the web to another computer the next morning and don't understanding why his changes from last night aren't there.
So my idea was to detect when the users logs off or reboots Windows, and if I'm in the middle of an upload, just asking the user "We're still synchronizing file Foo.txt that you just changed. Are you sure you want to reboot ? You're changes won't be available to others until you restart your computer !". If the users says no, I'd need to cancel the reboot/loging off
Is this possible?
There is a static class called SystemEvents that exposes this behaviour:
http://msdn.microsoft.com/en-us/library/microsoft.win32.systemevents.aspx
However, it cannot differentiate between certain actions and doesn't pause the OS process time-out guard. I used it once, but the default time-out as configured in the registry is a little short so will likely need increasing.
To cut a long story short, it all felt a little hackish.
To add to #Adam's answer, if you need to tell the difference between logoff and shutdown/reboot, you can handle the WM_QUERYENDSESSION message.
"Shutdown Changes for Windows Vista" is a useful article for understanding the shutdown timeout.
Trying to block a shutdown is a lossy proposition these days, it's no longer possible to do so in Vista and up. A prompt isn't readable nor reachable. Using a service is highly indicated here, lets you survive a user log-off. And a reboot, your service will start running again automatically, letting you complete the job.
Is there any good way to handle a forced exit in C#?
I have a formless C# application that talks to an LCD over serial. Once the application is running, the only way to kill it is with task manager. The trouble with this is that the program needs to turn the LCD off when it is done, and it doesn't look as if my Application.ApplicationExit event is ever fired in this condition.
Any ideas?
Once the application is running, the only way to kill it is with task manager.
My big idea would be to change this.
Stick an icon in the notification area that the user can use to shut your app down properly, or set it up so that running the app again will instead shut down an already-running instance if one exists, or any other way that sounds like a good idea.
Requiring a user to use Task Manager to shut down your application screams poor design.
Write a code in your program loop (with a timer perhaps) to read a file or a registry key. For example if a file at C:\YOURPROGRAM\CLOSEME contains text "closeme", close your program gracefully. Write another program that write that C:\YOURPROGRAM\CLOSEME file. So, whenever you want to shutdown your program, don't use taskmanager, instead, open second program.
Some options:
Write a separate process with a GUI that can start and stop the main process. For example, when you install the Apache web server on Windows the server itself is installed as a service. It can be started and stopped from the system services management panel, but it also comes with a "monitor" process that sits in the notification area, tells you whether Apache is running and lets you start or stop it manually.
If it's acceptable for your use-case, make the application a console application. You can register a handler for when the user presses CTRL+C (see Console.CancelKeyPress) that performs your cleanup before your process exits. This still won't let you handle someone killing the process from Task Manager, but it's very easy to do and might be good enough depending on your situation.