#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; }