⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 processlist.cpp

📁 wince6.0平台上的任务管理器,功能类似于windows的任务管理器. In order to develop applications for Windows Mobile 6.x from
💻 CPP
字号:
//#define BUG2  // Undefine to fix BUG2

#include "stdafx.h"
#include <stdexcept>
#include <tlhelp32.h>
#include "resource.h"
#include "Tools\Exception.h"
#include "ProcessList.h"
#include "VirtualMemory.h"
#include "HeapMemory.h"

#include "atlcom2.h"

CProcessList::CProcessList()
{
}

// CProcessList
HRESULT CProcessList::FinalConstruct()
{
	return S_OK;
}

void CProcessList::FinalRelease()
{
}

STDMETHODIMP CProcessList::InterfaceSupportsErrorInfo(REFIID riid)
{
	static const IID* arr[] = 
	{
		&IID_IProcessList
	};

	for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		if (InlineIsEqualGUID(*arr[i],riid))
			return S_OK;
	}
	return S_FALSE;
}

int CProcessList::Filter(unsigned int code, struct _EXCEPTION_POINTERS *ep)
{ 
    if (code == EXCEPTION_ACCESS_VIOLATION)
    { 
        return EXCEPTION_EXECUTE_HANDLER; 
    } else
    { 
        return EXCEPTION_CONTINUE_SEARCH; 
    }; 
} 

bool CProcessList::DoUpdate()
{
    // Make sure this happens thread-safe
    Windows::AutoCriticalSection lock(m_lock);

#ifdef DEBUG
    if (m_listOfProcesses.size() > 0)
    {
        ULONG m = m_listOfProcesses[0]->AddRef();
        ULONG n = m_listOfProcesses[0]->Release();
    }
#endif

    bool ok = false;
    HANDLE snapShot = INVALID_HANDLE_VALUE;
    // Need to use __try __except on ToolHelp API.
    // If a process is being destroyed (shutdown), the API crashes (AV on NULL pointer)
    // Can use try catch if /EHa compiler settings is used
//  __try
    try
    {
        snapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPNOHEAPS, 0);

        if (snapShot != INVALID_HANDLE_VALUE)
        {
            // Clear previous list
            m_listOfProcesses.clear();

            // Build new list
            PROCESSENTRY32 processEntry;
            processEntry.dwSize = sizeof(PROCESSENTRY32);
            BOOL ret = Process32First(snapShot, &processEntry);
            while (ret == TRUE)
            {
                VirtualMemory virtualMemory(
#if defined(UNDER_CE)
                    processEntry.th32ProcessID, processEntry.th32MemoryBase
#else
                    processEntry.th32ProcessID, 0 
#endif
                );
                HeapMemory heapMemory(processEntry.th32ProcessID);

				// We construct our own Process object
                CComObjectNoLock<CProcess>* processItem = new CComObjectNoLock<CProcess>();
                processItem->Init(_bstr_t(processEntry.szExeFile), 
                                 processEntry.th32ProcessID,
                                 processEntry.cntThreads,
#if defined(UNDER_CE)
                                 processEntry.th32MemoryBase,
#else
                                 0,
#endif
                                 heapMemory.GetHeapMemory(),
                                 virtualMemory.GetTotalMemory(),
                                 virtualMemory.GetCommittedMemory(),
                                 virtualMemory.GetReservedMemory(),
                                 0);
                m_listOfProcesses.insert(m_listOfProcesses.end(), IProcessPtr(processItem));
                ret = Process32Next(snapShot, &processEntry);
            }
#if defined(UNDER_CE)
            CloseToolhelp32Snapshot(snapShot);
#endif
        } else
        {
            DWORD err = GetLastError();
            LPVOID lpMsgBuf;
            FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                            NULL,
                            err,
                            0, // Default language
                            (LPTSTR) &lpMsgBuf,
                            0,
                            NULL);
            lpMsgBuf = lpMsgBuf;
        }
        ok = true;
//  } __except ( Filter(GetExceptionCode(), GetExceptionInformation()) )
    } catch (...)
    {
        ok = false;
        if (snapShot != INVALID_HANDLE_VALUE)
        {
#if defined(UNDER_CE)
            CloseToolhelp32Snapshot(snapShot);
#endif
        }
    }
    
#ifdef DEBUG
    if (m_listOfProcesses.size() > 0)
    {
        ULONG m = m_listOfProcesses[0]->AddRef();
        ULONG n = m_listOfProcesses[0]->Release();
    }
#endif

    return ok;
}

STDMETHODIMP CProcessList::Update(/*[out, retval]*/ VARIANT_BOOL *value)
{
    // Make sure this happens thread-safe
    Windows::AutoCriticalSection lock(m_lock);

    bool ret = DoUpdate();
    *value = (ret == true) ? VARIANT_TRUE : VARIANT_FALSE;

    return S_OK;
}

STDMETHODIMP CProcessList::get_Count(/*[out, retval]*/ LONG *value)
{
    // Make sure this happens thread-safe
    Windows::AutoCriticalSection lock(m_lock);

    *value = m_listOfProcesses.size();

    return S_OK;
}

STDMETHODIMP CProcessList::get__NewEnum(/*[out, retval]*/ IUnknown** retval)
{
    HRESULT hr = S_OK;
    VARIANT *processes = NULL;

    if (retval == NULL) 
        return E_POINTER;

    // Init in case we bail out prematurely
    *retval = NULL;

    // Make sure this happens thread-safe
    Windows::AutoCriticalSection lock(m_lock);

    // Make temporary variant vector needed to initialize the IEnumVARIANT
    size_t size = m_listOfProcesses.size();
    processes = new VARIANT[size];

    for (size_t i = 0; i < size; i++)
    {
        IProcess *process = m_listOfProcesses[i];
        ::VariantInit(&processes[i]);
        hr = process->QueryInterface (IID_IDispatch, reinterpret_cast<void**>(&processes[i].pdispVal));
        if (FAILED(hr))
        {
            size = 0;
            break;   // We interrupt and return an empty EnumVariant
        }
        processes[i].vt = VT_DISPATCH;
        process->Release();
    }
    
    // Assign it to a IEnumVARIANT COM object
#if defined(BUG2)
    typedef CComObject< CComEnum< IEnumVARIANT, &IID_IEnumVARIANT, VARIANT, _Copy<VARIANT> > > t_ComEnumVariant;
#else
    typedef CComObject< CComEnum2< IEnumVARIANT, &IID_IEnumVARIANT, VARIANT, _Copy<VARIANT> > > t_ComEnumVariant;
#endif
    t_ComEnumVariant *enumVariant = new t_ComEnumVariant;
    hr = enumVariant->Init (&processes[0], &processes[size], NULL, AtlFlagCopy); // Init will do a VariantCopy(), hence AddRef()

    delete [] processes;

    if (SUCCEEDED (hr)) 
        hr = enumVariant->QueryInterface (IID_IEnumVARIANT, reinterpret_cast<void**>(retval));

    if (FAILED (hr)) 
        delete enumVariant;

    return hr;
}

STDMETHODIMP CProcessList::Item (/*[in]*/ VARIANT index, /*[out, retval]*/ IProcess **retval)
{
    IProcess *process = NULL;
    HRESULT hr = S_OK;
    _variant_t vtLong;

    if (::VariantChangeType (&vtLong, &index, 0, VT_I4) == S_OK)
    {
        // Make sure this happens thread-safe
        Windows::AutoCriticalSection lock(m_lock);

        size_t i = vtLong.lVal; // 0-based index.

        if ((i >= 0) && (i < m_listOfProcesses.size ()))
        {
            process = m_listOfProcesses[i];
            hr = process->AddRef ();
            if (FAILED (hr))
            {
                process = NULL; // Do not trust process.
                return hr;
            }
        }
    }

    // Check if we have a hit
    if (process == NULL) 
    {
        Tools::Exception exception(CLSID_Process, IDS_ITEM_NOT_FOUND);
        return exception.GetException();
    }

    *retval = process;

    return S_OK;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -