我想无条件强制杀死一个进程,该如何做呀?
我已经可以获得此进程的HWND(利用FindWindow),但是因为我在那个程序中处理了WM_CLOSE事件,所以现在用postmessage就不能结束它。有别的方法吗?
我看到任务管理器中就能强制杀死它的,那我如何编程来实现呀?
我已经可以获得此进程的HWND(利用FindWindow),但是因为我在那个程序中处理了WM_CLOSE事件,所以现在用postmessage就不能结束它。有别的方法吗?
我看到任务管理器中就能强制杀死它的,那我如何编程来实现呀?
#define RTN_USAGE 1
#define RTN_ERROR 13#include <windows.h>
#include <stdio.h>BOOL SetPrivilege(
HANDLE hToken, // token handle
LPCTSTR Privilege, // Privilege to enable/disable
BOOL bEnablePrivilege // TRUE to enable. FALSE to disable
);void DisplayError(LPTSTR szAPI);int main(int argc, char *argv[])
{
HANDLE hProcess;
HANDLE hToken;
int dwRetVal=RTN_OK; // assume success from main() // show correct usage for kill
if (argc != 2)
{
fprintf(stderr,"Usage: %s [ProcessId]\n", argv[0]);
return RTN_USAGE;
} if(!OpenProcessToken(
GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken
)) return RTN_ERROR; // enable SeDebugPrivilege
if(!SetPrivilege(hToken, SE_DEBUG_NAME, TRUE))
{
DisplayError("SetPrivilege"); // close token handle
CloseHandle(hToken); // indicate failure
return RTN_ERROR;
} // open the process
if((hProcess = OpenProcess(
PROCESS_ALL_ACCESS,
FALSE,
atoi(argv[1]) // PID from commandline
)) == NULL)
{
DisplayError("OpenProcess");
return RTN_ERROR;
} // disable SeDebugPrivilege
SetPrivilege(hToken, SE_DEBUG_NAME, FALSE); if(!TerminateProcess(hProcess, 0xffffffff))
{
DisplayError("TerminateProcess");
dwRetVal=RTN_ERROR;
} // close handles
CloseHandle(hToken);
CloseHandle(hProcess); return dwRetVal;
}BOOL SetPrivilege(
HANDLE hToken, // token handle
LPCTSTR Privilege, // Privilege to enable/disable
BOOL bEnablePrivilege // TRUE to enable. FALSE to disable
)
{
TOKEN_PRIVILEGES tp;
LUID luid;
TOKEN_PRIVILEGES tpPrevious;
DWORD cbPrevious=sizeof(TOKEN_PRIVILEGES); if(!LookupPrivilegeValue( NULL, Privilege, &luid )) return FALSE; //
// first pass. get current privilege setting
//
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = 0; AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
&tpPrevious,
&cbPrevious
); if (GetLastError() != ERROR_SUCCESS) return FALSE; //
// second pass. set privilege based on previous setting
//
tpPrevious.PrivilegeCount = 1;
tpPrevious.Privileges[0].Luid = luid; if(bEnablePrivilege) {
tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
}
else {
tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED &
tpPrevious.Privileges[0].Attributes);
} AdjustTokenPrivileges(
hToken,
FALSE,
&tpPrevious,
cbPrevious,
NULL,
NULL
); if (GetLastError() != ERROR_SUCCESS) return FALSE; return TRUE;
}void DisplayError(
LPTSTR szAPI // pointer to failed API name
)
{
LPTSTR MessageBuffer;
DWORD dwBufferLength; fprintf(stderr,"%s() error!\n", szAPI); if(dwBufferLength=FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
GetSystemDefaultLangID(),
(LPTSTR) &MessageBuffer,
0,
NULL
))
{
DWORD dwBytesWritten; //
// Output message string on stderr
//
WriteFile(
GetStdHandle(STD_ERROR_HANDLE),
MessageBuffer,
dwBufferLength,
&dwBytesWritten,
NULL
); //
// free the buffer allocated by the system
//
LocalFree(MessageBuffer);
}
}
怎么获得ProcessId呢?我只能通过FindWindow得到HWD 。
* 退出线程 *
*******************************************************************************/
DWORD m_ThreadID; //线程ID
HANDLE m_hThread; //线程句柄
int ExitThread()
{
if (TerminateThread(m_hThread, 4))
{
DWORD dwExitCode =0;
while(TRUE)
{
GetExitCodeThread(m_hThread, &dwExitCode);
if (dwExitCode != STILL_ACTIVE)
break;
Sleep(10);
}
CloseHandle(m_hThread);
} return 0;
}
The EnumProcesses function retrieves the process identifier for each process object in the system. BOOL EnumProcesses(
DWORD *lpidProcess, // array of process identifiers
DWORD cb, // size of array
DWORD *cbNeeded // number of bytes returned
);
////////////////////////////////////////////////////////////////
// MSDN Magazine -- August 2002
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual Studio 6.0 on Windows XP.
//
#include "stdafx.h"#include <Psapi.h>
#include "..\..\include\EnumProc.h"
//#include "Psapi.h"
#include "XSTRING"
//#if(WINVER >= 0x0500)
#define SMTO_NOTIMEOUTIFNOTHUNG 0x0008
//#endif /* WINVER >= 0x0500 */
#pragma comment(lib, "Psapi.Lib")
////////////////////////////////////////////////////////////////
// CProcessIterator - Iterates all processes
//
CProcessIterator::CProcessIterator()
{
m_pids = NULL;
}CProcessIterator::~CProcessIterator()
{
delete [] m_pids;
}//////////////////
// Get first process: Call EnumProcesses to init array. Return first one.
//
DWORD CProcessIterator::First()
{
m_current = (DWORD)-1;
m_count = 0;
DWORD nalloc = 1024;
do {
delete [] m_pids;
m_pids = new DWORD [nalloc];
if (EnumProcesses(m_pids, nalloc*sizeof(DWORD), &m_count)) {
m_count /= sizeof(DWORD);
m_current = 1; // skip IDLE process
}
} while (nalloc <= m_count); return Next();
}////////////////////////////////////////////////////////////////
// CProcessModuleIterator - Iterates all modules in a process
//
CProcessModuleIterator::CProcessModuleIterator(DWORD pid)
{
m_hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, pid);
}CProcessModuleIterator::~CProcessModuleIterator()
{
CloseHandle(m_hProcess);
delete [] m_hModules;
}//////////////////
// Get first module in process. Call EnumProcesseModules to
// initialize entire array, then return first module.
//
HMODULE CProcessModuleIterator::First()
{
m_count = 0;
m_current = (DWORD)-1;
m_hModules = NULL;
if (m_hProcess) {
DWORD nalloc = 1024;
do {
delete [] m_hModules;
m_hModules = new HMODULE [nalloc];
if (EnumProcessModules(m_hProcess, m_hModules,
nalloc*sizeof(DWORD), &m_count)) {
m_count /= sizeof(HMODULE);
m_current = 0;
}
} while (nalloc <= m_count);
}
return Next();
}////////////////////////////////////////////////////////////////
// CWindowIterator - Iterates all top-level windows (::EnumWindows)
//
CWindowIterator::CWindowIterator(DWORD nAlloc)
: m_current(0), m_count(0)
{
ASSERT(nAlloc>0);
m_hwnds = new HWND [nAlloc];
m_nAlloc = nAlloc;
}CWindowIterator::~CWindowIterator()
{
delete [] m_hwnds;
}// callback passes to virtual fn
BOOL CALLBACK CWindowIterator::EnumProc(HWND hwnd, LPARAM lp)
{
return ((CWindowIterator*)lp)->OnEnumProc(hwnd);
}//////////////////
// Virtual enumerator proc: add HWND to array if OnWindows is TRUE.
// You can override OnWindow to filter windows however you like.
//
BOOL CWindowIterator::OnEnumProc(HWND hwnd)
{
if (OnWindow(hwnd)) {
if (m_count < m_nAlloc)
m_hwnds[m_count++] = hwnd;
}
return TRUE; // keep looking
}////////////////////////////////////////////////////////////////
// CMainWindowIterator - Iterates the main windows of a process.
// Overrides CWindowIterator::OnWindow to filter.
//
CMainWindowIterator::CMainWindowIterator(DWORD pid, BOOL bVis,
DWORD nAlloc) : CWindowIterator(nAlloc), m_pid(pid), m_bVisible(bVis)
{
}CMainWindowIterator::~CMainWindowIterator()
{
}//////////////////
// OnWindow:: Is window's process ID the one i'm looking for?
// Set m_bVisible=FALSE to find invisible windows too.
//
BOOL CMainWindowIterator::OnWindow(HWND hwnd)
{
if (!m_bVisible || (GetWindowLong(hwnd,GWL_STYLE) & WS_VISIBLE)) {
DWORD pidwin;
GetWindowThreadProcessId(hwnd, &pidwin);
if (pidwin==m_pid)
return TRUE;
}
return FALSE;
}////////////////////////////////////////////////////////////////
// CFindKillProcess - to find/kill a process by module name.
//
CFindKillProcess::CFindKillProcess()
{
}CFindKillProcess::~CFindKillProcess()
{
}//////////////////
// Search for process whose module name matches parameter.
// Finds "foo" or "foo.exe"
//
DWORD CFindKillProcess::FindProcess(LPCTSTR modname, BOOL bAddExe)
{
CProcessIterator itp;
for (DWORD pid=itp.First(); pid; pid=itp.Next()) {
TCHAR name[_MAX_PATH];
CProcessModuleIterator itm(pid);
HMODULE hModule = itm.First(); // .EXE
if (hModule) {
GetModuleBaseName(itm.GetProcessHandle(),
hModule, name, _MAX_PATH); std::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;
}//////////////////
// Kill a process cleanly: Close main windows and wait.
// bZap=TRUE to force kill.
//
BOOL CFindKillProcess::KillProcess(DWORD pid, BOOL bZap)
{
CMainWindowIterator 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; // window doesn't want to die: abort
PostMessage(hwnd, WM_CLOSE, 0, 0);
} // I've closed the main windows; now wait for 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) { // didn't die: force kill it if zap requested
TerminateProcess(hp,0);
} else {
bKilled = FALSE;
}
}
CloseHandle(hp);
}
return bKilled;
}
////.h////////////////////////////////////////////////////////////////
// MSDN Magazine -- August 2002
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual Studio 6.0 on Windows XP.
//
#pragma once//////////////////
// Process iterator -- iterator over all system processes
// Always skips the first (IDLE) process with PID=0.
//
class CProcessIterator {
protected:
DWORD* m_pids; // array of procssor IDs
DWORD m_count; // size of array
DWORD m_current; // next array item
public:
CProcessIterator();
~CProcessIterator(); DWORD First();
DWORD Next() {
return m_pids && m_current < m_count ? m_pids[m_current++] : 0;
}
DWORD GetCount() {
return m_count;
}
};//////////////////
// Iterate the modules in a process. Note that the first module is the
// main EXE that started the process.
//
class CProcessModuleIterator {
protected:
HANDLE m_hProcess; // process handle
HMODULE* m_hModules; // array of module handles
DWORD m_count; // size of array
DWORD m_current; // next module handle
public:
CProcessModuleIterator(DWORD pid);
~CProcessModuleIterator(); HMODULE First();
HMODULE Next() {
return m_hProcess && m_current < m_count ? m_hModules[m_current++] : 0;
}
DWORD GetCount() {
return m_count;
}
HANDLE GetProcessHandle() {
return m_hProcess;
}
};//////////////////
// Iterate the top-level windows
//
class CWindowIterator {
protected:
HWND* m_hwnds; // array of hwnds for this PID
DWORD m_nAlloc; // size of array
DWORD m_count; // number of HWNDs found
DWORD m_current; // current HWND
static BOOL CALLBACK EnumProc(HWND hwnd, LPARAM lp); // virtual enumerator
virtual BOOL OnEnumProc(HWND hwnd); // override to filter different kinds of windows
virtual BOOL OnWindow(HWND hwnd) {
return TRUE;
}public:
CWindowIterator(DWORD nAlloc=1024);
~CWindowIterator();
HWND Next() {
return m_hwnds && m_current < m_count ? m_hwnds[m_current++] : NULL;
}
HWND First() {
::EnumWindows(EnumProc, (LPARAM)this);
m_current = 0;
return Next();
}
DWORD GetCount() {
return m_count;
}
};//////////////////
// Iterate the top-level windows in a process
//
class CMainWindowIterator : public CWindowIterator {
protected:
DWORD m_pid; // process id
DWORD m_bVisible; // show only visible windows
virtual BOOL OnWindow(HWND hwnd);
public:
CMainWindowIterator(DWORD pid, BOOL bVis=TRUE, DWORD nAlloc=1024);
~CMainWindowIterator();
};//////////////////
// Handy class to facilitate finding and killing a process by name.
//
class CFindKillProcess {
public:
CFindKillProcess();
~CFindKillProcess();
DWORD FindProcess(LPCTSTR lpModname, BOOL bAddExe=TRUE);
BOOL KillProcess(DWORD pid, BOOL bZap);
};
没有Psapi.h呀?
请发给我 : [email protected] 谢谢!