I wrote a simple test program (TestProgram.exe) to learn how to handle the CTRL_CLOSE_EVENT and here are my observations and my question:
1) When I double click Test
When a process is terminated (not closed) nothing realy can be done unless you start do some hooking, either by hooking TerminateProcess or NtTerminateProcess in the Task Manger process, example of how it works:
#include
#include
BOOL WINAPI MyTerminateProcess(HANDLE hProcess, UINT uExitCode ) {
MessageBox(NULL, TEXT("Do some cleanup"), NULL, MB_OK);
ExitProcess(0);
return TRUE;
}
#pragma pack(1)
typedef struct __PATCHDATA {
BYTE push;
DWORD address;
BYTE ret;
} PATCHDATA;
#pragma pack()
int main(int argc, char **argv) {
HMODULE hModule;
DWORD written;
// This struct contains assembly instruction that do:
// push address ; 0x68 MyTerminateProcess
// ret ; 0xc3
// so the execution will return to our hook
PATCHDATA patch = {0x68, (DWORD) MyTerminateProcess, 0xc3};
// remove this code, the program will terminate itself.
// TODO: check the memory protection and modify it.
WriteProcessMemory(GetCurrentProcess(),
TerminateProcess,
&patch,
sizeof(PATCHDATA),
&written);
TerminateProcess(NULL, 0);
return 0;
}
This hooks TerminateProcess
in the same process, you need to ship it in a DLL and inject it in the Task Maneger process, didn't test it. But this method is overwork and not safe, some AV products may detect it as harmful program.
A simple solution is to clean up on the program start-up as @Martin James suggested. On your program start-up create a file or use the registry to store some value like 0
, if the program was closed, received WM_CLOSE
if it's GUI or CTRL_CLOSE_EVENT
if you closed the command prompt, you do the clean-up and store 1
.
On the next start-up you you check back that value if it stills 0
, this mean do the program was not closed properly, do do the clean up, if it's 1
no need to the clean-up, store 0
and move on.
Many programs use this method to detect if the program was closed properly.