C++ Windows进程管理

时间:2023-03-08 22:30:13
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 = ; 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, ); 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, );
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, , NULL); string strError = (char*)lpMsgBuf; LocalFree(lpMsgBuf); return strError;
}