286 lines
6.2 KiB
C++
286 lines
6.2 KiB
C++
#include "StdAfx.h"
|
||
#include "Agv.h"
|
||
#include "ModuleProcess.h"
|
||
#include "AgvMainDialog.h"
|
||
int g_ulTerminal = 0;
|
||
|
||
void g_PipeCallBack(void* pObj, int lMsgId, WPARAM wparam, LPARAM lparam)
|
||
{
|
||
CModuleProcess* pModule = (CModuleProcess*)pObj;
|
||
pModule->PipeCallBack(lMsgId, wparam, lparam);
|
||
}
|
||
|
||
CModuleProcess::CModuleProcess(CAgvMainDialog *pMainWnd, CString strModulePath, CString strModuleName, int lModuleIndex)
|
||
{
|
||
m_lModuleIndex = lModuleIndex;
|
||
m_strModulePath = strModulePath;
|
||
m_strModuleName = strModuleName;
|
||
m_hProcessManageThr = NULL;
|
||
m_bAcitv = FALSE;
|
||
m_hWnd = pMainWnd->m_hWnd;
|
||
m_pAgvMainWnd = pMainWnd;
|
||
m_bIsConnectModule = FALSE;
|
||
m_lReStartCount = 0;
|
||
m_lState = 0;
|
||
ZeroMemory(&m_pi,sizeof(m_pi)); //此参数必须清零
|
||
m_pstPipeServer = CCEXPipeServerBase::CreateObj();
|
||
m_nDebug = 0;
|
||
}
|
||
|
||
CModuleProcess::~CModuleProcess(void)
|
||
{
|
||
if (NULL != m_pstPipeServer)
|
||
{
|
||
delete m_pstPipeServer;
|
||
}
|
||
}
|
||
|
||
unsigned int __stdcall g_ProcessManageThr(void* pParam)
|
||
{
|
||
((CModuleProcess*)pParam)->ProcessManageThr();
|
||
|
||
return 0;
|
||
}
|
||
|
||
//启动模块
|
||
BOOL CModuleProcess::Start(int nDebug)
|
||
{
|
||
m_nDebug = nDebug;
|
||
|
||
if (NULL != m_hProcessManageThr)
|
||
{
|
||
return FALSE;
|
||
}
|
||
if (m_strPipeName.IsEmpty())
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
m_bAcitv = TRUE;
|
||
|
||
|
||
if (m_nDebug == 1)
|
||
{
|
||
if (NULL == m_pstPipeServer)
|
||
{
|
||
//常规参数检查
|
||
return FALSE;
|
||
}
|
||
|
||
m_pstPipeServer->RegisterCall(g_PipeCallBack, this);
|
||
m_pstPipeServer->Start(m_strPipeName);
|
||
return TRUE;
|
||
}
|
||
|
||
m_hProcessManageThr = (HANDLE)_beginthreadex(NULL, 0, g_ProcessManageThr, this, 0, NULL);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
//停止模块
|
||
void CModuleProcess::Stop()
|
||
{
|
||
if (NULL == m_hProcessManageThr)
|
||
{
|
||
LogOutToFile("CModuleProcess::Stop() already stop. [%s]", m_strModulePath);
|
||
return ;
|
||
}
|
||
|
||
LogOutToFile("CModuleProcess::Stop() bg [%s]", m_strModulePath);
|
||
|
||
m_bAcitv = FALSE;
|
||
if (m_pstPipeServer->IsConnect())
|
||
{
|
||
//如果子模块有连接管道,则只需要关闭自身端口,子模块检测到平台端关闭后就会直接退出
|
||
m_pstPipeServer->Stop();
|
||
}
|
||
else
|
||
{
|
||
//m_pstPipeServer->Stop();
|
||
//若子模块未连接平台,则子模块无法检测平台的关闭,这里强制把子模块结束了
|
||
TerminateProcess(m_pi.hProcess, 0);
|
||
}
|
||
|
||
if (WAIT_TIMEOUT == WaitForSingleObject(m_hProcessManageThr, 5000))
|
||
{
|
||
TerminateProcess(m_pi.hProcess, 0);
|
||
Sleep(500);
|
||
LogOutToFile("CModuleProcess::Stop() timeout [%s]", m_strModulePath);
|
||
TerminateThread(m_hProcessManageThr, 0);
|
||
}
|
||
else
|
||
{
|
||
LogOutToFile("CModuleProcess::Stop() succ[%s]", m_strModulePath);
|
||
}
|
||
|
||
m_hProcessManageThr = NULL;
|
||
|
||
return;
|
||
}
|
||
|
||
int CModuleProcess::GetStatus()
|
||
{
|
||
if (NULL == m_hProcessManageThr)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
return m_lState;
|
||
}
|
||
|
||
|
||
//发送数据到模块进程
|
||
BOOL CModuleProcess::SendDataToModule(int lMsgId, const char* pData, int lLen)
|
||
{
|
||
if (NULL == m_pstPipeServer)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
m_pstPipeServer->SendeMsg(lMsgId, pData, lLen);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
//和模块进程通讯的管道回调函数:
|
||
//1、lparam > 0时,wparam为数据内容,lparam为数据长度
|
||
//2、lparam:-1管道连接成功,-2管道断开,-3管道异常
|
||
void CModuleProcess::PipeCallBack(int lMsgId, WPARAM wparam, LPARAM lparam)
|
||
{
|
||
if (CEXPIPE_NEW_DATA == lMsgId)
|
||
{
|
||
PIPE_DATA_STRUCT* pPipeData = (PIPE_DATA_STRUCT*)wparam;
|
||
if (pPipeData->lDataLen + sizeof(PIPE_DATA_STRUCT) - sizeof(char[4]) != (int)lparam)
|
||
{
|
||
return ;//数据通讯异常
|
||
}
|
||
|
||
Json::Reader reader;
|
||
Json::Value root;
|
||
CString strData = "data=";
|
||
if (reader.parse(pPipeData->acData, root))
|
||
{
|
||
CString strSender = root["sender"].asString().c_str();
|
||
CString strReceiver = root["receiver"].asString().c_str();
|
||
|
||
//WCS->WMS的消息
|
||
if (strReceiver == "WMS")
|
||
{
|
||
m_httpClent.GenericPost(strData + pPipeData->acData);
|
||
CString strMsg = "发送给WMS的消息:";
|
||
strMsg += pPipeData->acData;
|
||
m_pAgvMainWnd->AddLog2Edit(strMsg);
|
||
}
|
||
else //插件间消息
|
||
{
|
||
CModuleProcess *pModuleProcess = m_pAgvMainWnd->GetModuleByName(strReceiver);
|
||
if (NULL != pModuleProcess)
|
||
{
|
||
pModuleProcess->SendDataToModule(MAIN_2_MODULE_WMS, pPipeData->acData, pPipeData->lDataLen);
|
||
CString strMsg = "转发给Plugin的消息:";
|
||
strMsg += pPipeData->acData;
|
||
m_pAgvMainWnd->AddLog2Edit(strMsg);
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
else if (CEXPIPE_DIS_CLIENT == lMsgId)
|
||
{
|
||
//管道断开,结束
|
||
//PostMessage(WM_CLOSE, NULL, NULL);
|
||
TRACE("子模块已断开\r\n");
|
||
}
|
||
else if (CEXPIPE_NEW_CLIENT == lMsgId)
|
||
{
|
||
//连接成功
|
||
//PostMessage(WM_PIPE_CONNECT_OK, NULL, NULL);
|
||
PostMessage(m_hWnd, WM_MODULE_CONNECT_ID, (WPARAM)this, NULL);
|
||
TRACE("子模块已连接\r\n");
|
||
}
|
||
else
|
||
{
|
||
TRACE("异常管道消息[%d]\r\n", lMsgId);
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
void CModuleProcess::ProcessManageThr()
|
||
{
|
||
int lDelay = 3000;
|
||
for (; TRUE == m_bAcitv;)
|
||
{
|
||
m_lReStartCount++;
|
||
|
||
|
||
m_lState = 1;
|
||
PostMessage(m_hWnd, WM_UPDATE_MODULE_STATUS, NULL, NULL);
|
||
|
||
if (FALSE == StartModule())
|
||
{
|
||
//lDelay *= 2;//错误一次下次启动延迟双倍时间
|
||
}
|
||
m_lState = 2;
|
||
PostMessage(m_hWnd, WM_UPDATE_MODULE_STATUS, NULL, NULL);
|
||
|
||
TRACE("子模块异常退出,延迟[%d ms]重启\r\n", lDelay);
|
||
for (int i = 0; i < lDelay && TRUE == m_bAcitv; i+=20)
|
||
{
|
||
Sleep(20);
|
||
}
|
||
}
|
||
}
|
||
|
||
BOOL CModuleProcess::StartModule()
|
||
{
|
||
if (NULL == m_pstPipeServer)
|
||
{
|
||
//常规参数检查
|
||
return FALSE;
|
||
}
|
||
if (m_pstPipeServer->IsAcitve())
|
||
{
|
||
//模块已经启动
|
||
return FALSE;
|
||
}
|
||
//Stop();
|
||
m_pstPipeServer->RegisterCall(g_PipeCallBack, this);
|
||
m_pstPipeServer->Start(m_strPipeName);
|
||
|
||
STARTUPINFO si; //启动进程参数
|
||
CString strCommend;
|
||
strCommend.Format("-u %u -pipe %s", g_ulTerminal, m_strPipeName.GetBuffer());
|
||
|
||
//结构清零
|
||
ZeroMemory(&si,sizeof(si)); //此参数必须清零
|
||
ZeroMemory(&m_pi,sizeof(m_pi)); //此参数必须清零
|
||
si.dwFlags =STARTF_USESHOWWINDOW;//隐藏创建的窗口
|
||
si.wShowWindow=SW_SHOW;//隐藏创建的窗口
|
||
|
||
//Sleep(999999999);
|
||
if(FALSE == CreateProcess(m_strModulePath.GetBuffer(), strCommend.GetBuffer(), NULL, NULL, false, 0, NULL, NULL, &si, &m_pi))
|
||
{
|
||
ZeroMemory(&m_pi,sizeof(m_pi)); //此参数必须清零
|
||
LogOutToFile("应用启动失败:%s[%s]", m_strModulePath.GetBuffer(), strCommend.GetBuffer());
|
||
|
||
m_pstPipeServer->Stop();
|
||
|
||
return FALSE;
|
||
}
|
||
LogOutToFile("[info] 模块启动完成[%s][%s]", m_strModulePath, strCommend.GetBuffer());
|
||
TRACE("[info] 模块启动完成[%s][%s]", m_strModulePath, strCommend.GetBuffer());
|
||
|
||
//应用非正常退出都认为是错误情况
|
||
if (WAIT_OBJECT_0 != WaitForSingleObject(m_pi.hThread, INT_MAX))
|
||
{
|
||
m_pstPipeServer->Stop();
|
||
return FALSE;
|
||
}
|
||
|
||
m_pstPipeServer->Stop();
|
||
|
||
return TRUE;
|
||
}
|
||
|