Programs like Notepad can stop the computer shutdown process when files are not saved. How can I write a program that stops the shutdown process (in C)?
For Windows Vista and above there exists a fuction defined in User32.dll (User32.lib) called "ShutdownBlockReasonCreate".
It takes two parameters:
- A handle of the window
- A string representing a message to be displayed
If the call succeeds than you application will block windows from shutting down.
This is a powerful function and should not be abused!
Related
I have a C pthread running a non-blocking event loop which executes lua scripts. A lua script runs io.popen to execute a shell script which takes some time to complete.
I am only interested in capturing the first few characters from the output of the script even though the script takes time to complete. As the lua script reads those first few characters and reaches its end it returns execution to C as expected. The problem is that the shell script that was opened with io.popen keeps running in the background until it completes. Calling f.close() in lua after reading the first few characters does not seem to halt its execution (it appears to only close the read side of the pipe?). Unfortunately, it starts blocking my C thread and displays "write error: broken pipe" messages until the shell script ends. This would make sense if the read end of the pipe is closed (and garbage collected) as the lua script ends execution, and the write end is still being written to by the shell script. The question is, how do I either kill the shell script since i am no longer interested in the rest of its output/execution, or silence it in a way that will not block my parent process?
I have tried redirecting 2>/dev/null on the io.popen command but that only silenced the "write error: broken pipe" messages - the blocking is still there.
If there is a way to get the child process (from C) of what lua openes with io.popen and kill that? (I'm thinking that might also help).
Any thoughts/suggestions are greatly appreciated!
Terminating a Process from CMD: Softest to Hardest
I was wondering if anyone had experience using command line to terminate processes using taskkill and WIMC.
I was wondering if anyone knew the order of how "hard" of a close/terminate these commands are from the command that is the "softest" (least forceful) close to the command that is the "hardest" (most forceful):
My guess would be:
Least/Softest
1) taskkill /im processname.exe
2) wmic process where name="processname.exe" call terminate
3) wmic process where name='processname.exe' delete
4) taskkill /f /im processname.exe
Most/Hardest
I am trying to create a batch command file and wanted to just know the difference between these, to see which I should use.
I prefer to use a softer close, check to see if the process is still running, and then try a harder close, and then repeat this until the program is successfully closed. Any info on the difference between any of these would be helpful, especially between using terminate and delete via CMD: WMIC would be helpful, as I cannot find documentation anywhere on them.
As CatCat mentioned, there are two main ways to terminate a process : WM_CLOSE and TerminateProcess(). I've included two more for completeness sake.
Sending window message WM_CLOSE to the main window of the process. This is the same message an application receives when user clicks X button to close the window. The app may then gracefully shutdown or ask user for confirmation - for example if some work is unsaved.
taskkill without /f appears to attempt doing that but seems to not always succeed in finding the correct window to close. If the app is supposed to not have a visible window (such as if it only displays an icon in system tray or is a windowless server) it may ignore this message entirely.
If taskkill does not work for you, it is possible NirCmd: does better job: NirCmd.exe closeprocess iexplore.exe
There is also WM_ENDSESSION message - it it sent by the OS when shutting down (after WM_QUERYENDSESSION). It works pretty much the same way except it is sent to whole application rather then a specific window. Depending on parameters, apps may be requested to save the work into temporary files because the system needs to restart to apply some updates. Some applications react to this message, some don't.
It should be possible to send these messages manually, but I have not seen it done other than to test how app reacts to shutdown without actually shutting down OS.
WM_QUIT message suggests the application as a whole needs to shut down (more specifically, it is sent to a thread). An application should normally post it to itself after its window is done closing and now it is time to end the process.
It is possible to manually post the message to every thread of another process but this is hackish and rare, it may crash processes not expecting to be issued this message from outside. I'm not sure if it's a better option than just terminating the process or not.
TerminateProcess() tells the OS to forcefully terminate the process. This is what happens when you click End process button on processes tab in the task manager. The process does not get notified it is being closed - it is just stopped where it was and removed from the memory - no questions, no shutdown, etc.
This may cause corruption if some files were being written at that time or data transferred.
That is what taskkill /f command does. Both wmic process call terminate and wmic process delete appear to also do this although I'm not sure.
using wmic:
print all running process where name of process is cmd.exe
wmic process where name="cmd.exe" GET ProcessId, CommandLine,CreationClassName
then terminate the specific instance of process by processId (PID)
WMIC PROCESS WHERE "ProcessID=13800" CALL TERMINATE
Is it possible to make a program written in C to stop and then relaunch itself after x seconds In windows ?? And if yes, how to make it happen ??
You can accomplish that goal by having your program launch a second program, whose only function is to wait a while and then launch your first program again. In pseudocode, the idea would be:
Program A:
Do whatever the program is supposed to do
Launch program B
exit.
Program B:
Wait predetermined time
Launch program A
exit.
I hope this answers your question adequately.
The way I do this kind of thing is with a command-line option 'startDelay=xx'.
If there is no such command, my app just starts up as normal. If there is, its first action , before attempting to open any files, DB, construct GUI, start threads, start server etc. is to sleep for 'xx' seconds.
If my app needs to restart itself, it copies its own command-line, adds the 'startDelay=xx' to it and launches a new copy of itself, which then immediately sleeps. The original then has plenty of time to shut down normally before the new copy starts the bulk of its run-up.
No need for any other app or Windows scheduler and/or cron crap:)
If you run a .bat or .cmd file with %0|%0 inside, your computer starts to use a lot of memory and after several minutes, is restarted. Why does this code block your Windows? And what does this code programmatically do? Could it be considered a "bug"?
This is the Windows version of a fork bomb.
%0 is the name of the currently executing batch file. A batch file that contains just this line:
%0|%0
Is going to recursively execute itself forever, quickly creating many processes and slowing the system down.
This is not a bug in windows, it is just a very stupid thing to do in a batch file.
This is known as a fork bomb.
It keeps splitting itself until there is no option but to restart the system.
http://en.wikipedia.org/wiki/Fork_bomb
What it is:
%0|%0 is a fork bomb. It will spawn another process using a pipe | which runs a copy of the same program asynchronously. This hogs the CPU and memory, slowing down the system to a near-halt (or even crash the system).
How this works:
%0 refers to the command used to run the current program. For example, script.bat
A pipe | symbol will make the output or result of the first command sequence as the input for the second command sequence. In the case of a fork bomb, there is no output, so it will simply run the second command sequence without any input.
Expanding the example, %0|%0 could mean script.bat|script.bat. This runs itself again, but also creating another process to run the same program again (with no input).
%0 will never end, but it never creates more than one process because it instantly transfers control to the 2nd batch script (which happens to be itself).
But a Windows pipe creates a new process for each side of the pipe, in addition to the parent process. The parent process can't finish until each side of the pipe terminates. So the main program with a simple pipe will have 3 processes. You can see how the bomb quickly get's out of control if each side of the pipe recursively calls the parent batch!
It's a logic bomb, it keeps recreating itself and takes up all your CPU resources. It overloads your computer with too many processes and it forces it to shut down. If you make a batch file with this in it and start it you can end it using taskmgr. You have to do this pretty quickly or your computer will be too slow to do anything.
I have written a program which calculates the amount of battery level available in my laptop. I have also defined a threshold value in the program. Whenever the battery level falls below threshold i would like to call another process. I have used system("./invoke.o") where invoke.o is the program that i have to run. I am running a script which runs the battery level checker program for every 5 seconds. Everything is working fine but when i close the bash shell the automatic invocation of invoke.o is not happening. How should i make the invoke.o to be invoked irrespective of whether bash is closed or not??. I am using UBUNTU LINUX
Try running it as: nohup ./myscript.sh, where the nohup command allows you to close the shell without terminating the process.
You could run your script as a cron job. This lets cron set up standard input and output for you, reschedule the job, and it will send you email if it fails.
The alternative is to run a script in the background with all input and output, including standard error output, redirected.
While you could make a proper daemon out of your program that kind of effort is probably not necessary.
man nohup
man upstart
man 2 setsid (more complex, leads to longer trail of breadcrumbs on daemon launching).