C++ Windows进程管理

功能:

1.各个进程启动、挂起、恢复、停止等

2.监听进程的运行状态,进程退出(正常、非正常)时,通知用户

3.异步队列

4.线程安全

 

进程管理器类:

#ifndef __ProcessManager_ProcessManager_H__
#define __ProcessManager_ProcessManager_H__

#include "Process.h"

#define PROCESSMANAGER_AUTO_MUTEX      boost::recursive_mutex PROCESSMANAGER_AUTO_MUTEX_NAME;
#define PROCESSMANAGER_LOCK_AUTO_MUTEX boost::recursive_mutex::scoped_lock AutoMutexLock(PROCESSMANAGER_AUTO_MUTEX_NAME);

/** Process Manager
*/
class ProcessManager : public QObject, public Singleton<ProcessManager>
{
    Q_OBJECT
public:
    /** Default constructor.
     */
    ProcessManager(Log* pLog);

    /** Default destructor.
     */
    ~ProcessManager(void);

public:
    /** start
     */
    Process* Start(const string& strName, const string& strCmdLine, bool bShowWnd = true);

    /** suspend
     */
    void Suspend(Process* pProc);

    /** resume
     */
    void Resume(Process* pProc);

    /** stop
     */
    void Stop(Process* pProc);
    
    /** suspend all
     */
    void SuspendAll();
    
    /** resume all
     */
    void ResumeAll();

    /** stop all
     */
    void StopAll();

    /** Override standard Singleton retrieval.
     */
    static ProcessManager& GetSingleton(void);

    /** Override standard Singleton retrieval.
     */
    static ProcessManager* GetSingletonPtr(void);

protected slots:
    /** Notify finish
     */
    void _NoifyFinished(Process* pProc);

Q_SIGNALS:
    /** Fire finish
    */
    void _FireFinished(const string&);

private:
    typedef map<string, Process*> ProcessMap;
    ProcessMap m_Processs;

    Log*       m_pLog;

    PROCESSMANAGER_AUTO_MUTEX
};

#endif // __ProcessManager_ProcessManager_H__
#include "ProcessManager.h"


//-----------------------------------------------------------------------
template<> ProcessManager* Singleton<ProcessManager>::m_pSingleton = 0;

ProcessManager* ProcessManager::GetSingletonPtr(void)
{
    return m_pSingleton;
}

//-----------------------------------------------------------------------
ProcessManager& ProcessManager::GetSingleton(void)
{  
    assert(m_pSingleton); 
    return *m_pSingleton;  
}

//-----------------------------------------------------------------------
ProcessManager::ProcessManager(Log* pLog)
{
    if (pLog == NULL)
    {
        THROW_EXCEPTION("Log can not be null!", "ProcessManager");
    }

    m_pLog = pLog;
}

//-----------------------------------------------------------------------
ProcessManager::~ProcessManager(void)
{
    StopAll();
}

//-----------------------------------------------------------------------
Process* ProcessManager::Start( const string& strName, const string& strCmdLine, bool bShowWnd /*= true*/ )
{
    PROCESSMANAGER_LOCK_AUTO_MUTEX

    ProcessMap::iterator i = m_Processs.find(strName);
    if (i != m_Processs.end())
    {
        return i->second;
    }
    else
    {
        Process* pProc = new Process(strName, m_pLog);
        connect(pProc, SIGNAL(_FireFinished(Process*)), this, SLOT(_NoifyFinished(Process*)), Qt::QueuedConnection);
        m_Processs[strName] = pProc;

        pProc->Start(strCmdLine, bShowWnd);

        return pProc;
    }
}

//-----------------------------------------------------------------------
void ProcessManager::Suspend(Process* pProc)
{
    PROCESSMANAGER_LOCK_AUTO_MUTEX

    pProc->Suspend();
}

//-----------------------------------------------------------------------
void ProcessManager::Resume(Process* pProc)
{
    PROCESSMANAGER_LOCK_AUTO_MUTEX

    pProc->Resume();
}

//-----------------------------------------------------------------------
void ProcessManager::Stop(Process* pProc)
{
    PROCESSMANAGER_LOCK_AUTO_MUTEX

    pProc->Stop();
}

//-----------------------------------------------------------------------
void ProcessManager::SuspendAll()
{
    PROCESSMANAGER_LOCK_AUTO_MUTEX

    ProcessMap::iterator i = m_Processs.begin();
    for ( ; i != m_Processs.end(); ++i)
    {
        i->second->Suspend();
    }
}

//-----------------------------------------------------------------------
void ProcessManager::ResumeAll()
{
    PROCESSMANAGER_LOCK_AUTO_MUTEX

    ProcessMap::iterator i = m_Processs.begin();
    for ( ; i != m_Processs.end(); ++i)
    {
        i->second->Resume();
    }
}

//-----------------------------------------------------------------------
void ProcessManager::StopAll()
{
    PROCESSMANAGER_LOCK_AUTO_MUTEX

    ProcessMap::iterator i = m_Processs.begin();
    for ( ; i != m_Processs.end(); ++i)
    {
        i->second->Stop();
    }
}

//-----------------------------------------------------------------------
void ProcessManager::_NoifyFinished(Process* pProc)
{
    PROCESSMANAGER_LOCK_AUTO_MUTEX

    emit _FireFinished(pProc->GetName());

    ProcessMap::iterator i = m_Processs.find(pProc->GetName());
    if (i != m_Processs.end())
    {
        m_Processs.erase(i);
    }
    delete pProc;
}

 

进程类:

#ifndef __ProcessManager_Process_H__
#define __ProcessManager_Process_H__

#include "PreDefine.h"

#define PROCESS_AUTO_MUTEX      boost::recursive_mutex PROCESS_AUTO_MUTEX_NAME;
#define PROCESS_LOCK_AUTO_MUTEX boost::recursive_mutex::scoped_lock AutoMutexLock(PROCESS_AUTO_MUTEX_NAME);

/** Process
*/
class Process : public QObject
{
    Q_OBJECT

    friend class ProcessManager;
protected:
    /** Default constructor - used by ProcessManager.
        Warning Do not call directly
     */
    Process(const string& strName, Log* pLog);

    /** Default destructor.
     */
    ~Process();

public:
    /** start process
     */
    bool Start(const string& strCmdLine, bool bShowWnd = true);
    
    /** suspend process
     */
    void Suspend();

    /** resume process 
     */
    void Resume();

    /** stop process
     */
    void Stop();

    /** is process runing
     */
    bool IsRuning();

    /** get name
     */
    string GetName();

private:
    /** listen to process is stoped ?
     */
    void Listener();

Q_SIGNALS:
    /** Fire ProcessManager this process is stoped
     */
    void _FireFinished(Process*);

protected:
    /* Gets the last loading error
    */
    string ProcessError(void);

private:
    string m_strName;
    Log*   m_pLog;

    HANDLE m_hPId;
    HANDLE m_hTId;
    boost::thread* m_pListener;

    PROCESS_AUTO_MUTEX
};

#endif // __ProcessManager_Process_H__
#include "Process.h"

//-----------------------------------------------------------------------
Process::Process(const string& strName, Log* pLog)
{
    if (pLog == NULL)
    {
        THROW_EXCEPTION("Log can not be null!", "Process");
    }

    m_strName    = strName;
    m_pLog       = pLog;

    m_hPId       = NULL;
    m_hTId       = NULL;
    m_pListener  = NULL;
}

//-----------------------------------------------------------------------
Process::~Process()
{

}

//-----------------------------------------------------------------------
bool Process::Start(const string& strCmdLine, bool bShowWnd /** = true */)
{
    PROCESS_LOCK_AUTO_MUTEX

    if (m_hPId != NULL) 
    {
        //log
        m_pLog->LogMessage("Process " + m_strName + " is started.", LMT_OUTBAR);
        return true;
    }

    //-----------Create Process-----------
    STARTUPINFOA si;
    ZeroMemory(&si, sizeof(STARTUPINFOA));
    si.cb = sizeof(STARTUPINFOA);
    si.dwFlags       = STARTF_USESHOWWINDOW;
    si.wShowWindow = bShowWnd ? SW_SHOW : SW_HIDE;

    PROCESS_INFORMATION pi;
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

    BOOL bSuccess = CreateProcessA(NULL, (LPSTR)(strCmdLine.c_str()), NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
    if (!bSuccess) 
    {
        //log
        m_pLog->LogMessage("Could not start process " + m_strName + ".  System Error: " + ProcessError(), LMT_OUTBAR);

        //notify process manager to remove me
        emit _FireFinished(this);
        
        return false;
    }

    //log
    m_pLog->LogMessage("Start process " + m_strName + " successful.", LMT_OUTBAR);

    m_hPId = pi.hProcess;
    m_hTId = pi.hThread;

    //-----------Listener-----------
    boost::function0<void> listenerFunc = boost::bind(&Process::Listener, this);
    m_pListener = new boost::thread(listenerFunc);

    //-----------Resume-----------
    ResumeThread(pi.hThread);
    WaitForInputIdle(pi.hProcess, 5000);

    return true;
}

//-----------------------------------------------------------------------
void Process::Suspend()
{
    PROCESS_LOCK_AUTO_MUTEX

    if (m_hPId == NULL) return;

    SuspendThread(m_hTId);
}

//-----------------------------------------------------------------------
void Process::Resume()
{
    PROCESS_LOCK_AUTO_MUTEX

    if (m_hPId == NULL) return;

    ResumeThread(m_hTId);
}

//-----------------------------------------------------------------------
void Process::Stop()
{
    PROCESS_LOCK_AUTO_MUTEX

    if (m_hPId == NULL) return;

    //Kill Listener
    m_pListener->interrupt();
    m_pListener->detach();
    delete m_pListener;
    m_pListener = NULL;

    //Kill Process
    TerminateProcess(m_hPId, 0);
    m_hPId = NULL;
    m_hTId = NULL;

    //log
    m_pLog->LogMessage("Process " + m_strName + " is stoped.", LMT_OUTBAR);

    //notify process manager to remove me
    emit _FireFinished(this);
}

//-----------------------------------------------------------------------
bool Process::IsRuning()
{
    PROCESS_LOCK_AUTO_MUTEX

    if (m_hPId == NULL) return false;

    return true;
}

//-----------------------------------------------------------------------
string Process::GetName()
{
    return m_strName;
}

//-----------------------------------------------------------------------
void Process::Listener()
{
    try
    {
        WaitForSingleObject(m_hPId, INFINITE);

        {
            //local : avoid to always lock 
            PROCESS_LOCK_AUTO_MUTEX

            m_pListener->detach();
            delete m_pListener;
            m_pListener = NULL;

            m_hPId = NULL;
            m_hTId = NULL;

            //log
            m_pLog->LogMessage("Process " + m_strName + " is stoped.", LMT_OUTBAR);

            //notify process manager to remove me
            emit _FireFinished(this);
        }
    }
    catch(const boost::thread_interrupted&)
    {
        //interrupted
    }
    catch(...)
    {
        //other
    }
}

string Process::ProcessError( void )
{
    LPVOID lpMsgBuf; 
    FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 
                  NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR) &lpMsgBuf, 0, NULL); 

    string strError = (char*)lpMsgBuf;

    LocalFree(lpMsgBuf);

    return strError;
}

 

转载于:https://www.cnblogs.com/GuiltySpark/p/5133817.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值