我想无条件强制杀死一个进程,该如何做呀?
我已经可以获得此进程的HWND(利用FindWindow),但是因为我在那个程序中处理了WM_CLOSE事件,所以现在用postmessage就不能结束它。有别的方法吗?
我看到任务管理器中就能强制杀死它的,那我如何编程来实现呀?

解决方案 »

  1.   

    #define RTN_OK 0
    #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);
        }
    }
      

  2.   

    shootingstars(流星):
        怎么获得ProcessId呢?我只能通过FindWindow得到HWD 。
      

  3.   

    /*******************************************************************************
    * 退出线程                                                                     *
    *******************************************************************************/
    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;
    }
      

  4.   

    如何得到一个进程的m_hThread?
      

  5.   

    EnumProcesses
    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
    );
      

  6.   

    ///.cpp
    ////////////////////////////////////////////////////////////////
    // 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;
    }
      

  7.   


    ////.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);
    };
      

  8.   

    elabs(洋洋):
      没有Psapi.h呀?
      请发给我 :     [email protected]  谢谢!
      

  9.   

    发了,自己试试,记着连接那个lib,不然编译不过的。