How to exit SW quickly - winapi

I have a SW which reside in external HDD, it will run automatically when user plug external HDD, of course, the SW have to close automatically when user unplug the external HDD. I can receive the device lost message, however my SW will not be respond druing releasing all objects, if I call exit(0) directly, the SW will show a crash message. Is there any way to quickly exit SW?

The clean way to exit a Windows application is
PostQuitMessage(0);
This will send WM_QUIT to the application, causing the message loop to terminate.

The fastest way to terminate a process is to call TerminateProcess(). This simply stop the process from receiving any further time slices and releases all the resources allocated to it by windows.
This method of ending a process is not recommended though for various reasons. One of the for instance is that if you have an open file which you write to using the standard library, some data may still be buffered and not fully written to the file.

I'll assume you want to exit cleanly. If you don't need to exit cleanly, use PostQuitMessage. If you do, and it's a UI app, send WM_CLOSE to your main window.
You should clarify what objects your software "will not be respond during" when you quit, and why it ceases to respond

I assume you're looking for a way to keep your app from crashing when the user unplugs an external device. You can force the OS to copy your executable from movable media to the swapfile and execute it from there. The corresponding linker switch (for MSVC++) is /SWAPRUN:{NET|CD}.
Set it to CD and the OS will copy the executable to swap when it's executed from the external drive.

Related

How to open file in Windows as soon as it's unlocked?

In my program I call ReadDirectoryChangesW to listen for file events in a given directory. The problem is some events (e.g. FILE_ACTION_ADDED) are signaled when the file is opened, not closed. This means the file will be locked by other process for some unspecified amount of time and CreateFileW will be returning an error.
The question is: how do I open the file when the other process is done with it? I can tolerate race conditions (e.g. some other process manages to delete the file after it's closed, but before I open it), but I'd like to avoid busy waiting.
Options I see/considered so far:
Asynchronous CreateFileW. That would be an ideal solution, but it's not possible - all user-space APIs for opening a file are synchronous by design (see a great explanation).
Listening for FILE_NOTIFY_CHANGE_LAST_ACCESS. This almost works - notification on close is sent only when the other process wrote some bytes to the file.
I also found some resources on kernel filter drivers, which can detect file close event. Probably works, but seems a bit too complex.
Busy loop continuously calling CreateFileW until it succeeds. Overutilizes the CPU, but is the only thing that actually works. I'm worried I'm stuck with this approach.

How to handle abnormal program termination in Perl on Windows

I have a Perl program on Windows that needs to execute cleanup actions on exit. I wrote a signal handler using sigtrap, but it doesn't always work. I can intercept Ctrl-C, but if the machine is rebooted or the program is killed some other way, neither the signal handler nor the END block are run. I've read that Windows doesn't really have signals, and signal handling on windows is sort of a hack in Perl. My question is, how can I handle abnormal termination the Windows way? I want to run my cleanup code regardless of how or why the program terminates (excluding events that can't be caught). I've read that Windows uses events instead of signals, but I can't find information on how to deal with Windows events in Perl.
Unfortunately, I don't have the authority to install modules from CPAN, so I'll have to use vanilla ActiveState Perl. And to make things even more interesting, most of the machines I'm using only have Perl 5.6.1.
Edit: I would appreciate any answers, even if they require CPAN modules or newer versions of Perl. I want to learn about Windows event handling in Perl, and any information would be welcome.
In all operating systems, you can always abruptly terminate any program. Think of kill -9 command in Unix/Linux. You do that on any program, and it stops instantly. No way to trap it. No way for the program to request a few more operating system cycles for a clean up.
I'm not up on the difference between Unix and Windows signals, but you can imagine why each OS must allow what we call in Unix SIGKILL - a sure and immediate way to kill any program.
Imagine you have a buggy program that intercepts a request to terminate (a SIGTERM in Unix), and it enters a cleanup phase. Instead of cleaning up, the program instead gets stuck in a loop that requests more and more memory. If you couldn't pull the SIGKILL emergency cord, you'd be stuck.
The ultimate SIGKILL, of course is the plug in the wall. Pull it, and the program (along with everything else) comes to a screeching halt. There's no way your program can say "Hmm... the power is out and the machines has stopped running... Better start up the old cleanup routine!"
So, there's no way you can trap every program termination signal, and, your program will have to account for that. What you can do is see if your program needs to do a cleanup before running. On Windows, you can put an entry in the registry when your program starts up, and remove it when it shuts down and does a cleanup. In Unix, you can put a file or directory name starting wit a period in the $ENV{HOME} directory.
Back in the 1980s, I wrote accounting software for a very proprietary OS. When the user pressed the ESCAPE button, we were suppose return immediately to the main menu. If the user was entering an order, and took stuff out of inventory, the transaction would be incomplete, and inventory would be showing the items as being sold even though the order was incomplete. The solution was to check for these incomplete orders the next time someone entered an order, and back out the changes in inventory before entering the new order. Your program may have to do something similar.

Can aborting a process without resetting the clipboard chain cause trouble?

I've got a program that calls SetClipboardViewer at startup to register for clipboard change notifications. At shutdown time, it will call ChangeClipboardChain to remove itself from the chain correctly.
This is all great as long as the program runs normally. But that's got me wondering, what happens if the program gets aborted, either by me killing it under the debugger, by a crash, or by the user killing the process because something went wrong? Then the cleanup never happens. Can that cause trouble for the system somehow?
Specifically, I know Windows can remove my viewer without trouble because it's a handle and Windows can clean up all handles when a process terminates, but will this cause the next value downstream in the chain, that I was holding a reference to, to get lost somehow?
Yes, failure to remove yourself from the chain will break the chain. Deadly sin #2. Please read the whole list to be sure that you're following all of the rules.
http://www.clipboardextender.com/developing-clipboard-aware-programs-for-windows/6
Lots of apps suffer from this, including the Delphi IDE. i.e. if Delphi crashes in certain ways, it'll kill the clipboard chain (D2005 anyway).
Consider using Vista style notification on Vista/Windows7.

Terminating a process before trying to copy files

I'm developing an NSIS installer, to update a program that runs in background. Obviously, I'd like to send the program termination signals, because otherwise I repeatedly get a "can't write" error. How can I do this, with a limited overhead on installer size?
If your app has a window with a unique class name, you could just send it WM_CLOSE/WM_QUIT or whatever message you need.
Or your app could register a local server COM object the uninstaller could call (The system plugin can call COM methods)
Another way to do this is for the program to create a named event and wait on it, the uninstaller would signal it, this would be the clue for the program to quit.
As a last resort, you could kill the process with one of several plugins: KillProcDLL, Processes plug-in, KillProc plug-in and NsProcess
Also, the Locked List plugin might be a better alternative.

How to reload a crashed process on Windows

How to reload a crashed process on Windows? Of course, I can run a custom monitoring Win service process. But, for example, Firefox: it doesn't seem to install such a thing, but still it can restart itself when it crashes.
On Vista and above, you can use the RegisterApplicationRestart API to automatically restart when it crashes or hangs.
Before Vista, you need to have a top level exception filter which will do the restart, but be aware that running code inside of a compromised process isn't entirely secure or reliable.
Firefox constantly saves its state to the hard disk, every time you open a tab or click a link, or perform some other action. It also saves a flag saying it shut down safely.
On startup, it reads this all back, and is able to "restore" based on that info.
Structured exception handling (SEH) allows you to catch program crashes and to do something when it happens.
See: __try and __except
SEH can be very dangerous though and could lead to your program hanging instead. Please see this article for more information.
If you write your program as an NT service then you can set the first, second and subsequent failure actions to "Restart the service".
For Windows 2008 server and Windows Vista and Windows 7 you can use the Win32 API RegisterApplicationRestart
Please see my answer here for more information about dealing with different types of program crashes.
If I recall correctly Windows implements at least some subset of POSIX and so "must" have the signal interface (things like SIGKILL, SIGSEGV, SIGQUIT etc.).
I've never done this but on linux, but you could try setting the unexpected termination trap with signal() (signal.h).
From quick scan of docs it seems that very few things can be done while handling signal, it may be possible that even starting a new process is on forbidden list.
Now that I've thought about it, I'd probably go with master/worker pattern, very simple parent thread that does nothing but spawns the worker (that does all the UI / other things). If it does not set a specific "I'm gonna die now" bit but still dies (parent process always gets message / notification that spawned process died) then master respawns the worker. The main theme is keep master very simple and hard to die due to own bugs.

Categories

Resources