Files
eUi/src/launcher/main.cpp
T
RCiRoot 9e2cd6eefc 优化了jsoneditdialog。
增加了对通讯检测的性能监控。
2025-10-17 10:02:32 +08:00

243 lines
9.6 KiB
C++

#include <windows.h>
#include "client/windows/handler/exception_handler.h"
#include <global.h>
#include <QApplication>
#include <QSystemSemaphore>
#include <QSharedMemory>
#include <QMessageLogger>//日志
#include <QDebug>
#include <qmessagebox.h>
#include <qpushbutton.h>
#include <qlineedit.h>
#include <qlabel.h>
#include <qcombobox.h>
#include <QMetaType>
#include <appCore.hpp>
#include <QGuiApplication>
#include <windows.h> // GetModuleFileName, ShellExecuteEx, SW_NORMAL 等
#include <tchar.h> // TCHAR 相关操作
#include <shellapi.h> // SHELLEXECUTEINFO 结构体
#include <iostream> // std::cout (如果需要打印信息)
#include <tlhelp32.h> // CreateToolhelp32Snapshot, Process32First, Process32Next
#include <filesystem> // std::filesystem::path
#include <GUI/mainwindow.h>
#pragma region 程序启动功能
// 获取当前exe文件名
std::string getCurrentExeName() {
char exePath[MAX_PATH];
GetModuleFileNameA(NULL, exePath, MAX_PATH);
std::filesystem::path path(exePath);
return path.filename().string();
}
// 枚举窗口回调函数,用于置顶指定进程的窗口
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) {
DWORD* targetPid = (DWORD*)lParam;
DWORD windowPid;
GetWindowThreadProcessId(hwnd, &windowPid);
if (windowPid == *targetPid && IsWindowVisible(hwnd)) {
// 将窗口置顶并激活
SetForegroundWindow(hwnd);
ShowWindow(hwnd, SW_RESTORE);
return FALSE; // 停止枚举
}
return TRUE; // 继续枚举
}
// 检查应用是否已在运行,如果是则置顶
bool appIsRuning(){
std::string currentExeName = getCurrentExeName();
DWORD currentPid = GetCurrentProcessId();
// 创建进程快照
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) {
return true; // 如果无法创建快照,允许启动
}
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
bool foundOtherInstance = false;
DWORD otherInstancePid = 0;
// 遍历进程
if (Process32First(hSnapshot, &pe32)) {
do {
// 比较进程名(忽略大小写)
if (_stricmp(pe32.szExeFile, currentExeName.c_str()) == 0 &&
pe32.th32ProcessID != currentPid) {
foundOtherInstance = true;
otherInstancePid = pe32.th32ProcessID;
break;
}
} while (Process32Next(hSnapshot, &pe32));
}
CloseHandle(hSnapshot);
if (foundOtherInstance) {
// 找到其他实例,将其置顶
EnumWindows(EnumWindowsProc, (LPARAM)&otherInstancePid);
return false; // 返回false表示已有实例在运行
}
return true; // 没有其他实例在运行
}
#pragma endregion
static bool dumpCallback(const wchar_t* dump_path,
const wchar_t* minidump_id,
void* context,
EXCEPTION_POINTERS* exinfo,
MDRawAssertionInfo* assertion,
bool succeeded) {
wprintf(L"Dump created at %s\\%s.dmp\n", dump_path, minidump_id);
return succeeded;
}
bool checkResourceExists(const QString& resourcePath) {
if (QFile::exists(resourcePath)) {
qDebug() << "文件存在:" << resourcePath;
return true;
}
else {
qDebug() << "文件不存在:" << resourcePath;
return false;
}
}
void connectSignalAndSlot(appCore* _core, MainWindow* _MainWindow, qtFuncBridge* bridge) {
QObject::connect(_core->_logService->getLogWidget(), &logToQtWidget::stdLogSignal,
_MainWindow->_logWidget, &logWidget::recvStdLogMsg);
QObject::connect(_core->_logService->getLogWidget(), &logToQtWidget::qtLogSignal,
_MainWindow->_logWidget, &logWidget::recvQtLogMsg);
QObject::connect(_core->_logService->getLogWidget(), &logToQtWidget::mainWindowStdLogSignal,
_MainWindow->_displayWidget, &displayWidget::recvMainWindowStdLogMsg);
QObject::connect(_core->_logService->getLogWidget(), &logToQtWidget::loadingWindow_appendConsoleLog,
_MainWindow, [=](const QString& text) {_MainWindow->_loadingWidget.appendConsoleLog(text); });
//BackEnd To Front
//等待界面
QObject::connect(bridge, &qtFuncBridge::loadingWindow_appendInitLog,
_MainWindow, [=](const QString& text, const QColor& color) {_MainWindow->_loadingWidget.appendInitLog(text, color); });
QObject::connect(bridge, &qtFuncBridge::loadingWindow_modifyLog,
_MainWindow, [=](int col, const QString& text, const QColor& color) {_MainWindow->_loadingWidget.modifyLog(col, text, color); });
QObject::connect(bridge, &qtFuncBridge::loadingWindow_clearLog,
_MainWindow, [=]() {_MainWindow->_loadingWidget.clearLog(); });
QObject::connect(bridge, &qtFuncBridge::pieWidgetAddNG,
_MainWindow, [=]() {_MainWindow->_displayWidget->_dsStatsWidget->addNg(); });
QObject::connect(bridge, &qtFuncBridge::pieWidgetAddOK,
_MainWindow, [=]() {_MainWindow->_displayWidget->_dsStatsWidget->addOK(); });
QObject::connect(bridge, &qtFuncBridge::histogramWidgetAddData,
_MainWindow, [=](std::vector<std::string>defects)
{_MainWindow->_displayWidget->_dayNightShiftHistogramWidget->addDefect(defects); });
QObject::connect(bridge, &qtFuncBridge::setPlcConnectionError,
_MainWindow, [=]() {_MainWindow->_displayWidget->_toolBarWidget->_ConnectionWidget->setPlcDisconnected(); });
QObject::connect(bridge, &qtFuncBridge::setPlcConnectionOk,
_MainWindow, [=]() {_MainWindow->_displayWidget->_toolBarWidget->_ConnectionWidget->setPlcConnected(); });
QObject::connect(bridge, &qtFuncBridge::setCamConnectionError,
_MainWindow, [=]() {_MainWindow->_displayWidget->_toolBarWidget->_ConnectionWidget->setCamDisconnected(); });
QObject::connect(bridge, &qtFuncBridge::setCamConnectionOk,
_MainWindow, [=]() {_MainWindow->_displayWidget->_toolBarWidget->_ConnectionWidget->setCamConnected(); });
//登录界面
QObject::connect(bridge, &qtFuncBridge::initResult,
_MainWindow, &MainWindow::recvInitFinished);
QObject::connect(bridge, &qtFuncBridge::initResult,
_core, &appCore::recvInitFinished);
//展示界面//主界面
QObject::connect(bridge, &qtFuncBridge::displayWidget_sendImg,
_MainWindow, &MainWindow::recvPixmapImageWidget);
//波形图
QObject::connect(bridge, &qtFuncBridge::summaryData_addData,
_MainWindow, &MainWindow::slot_summaryData_addData);
//排障
QObject::connect(bridge, &qtFuncBridge::runCommand_addBtn,
_MainWindow->_displayWidget->_runCommandWidget, &runCommandWidget::addBtn);
QObject::connect(_MainWindow->_displayWidget->_runCommandWidget,
&runCommandWidget::excuteCommandPreset,
[=](QString uuid) {_core->_backEnd.backend->excuteCliCommandPreset(uuid); });
QObject::connect(bridge, &qtFuncBridge::runCommand_addPlcValueViewer,
_MainWindow->_displayWidget->_runCommandWidget, &runCommandWidget::addPlcValueViewer);
QObject::connect(bridge, &qtFuncBridge::runCommand_refeshPlcValueViewer,
_MainWindow->_displayWidget->_runCommandWidget, &runCommandWidget::refreshPlcValueViewer);
//性能监测
QObject::connect(bridge, &qtFuncBridge::sendTriggerManagerLoopData,
_MainWindow->_displayWidget->_softwareDataDisplay, &softwareDataDisplay::onTriggerSateChanged);
}
int main(int argc, char* argv[])
{
//if (!isRunAsAdmin())
//{
// restartAsAdmin();
// exit(0);
//}
#pragma region 设置显示控制栏
HWND hWnd = GetConsoleWindow();
ShowWindow(hWnd, SW_SHOW);
#pragma endregion
#pragma region 启动breakPad崩溃捕获
std::wstring dumpPath = L"./dumps";
CreateDirectoryW(dumpPath.c_str(), nullptr);
// 初始化 breakpad
google_breakpad::ExceptionHandler eh(
dumpPath,
/*FilterCallback*/ nullptr,
dumpCallback,
/*context*/ nullptr,
/*install_handler*/ true
);
#pragma endregion
appCore _core;
auto& config = appConfig::getInstance();
config.consoleHandle = hWnd;
qtFuncBridge bridge; // 创建 C++ 对象
//检测是否已运行
if (appIsRuning() == false)
exit(0);
//////////
#pragma region 注册信号槽变量
qRegisterMetaType<cv::Mat*>("matPtr");
qRegisterMetaType<std::string>("stdString");
qRegisterMetaType<historyPack>("historyPack");
qRegisterMetaType<Qt::GlobalColor>("QtGlobalColor");
qRegisterMetaType<showImgPack>("showImgPack");
qRegisterMetaType<initStatus>("initStatus");
qRegisterMetaType<cv::Mat>("mat");
qRegisterMetaType<std::vector<std::string>>("vectorstring");
qRegisterMetaType<std::vector<std::pair<QString, int>>>("constvpqi");
#pragma endregion
QApplication a(argc, argv);
_core.initDatabase(); // 初始化数据库
QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + "/sqldrivers");
QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath());
MainWindow w(&config,&bridge, config.missionJson);
connectSignalAndSlot(&_core, &w, &bridge); // 连接信号和槽
w.show();
QThread::msleep(100);
// 创建后端对象
_core._backEnd.loadCore(config.dataBase,&bridge, config.missionJson["backend"]); // 加载核心功能
#if HIDE_CONSOLE
if (config.consoleHandle) {
ShowWindow(config.consoleHandle, SW_HIDE);
_core._logService->disableConsoleOutput();
}// 隐藏控制台窗口
#endif
w.registerQuitFunc([&]() {
_core._backEnd.releaseCore(); // 释放核心功能
QThread::msleep(100);
if (config.dataBase) delete config.dataBase;
config.dataBase = nullptr;
});
return a.exec();
}