Recently, I have a problem when I write procedures: I want to back up files to the network drive, but some files are being used by other programs, and they are open, and they are open, and they are not able to back up files. Operation. Therefore, if you want to back up these files, you must open the processes KILL. So how do you clean the process of opening these open files? I believe that after reading this article, there will be a way to solve it!
In fact, there is a tool program called TSkill.exe in a new Windows operating system version, and you can solve the problem. As shown in the figure:
Figure 1 TSKILL program
To kill a process, you can enter the following command to kill its operational examples:
TSKILL program name but I want to implement TSKILL's function in the code you write? The method of the safest kill process is to send a WM_CLOSE message to the main window of the running program.
HWND HWND = // Get the main window
PostMessage (hwnd, wm_close, 0, 0); After sending this message, you should usually wait until the process does terminate:
Handle HP = OpenProcess (Synchronize | Process_Terminate, False, PID);
WaitForsingleObject (HP, 5000); // Waiting for 5 seconds When the process terminates, it issues a status signal, and WaitForsingleObject returns Wait_Object_0. If you return other values, the process is either hang, or it is still processed. In this case, the only way to kill this process is to use more powerful TerminateProcess:
IF (WaitforsingleObject (HP, 5000)! = Wait_Object_0)
TerminateProcess (hp, 0); if you want to dry, you can send a WM_QueryEndSession message to the main window before shutting down. When the user ends the session (log out) or someone calls EXITWINDOWS, the application receives this message. Then prepare the upcoming death. At this time, a confirmation dialog will be popped up, tell the world: "I have to finish the easter, if you want to save the modified thing, now is the best time, want to save?" There are three options (Yes / No / Cancel). In addition, WM_QUERYENDSESSION can even reject death ("Cancel key"), if so, life will continue. The code should be written like this:
DWORD BOKTOKILL = FALSE;
SendMessageTimeout (hwnd, wm_queryendsession, 0, 0,
SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG, 100, & BOKTOKILL
IF (boktokill) {
// Send WM_Close and wait
} If the process you want to close is hang. It is very important to use SendMessageTimeout, not to use SendMessage. SMTO_NOTIMEOUTIFNOTHUG is a flag only with Windows 2000 and Windows XP. Its meaning is "If the thread does not hang, don't time out." SOLVED is: If the thread is working properly, then wait, so that users can see the dialog and decide what to do. After the user finally decided, SendMessageTimeout will return with the corresponding boktokill value. All of these premise is that other applications are running normally and WM_QueryEndSession also gets normal processing. This article provides a small example program KP.exe, below is key code: /
Kp.exe program code
#include "stdafx.h"
#include "enumproc.h"
Typedef List
INLINE BOOL ISSWITCH (TCHAR C) {RETURN C == L '' '' '|| c == L' '' '' '' '' - '' '' '' ';}
INT Main (int Argc, tchar * argv [], tchar * envp [])
{
CSTRINGLIST cmdargs; // command line parameters (to kill the process, you can multiple)
Bool bdisplayOnly = false; // Do not kill, just display
Bool bquiet = false; // Prohibit error message
Bool bzap = false; // forced killing
// Analytical command line switch, switch order can be arbitrary
For (INT i = 1; i IF (ISSwitch (Argv [I] [0])) { For (uint j = 1; j Switch (TOLOWER (Argv [I] [J])) { Case '' '' '' '?' '' '' '': Help (); Return 0; Case '' '' '' '' '' '' '': bdisplayOnly = True; Break; Case '' '' '' '' '' '' '' ': Bquiet = True; Break; Case '' '' '' '' '' '' '' ': BZAP = True; Break; DEFAULT: Return help (); } } } else { cmdargs.push_back (argv [i]); // If it is a non-switch parameter, add to list} } IF (cmdargs.size () <= 0) Help (); // Traverse parameters (module name), one one CSTRINGLIST :: Iterator IT; For (it = cmdargs.begin (); it! = cmdargs.end (); it ) { CFINDKILLPROCESS FKP; DWORD PID = fkp.findprocess (it-> c_str ()); IF (PID) { IF (bdisplayOnly) { _tprintf (_T ("Kill Process% D (0x% 08x) / N"), PID, PID); } else { Fkp.killProcess (PID, BZAP); } } else if (! bquiet) { _tprintf (_t ("error: Can't find the process' '' '' '' '' '' '' '' '' '' ./ n"), IT-> C_STR ()); } } Return 0; } The functionality of this program is similar to TSKILL, and it can also kill the process. In order to enhance the reusability of the code, you will be packaged in a class called CFindkillProcess, including find and kill processes, please refer to Enumproc.h and Enumproc.cpp files for details. There are still two other reusable classes in the file, one is CPRocessItemrator and the other is CWindowItemrator. This has been described in detail in previous articles. see" How do I get the main window of a process and the program name that creates a process? " /// Enumproc.h and enumproc.cpp // ENUMPROC.H // // The following is the definition and implementation of cfindkillProcess, which is a small tool class that is specifically used to find and kill it through the name of a process. // Class cfindkillprocess { PUBLIC: CfindkillProcess (); ~ Cfindkillprocess (); DWORD FINDPROCESS (LPCTSTR LPMODNAME, BOOL BADDEXE = true); Bool KillProcess (DWORD PID, BOOL BZAP); } ENUMPROC.CPP #include "stdafx.h" #include "enumproc.h" ...... // Implement CPRocessITerator ....... // Implement CWINDOTERATOR // Implement CFINDKILLPROCESS - Use the module name to find and kill the process. // CfindkillProcess :: cfindkillprocess () { } CfindkillProcess :: ~ cfindkillprocess () { } // / / Search the module name matching with parameters, the module name can be foo or foo.exe // DWORD CFINDKILLLLPROCESS :: FindProcess (LPCTSTR MODNAME, BOOL BADDEXE) { CPROCESSITERATOR ITP; For (DWORD PID = itp.first (); PID; PID = itp.next ()) { Tchar name [_MAX_PATH]; CPROCESSMODULETOR ITM (PID); HModule hmodule = itm.first (); // .exeif (hmodule) { GetModuleBaseName (itm.getProcessHandle (), HModule, Name, _max_path; String smodname = modname; IF (Strcmpi (SmodName.c_Str (), Name) == 0) Return PID; Smodname = ".exe"; IF (Baddexe && Strcmpi (SmodName.c_Str (), Name) == 0) Return PID; } } Return 0; } // // Clean the process: Turn off the window after waiting. // bzap = true: forced killing // Bool CfindkillProcess :: KillProcess (DWORD PID, BOOL BZAP) { CMAINWINDOTERATOR ITW (PID); For (hwnd hwnd = itw.first (); hwnd; hWnd = itw.next ()) { DWORD BOKTOKILL = FALSE; SendMessageTimeout (hwnd, wm_queryendsession, 0, 0, SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG, 100, & BOKTOKILL IF (! boktokill) Return False; // Don't be willing to die, cancel action Postmessage (hwnd, wm_close, 0, 0); } // I have closed all the main windows and now wait for the process to die. Bool bkilled = True; Handle HP = OpenProcess (Synchronize | Process_Terminate, False, PID); IF (hp) { IF (WaitforsingleObject (HP, 5000)! = Wait_Object_0) { IF (bzap) {// does not want to die, that can't, you must die TerminateProcess (HP, 0); } else { BKILLED = FALSE; } } CloseHandle (HP); } Return bkilled; } The method of use of CFINDKILLPROCESS is as follows: CFINDKILLPROCESS FKP; DWORD PID = fkp.findprocess ("Outlook.exe"); Fkp.killProcess (PID); FindkillProcess enumerates all processes with CPRocessITerator and CPRocessModuleTorator classes, finds the first module that matches the name (ie, the execution of the EXE file): CPROCESSITERATOR ITP; For (DWORD PID = itp.first (); PID; PID = itp.next ()) { CPROCESSMODULETOR ITM (PID); HModule hmodule = itm.first (); // .exe IF (/ * Module Name = Module name "* /) { Return PID; } } FINDPROCESS looks for foo or foo.exe. If you find this process, it returns the ID of this process, then you pass it to cfindkillProcess :: killprocess. KillProcess encapsulates closing windows and terminates logic. It uses CMAINWINDOTERATOR to enumerate the main window of the process (more than one, see "How to get the main window of a process and create program names of the process?"), And send WM_Close to each window, then wait for the process to die. It has a Boolean parameter to indicate whether TerminateProcess is executed when the application is reluctant to die. See the downloaded code for details.