feat:增加配置文件加载失败提醒;新增图标;完善对数据库和QProcess的处理

develop
lichongyuan 2 months ago
parent 5191cdeef4
commit 5b28791bbf

9
.gitignore vendored

@ -69,3 +69,12 @@ LaunchRegisterKey.vcxproj.filters
.vs/LaunchRegisterKey/v17/ipch/AutoPCH/e407f47aecf49074/UDPDATATHREAD.ipch .vs/LaunchRegisterKey/v17/ipch/AutoPCH/e407f47aecf49074/UDPDATATHREAD.ipch
debug/ debug/
release/ release/
.vs/
LaunchRe.82F475D3.tlog/
qmake/
LaunchRegisterKey.log
LaunchRegisterKey.sln
qt_work.log
vc141.pdb
vcpkg.applocal.log
CMakeLists.txt

@ -1,9 +1,12 @@
QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_LFLAGS_RELEASE = $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO
QT += core gui network sql QT += core gui network sql
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11 CONFIG += c++11
RC_ICONS = resources/icon.ico
# The following define makes your compiler emit warnings if you use # The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings # any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the # depend on your compiler). Please consult the documentation of the

@ -1,4 +1,5 @@
#include "common.h" #pragma execution_character_set("utf-8")
#include "common.h"
#include <fstream> #include <fstream>
#include <QDir> #include <QDir>
#include <QSettings> #include <QSettings>
@ -14,39 +15,47 @@ Common::Common()
bool Common::loadConfig(const QString &filePath) bool Common::loadConfig(const QString &filePath)
{ {
// 提取网络配置 try
QString iniFilePath = filePath + "/network.ini";
QSettings *configIni = new QSettings(iniFilePath, QSettings::IniFormat);
m_ipAddr = configIni->value("network/ip").toString();
m_srcPort = configIni->value("network/src_port").toInt();
m_dstPort = configIni->value("network/dst_port").toInt();
m_configFilePath = filePath + "/Config.json";
std::ifstream jsonStream(m_configFilePath.toLocal8Bit());
m_configJson = json::parse(jsonStream);
jsonStream.close();
// 提取工作模式
auto workmodes = m_configJson.at("workmode");
for (const auto& workmode : workmodes)
{ {
QString name = QString::fromStdString(workmode["name"]); // 提取网络配置
int index = workmode["index"]; QString iniFilePath = filePath + "/network.ini";
QString path = QString::fromStdString(workmode["exe_path"]); QSettings* configIni = new QSettings(iniFilePath, QSettings::IniFormat);
QString reworkPath = QString::fromStdString(workmode["rework_exe_path"]); m_ipAddr = configIni->value("network/ip").toString();
m_modeConfigs[index] = ModeConfig{index, name, path, reworkPath}; m_srcPort = configIni->value("network/src_port").toInt();
m_dstPort = configIni->value("network/dst_port").toInt();
m_configFilePath = filePath + "/Config.json";
std::ifstream jsonStream(m_configFilePath.toLocal8Bit());
m_configJson = json::parse(jsonStream);
jsonStream.close();
// 提取工作模式
auto workmodes = m_configJson.at("workmode");
for (const auto& workmode : workmodes)
{
QString name = QString::fromStdString(workmode["name"]);
int index = workmode["index"];
QString path = QString::fromStdString(workmode["exe_path"]);
QString reworkPath = QString::fromStdString(workmode["rework_exe_path"]);
m_modeConfigs[index] = ModeConfig{ index, name, path, reworkPath };
}
// 提取产品配置
auto products = m_configJson.at("products");
for (const auto& product : products)
{
int index = product["index"];
bool selected = product["selected"];
int mode = product["mode"];
QString formatStr = QString::fromStdString(product["format"]);
m_productConfigs[index] = ProductConfig{ index, static_cast<Mode>(mode), selected, formatStr };
}
FilterSelectedProducts();
return true;
} }
// 提取产品配置 catch(const std::exception& e)
auto products = m_configJson.at("products"); {
for (const auto& product : products) LError(QString("Load config file error: %1").arg(e.what()));
{ return false;
int index = product["index"];
bool selected = product["selected"];
int mode = product["mode"];
QString formatStr = QString::fromStdString(product["format"]);
m_productConfigs[index] = ProductConfig{index, static_cast<Mode>(mode), selected, formatStr};
} }
FilterSelectedProducts();
return true;
} }
bool Common::saveConfig(const QMap<int, ProductConfig> &productsCfg, const QMap<int, ModeConfig> &workmodeCfg) bool Common::saveConfig(const QMap<int, ProductConfig> &productsCfg, const QMap<int, ModeConfig> &workmodeCfg)
@ -79,6 +88,18 @@ int Common::getDstPort() const
return m_dstPort; return m_dstPort;
} }
const QString Common::getCurrWorkModeStr() const
{
if (m_currentMode.load() == -1)
{
return getWorkModeStr(-1);
}
QString reStr = m_isRepair.load() == 1 ? "反修" : "正常";
QString logStr = QString("%1-%2").arg(getWorkModeStr(m_currentMode.load())).arg(reStr);
return logStr;
}
bool Common::saveConfig() bool Common::saveConfig()
{ {
std::ofstream outFile(m_configFilePath.toLocal8Bit()); std::ofstream outFile(m_configFilePath.toLocal8Bit());
@ -156,3 +177,23 @@ void Common::setCurrentWorkMode(const int workMode)
{ {
m_currentMode.store(workMode); m_currentMode.store(workMode);
} }
bool Common::getRepairFlag() const
{
return m_isRepair.load();
}
void Common::setRepairFlag(const bool isRepair)
{
m_isRepair.store(isRepair);
}
QString Common::getWorkModeStr(int mode)
{
static QMap<int, QString> modeMap = { {-1, "未连接"}, {2, "GLOBAL_M2M"}, {3, "LOCAL_M2M"}};
if (!modeMap.contains(mode))
{
return "unknown mode";
}
return modeMap[mode];
}

@ -9,6 +9,8 @@
#include "nlohmann/json.hpp" #include "nlohmann/json.hpp"
#include "EasySpdLog.h" #include "EasySpdLog.h"
#define TEST_MODE
class Common : public QObject, public Singleton<Common> class Common : public QObject, public Singleton<Common>
{ {
Q_OBJECT Q_OBJECT
@ -25,6 +27,7 @@ public:
// 获取端口号 // 获取端口号
int getSrcPort() const; int getSrcPort() const;
int getDstPort() const; int getDstPort() const;
const QString getCurrWorkModeStr() const;
// 获取产品配置 // 获取产品配置
QMap<int, ProductConfig> getProductConfigs(); QMap<int, ProductConfig> getProductConfigs();
// 设置产品配置 // 设置产品配置
@ -40,6 +43,11 @@ public:
// 设置当前工作模式 // 设置当前工作模式
void setCurrentWorkMode(const int workMode); void setCurrentWorkMode(const int workMode);
bool getRepairFlag() const;
void setRepairFlag(const bool isRepair);
static QString getWorkModeStr(int mode);
signals: signals:
private: private:
@ -52,12 +60,14 @@ private:
nlohmann::json m_configJson{}; nlohmann::json m_configJson{};
QString m_currentWorkPath{}; // 当前工作路径 QString m_currentWorkPath{}; // 当前工作路径
std::atomic<int> m_currentMode{ -1 }; // 当前正在进行的工作模式 std::atomic<int> m_currentMode{ -1 }; // 当前正在进行的工作模式
std::atomic<bool> m_isRepair{ false };
QString m_ipAddr{}; QString m_ipAddr{};
int m_dstPort{}; int m_dstPort{};
int m_srcPort{}; int m_srcPort{};
QMap<int, ModeConfig> m_modeConfigs{}; // 模式配置 QMap<int, ModeConfig> m_modeConfigs{}; // 模式配置
QMap<int, ProductConfig> m_productConfigs{}; // 产品配置 QMap<int, ProductConfig> m_productConfigs{}; // 产品配置
QMap<QString, Mode> m_selectedProduct{}; // 选择的产品 QMap<QString, Mode> m_selectedProduct{}; // 选择的产品
std::atomic<bool> m_isLockSNLineEdit{false};
}; };
#endif // COMMON_H #endif // COMMON_H

@ -1,7 +1,8 @@
#include "widget.h" #pragma execution_character_set("utf-8")
#include "widget.h"
#include <QApplication> #include <QApplication>
#include <QMessageBox>
#include "common.h" #include "common.h"
#include "EasySpdLog.h" #include "EasySpdLog.h"
@ -13,7 +14,11 @@ int main(int argc, char *argv[])
SetLogger(loggerPath.data()); SetLogger(loggerPath.data());
// 加载配置文件 // 加载配置文件
QString filePath = QApplication::applicationDirPath() + "/config"; QString filePath = QApplication::applicationDirPath() + "/config";
Common::GetInstance()->loadConfig(filePath); if (!Common::GetInstance()->loadConfig(filePath))
{
QMessageBox::warning(nullptr, "错误", "配置文件加载失败!\n 请检查配置文件是否存在或格式是否正确!");
return 0;
}
// //
Widget w; Widget w;
w.move(0, 0); w.move(0, 0);

@ -1,4 +1,5 @@
#include "udpdatahandler.h" #pragma execution_character_set("utf-8")
#include "udpdatahandler.h"
#include <QHostAddress> #include <QHostAddress>
#include "common.h" #include "common.h"
#include "EasySpdLog.h" #include "EasySpdLog.h"
@ -91,6 +92,8 @@ void UdpDataHandler::recvData(const QByteArray &data)
{ {
emit GetDoneSig(ret); emit GetDoneSig(ret);
} }
QString snMsg = QString("590200");
m_udpWorker->sendData(snMsg.toLocal8Bit(), m_hostAddr, Common::GetInstance()->getDstPort());
break; break;
} }
default: default:

@ -2,5 +2,7 @@
<qresource prefix="/"> <qresource prefix="/">
<file>resources/folding.png</file> <file>resources/folding.png</file>
<file>resources/unfolding.png</file> <file>resources/unfolding.png</file>
<file>resources/icon.ico</file>
<file>resources/icon.png</file>
</qresource> </qresource>
</RCC> </RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

@ -18,7 +18,7 @@ void CountdownMessageBox::showCountdownMessageBox(QWidget *parent, int timeoutSe
{ {
CountdownMessageBox msgBox(timeoutSeconds, parent); CountdownMessageBox msgBox(timeoutSeconds, parent);
msgBox.setWindowTitle(title); msgBox.setWindowTitle(title);
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.exec(); msgBox.exec();
} }

@ -163,6 +163,7 @@ void SettingWgt::onCheckBoxStateChanged(int index)
void SettingWgt::SelectPathButton_clicked(int index, bool isRework) void SettingWgt::SelectPathButton_clicked(int index, bool isRework)
{ {
LTrace("Function enter");
// 定义选择的路径和是否是 reworkPath 的标志 // 定义选择的路径和是否是 reworkPath 的标志
QString exe_path = QFileDialog::getOpenFileName(this, tr("选择可执行程序"), QString exe_path = QFileDialog::getOpenFileName(this, tr("选择可执行程序"),
QCoreApplication::applicationDirPath(), QCoreApplication::applicationDirPath(),
@ -183,6 +184,7 @@ void SettingWgt::SelectPathButton_clicked(int index, bool isRework)
void SettingWgt::on_pushButton_ok_clicked() void SettingWgt::on_pushButton_ok_clicked()
{ {
LTrace("Function enter");
for (int i = 0 ; i < m_productNums; ++i) for (int i = 0 ; i < m_productNums; ++i)
{ {
m_productsCfg[i + 1].selected = m_selectCheckBoxes[i]->isChecked(); m_productsCfg[i + 1].selected = m_selectCheckBoxes[i]->isChecked();

@ -2,14 +2,20 @@
#include "widget.h" #include "widget.h"
#include "ui_widget.h" #include "ui_widget.h"
#include <windows.h>
#include <tlhelp32.h>
#include <QDateTime>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QMessageBox> #include <QMessageBox>
#include <QEventLoop> #include <QEventLoop>
#include <QSqlDatabase>
#include <QSqlQuery> #include <QSqlQuery>
#include <QSqlError> #include <QSqlError>
#include <QProcess> #include <QProcess>
#include <QDir> #include <QDir>
#include <QRegularExpression>
#include "countdownmessagebox.h" #include "countdownmessagebox.h"
#include "common.h" #include "common.h"
@ -23,7 +29,6 @@ Widget::Widget(QWidget *parent)
, m_settingDlg(new SettingWgt(this)) , m_settingDlg(new SettingWgt(this))
, m_udpDataThread(new UdpDataHandler(this)) , m_udpDataThread(new UdpDataHandler(this))
, m_showSetting(false) , m_showSetting(false)
, m_isSwitching(false)
{ {
ui->setupUi(this); ui->setupUi(this);
@ -31,18 +36,27 @@ Widget::Widget(QWidget *parent)
connect(m_settingDlg, &SettingWgt::SettingFinishSig, this, &Widget::on_pushButton_setting_clicked); connect(m_settingDlg, &SettingWgt::SettingFinishSig, this, &Widget::on_pushButton_setting_clicked);
connect(m_udpDataThread, &UdpDataHandler::GetDoneSig, this, &Widget::RegisterDoneSlot); connect(m_udpDataThread, &UdpDataHandler::GetDoneSig, this, &Widget::RegisterDoneSlot);
connect(m_udpDataThread, &UdpDataHandler::GetConnStatusSig, this, &Widget::GetConnStatusSlot); connect(m_udpDataThread, &UdpDataHandler::GetConnStatusSig, this, &Widget::GetConnStatusSlot);
addLogItem("程序初始化成功!");
ProcessJudgment();
} }
Widget::~Widget() Widget::~Widget()
{ {
delete ui; delete ui;
if (m_db.isOpen())
{
m_db.close();
QSqlDatabase::removeDatabase(QSqlDatabase::defaultConnection);
}
} }
void Widget::initUI() void Widget::initUI()
{ {
this->setWindowTitle(""); this->setWindowTitle("LaunchRegisterKey");
//this->setWindowFlags(Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint); this->setWindowFlags(Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint);
this->setWindowFlags(Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint); //this->setWindowFlags(Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint);
this->setWindowIcon(QIcon(":/resources/icon.ico"));
ui->list_log->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->list_log->setEditTriggers(QAbstractItemView::NoEditTriggers);
QHBoxLayout *layout = new QHBoxLayout(this); QHBoxLayout *layout = new QHBoxLayout(this);
layout->addWidget(m_settingDlg); layout->addWidget(m_settingDlg);
@ -54,7 +68,11 @@ void Widget::initUI()
void Widget::setSNLineEditFocus() void Widget::setSNLineEditFocus()
{ {
// 全选LineEdit并且焦点放在LineEdit上 // 全选LineEdit并且焦点放在LineEdit上
ui->lineEdit_snId->selectAll(); #ifdef TEST_MODE
QString tmpSn = ui->lineEdit_snId->text();
ui->lineEdit_snId->setText("1234567890123456");
#endif
ui->lineEdit_snId->clear();
ui->lineEdit_snId->setFocus(); ui->lineEdit_snId->setFocus();
} }
@ -63,6 +81,7 @@ int Widget::checkSNId(const QString &snId)
if (snId.isEmpty()) if (snId.isEmpty())
{ {
QMessageBox::warning(this, "产品SN错误", "产品SN为空! 请重新扫码!"); QMessageBox::warning(this, "产品SN错误", "产品SN为空! 请重新扫码!");
addLogItem("产品SN为空! 请重新扫码!");
LWarn("Product SN id is empty!"); LWarn("Product SN id is empty!");
return SNEmptyError; return SNEmptyError;
} }
@ -70,6 +89,7 @@ int Widget::checkSNId(const QString &snId)
if (reg.indexIn(snId) != -1) if (reg.indexIn(snId) != -1)
{ {
QMessageBox::information(this,"提示",QString("产品SN(%1)包含小写! 请重新扫码!").arg(snId)); QMessageBox::information(this,"提示",QString("产品SN(%1)包含小写! 请重新扫码!").arg(snId));
addLogItem(QString("产品SN(%1)包含小写! 请重新扫码!").arg(snId));
LWarn("Product SN contains lowercase!"); LWarn("Product SN contains lowercase!");
ui->lineEdit_snId->setText(""); ui->lineEdit_snId->setText("");
return SNLowerCaseError; return SNLowerCaseError;
@ -77,6 +97,7 @@ int Widget::checkSNId(const QString &snId)
if (snId.contains(" ")) if (snId.contains(" "))
{ {
QMessageBox::information(this,"提示",QString("产品SN(%1)包含空格! 请重新扫码!").arg(snId)); QMessageBox::information(this,"提示",QString("产品SN(%1)包含空格! 请重新扫码!").arg(snId));
addLogItem(QString("产品SN(%1)包含空格! 请重新扫码!").arg(snId));
LWarn("Product SN contains Spaces!"); LWarn("Product SN contains Spaces!");
ui->lineEdit_snId->setText(""); ui->lineEdit_snId->setText("");
return SNSpaceError; return SNSpaceError;
@ -86,15 +107,22 @@ int Widget::checkSNId(const QString &snId)
int Widget::startIECSProgram(const QString& workPath, const QString& snId) int Widget::startIECSProgram(const QString& workPath, const QString& snId)
{ {
LInfo("Function enter");
QProcess *process = new QProcess(this); QProcess *process = new QProcess(this);
process->start(workPath); connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
process, &QProcess::deleteLater);
// 使用 cmd.exe 来启动进程并使用 start 命令使其脱离父进程
QString command = QString("cmd.exe /C start \"\" \"%1\"").arg(workPath);
process->start(command);
if (!process->waitForStarted()) if (!process->waitForStarted())
{ {
LError("Failed to start the program with arguments:{}", process->errorString()); LError("Failed to start the program with arguments: {}", process->errorString());
process->deleteLater();
addLogItem(QString("%1启动失败").arg(workPath));
return ExecIECSError; return ExecIECSError;
} }
m_udpDataThread->sendSnId(snId); LInfo("Process started: {}", workPath);
m_isSwitching = false;
return NoError; return NoError;
} }
@ -113,19 +141,31 @@ int Widget::checkForRepairProgram(const int mode, const QString& sn, bool& isFin
int Widget::databaseQuery(const QString& databasePath, const QString& deviceSn, bool& isFind) int Widget::databaseQuery(const QString& databasePath, const QString& deviceSn, bool& isFind)
{ {
// 创建和打开 SQLite 数据库 // 静态变量来保存上一次使用的数据库路径
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); static QString previousDatabasePath;
db.setDatabaseName(databasePath); // 使用传入的数据库路径 // 如果数据库路径发生变动,关闭之前的连接并移除数据库
if (m_db.isOpen() && previousDatabasePath != databasePath) {
m_db.close();
QSqlDatabase::removeDatabase(QSqlDatabase::defaultConnection);
}
if (!db.open()) // 如果数据库尚未打开或路径已变动,重新打开数据库
{ if (!m_db.isOpen() || previousDatabasePath != databasePath) {
LError("Failed to open database:{}", db.lastError().text()); m_db = QSqlDatabase::addDatabase("QSQLITE");
isFind = false; m_db.setDatabaseName(databasePath); // 使用传入的数据库路径
return DatabaseOpenError;
if (!m_db.open()) {
LError("Failed to open database:{}", m_db.lastError().text());
isFind = false;
return DatabaseOpenError;
}
// 更新路径
previousDatabasePath = databasePath;
} }
// 创建查询对象 // 创建查询对象
QSqlQuery query(db); QSqlQuery query(m_db);
// 准备 SQL 查询 // 准备 SQL 查询
query.prepare("SELECT COUNT(1) FROM history WHERE device_sn = :device_sn;"); query.prepare("SELECT COUNT(1) FROM history WHERE device_sn = :device_sn;");
@ -135,44 +175,209 @@ int Widget::databaseQuery(const QString& databasePath, const QString& deviceSn,
if (!query.exec()) { if (!query.exec()) {
LError("Failed to execute query:{}", query.lastError().text()); LError("Failed to execute query:{}", query.lastError().text());
isFind = false; isFind = false;
db.close();
QSqlDatabase::removeDatabase(QSqlDatabase::defaultConnection);
return DatabaseSelectError; return DatabaseSelectError;
} }
// 处理查询结果 // 处理查询结果
if (query.next()) if (query.next()) {
{
int count = query.value(0).toInt(); int count = query.value(0).toInt();
isFind = (count > 0); isFind = (count > 0);
db.close();
QSqlDatabase::removeDatabase(QSqlDatabase::defaultConnection);
return NoError; return NoError;
} }
isFind = false; isFind = false;
db.close();
QSqlDatabase::removeDatabase(QSqlDatabase::defaultConnection);
return DatabaseUnknownError; return DatabaseUnknownError;
} }
// 判断是否为单板 SN
static bool isSingleBoardSN(const QString& sn) {
// 单板 SN 格式9位前缀-固定12位尾数
QRegularExpression regex("^\\d{9}-[A-Z0-9]{12}$");
return regex.match(sn).hasMatch();
}
// 判断是否为整机 SN
static bool isCompleteMachineSN(const QString& sn) {
// 整机 SN 格式前25位前缀-固定8位尾数
QRegularExpression regex("^.{25}[A-Z0-9]{10,}$");
return sn.contains('#') && regex.match(sn).hasMatch();
}
bool Widget::identifyProduct(const QString &sn, int &mode)
{
const auto selectedProducts = Common::GetInstance()->getSelectedProducts();
if (isSingleBoardSN(sn))
{
QString productKey = sn.mid(9); // 提取单板 SN 的尾数部分
if (selectedProducts.contains(productKey))
{
mode = selectedProducts[productKey];
return true; // 返回匹配的产品名称
}
}
else if (isCompleteMachineSN(sn))
{
QString productKey = sn.mid(25); // 提取整机 SN 的尾数部分
if (selectedProducts.contains(productKey))
{
mode = selectedProducts[productKey];
return true; // 返回匹配的产品名称
}
}
return false;
}
void Widget::RegisterDoneSlot(bool ret) void Widget::RegisterDoneSlot(bool ret)
{ {
qDebug()<<"11111"; if (ret)
{
addLogItem("注KEY成功");
}
else
{
addLogItem("注KEY失败请检查对应程序注KEY详情");
}
ui->lineEdit_snId->setEnabled(true); ui->lineEdit_snId->setEnabled(true);
ui->pushButton_sendSnId->setEnabled(true);
setSNLineEditFocus();
} }
void Widget::GetConnStatusSlot(bool ret) void Widget::GetConnStatusSlot(bool ret)
{ {
if (!ret && !m_isSwitching) if (ret)
{ {
qDebug()<<"ret:"<<ret<<",m_isSwitching:"<<m_isSwitching; //Common::GetInstance()->
ui->lineEdit_snId->setEnabled(true); setWindowTitle(QString("LaunchRegisterKey-已连接"));
}
else
{
setWindowTitle("LaunchRegisterKey-未连接");
} }
} }
// 辅助函数:比较进程路径和目标路径
static bool isMatchingProcess(const QString& processPath, const QString& targetPath) {
return processPath.compare(targetPath, Qt::CaseInsensitive) == 0;
}
bool Widget::ProcessJudgment()
{
// 创建一个快照来获取当前系统的所有进程
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
qWarning() << "Failed to create process snapshot.";
return false;
}
PROCESSENTRY32 pe32{};
pe32.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hProcessSnap, &pe32))
{
qWarning() << "Failed to retrieve process information.";
CloseHandle(hProcessSnap);
return false;
}
const auto& workModeCfgs = Common::GetInstance()->getWorkModeConfigs();
do {
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pe32.th32ProcessID);
if (!hProcess)
{
continue; // 无法打开进程,继续下一个进程
}
WCHAR exePath[MAX_PATH];
DWORD size = MAX_PATH;
if (QueryFullProcessImageName(hProcess, 0, exePath, &size))
{
QString processPath = QDir::fromNativeSeparators(QString::fromWCharArray(exePath));
for (const auto& workmodeCfg : workModeCfgs)
{
int matchedType = -1; // 用于保存匹配的路径类型
if (isMatchingProcess(processPath, workmodeCfg.workPath))
{
matchedType = 0; // workPath 匹配
}
else if (isMatchingProcess(processPath, workmodeCfg.reworkPath))
{
matchedType = 1; // reworkPath 匹配
}
if (matchedType != -1)
{
Common::GetInstance()->setCurrentWorkMode(workmodeCfg.index);
Common::GetInstance()->setRepairFlag(matchedType == 1); // 如果是 reworkPath设置为 true
QString logStr = QString("正在使用%1").arg(Common::GetInstance()->getCurrWorkModeStr());
addLogItem(logStr);
qDebug() << "Matching process found:"
<< QString::fromWCharArray(pe32.szExeFile)
<< "PID:" << pe32.th32ProcessID
<< "Path:" << processPath
<< "Matched Type:" << (matchedType == 0 ? "workPath" : "reworkPath");
CloseHandle(hProcess);
CloseHandle(hProcessSnap);
return true;
}
}
}
CloseHandle(hProcess); // 确保句柄被关闭
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
qDebug() << "No matching process found.";
return false;
}
bool Widget::isProcessRunningWithName(const QString& processNamePart)
{
// 创建一个快照来获取当前系统的所有进程
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) {
qWarning() << "Failed to create process snapshot.";
return false;
}
// 初始化进程信息结构体
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
// 获取第一个进程信息
if (!Process32First(hProcessSnap, &pe32)) {
qWarning() << "Failed to retrieve process information.";
CloseHandle(hProcessSnap);
return false;
}
// 遍历所有进程
do {
// 将进程名称转换为QString
QString processName = QString::fromWCharArray(pe32.szExeFile);
// 判断进程名称是否包含指定字符串
if (processName.contains(processNamePart, Qt::CaseInsensitive)) {
qDebug() << "Found matching process:" << processName;
CloseHandle(hProcessSnap);
return true; // 找到匹配的进程,返回 true
}
} while (Process32Next(hProcessSnap, &pe32));
// 关闭快照句柄
CloseHandle(hProcessSnap);
return false;
}
void Widget::on_pushButton_setting_clicked() void Widget::on_pushButton_setting_clicked()
{ {
static auto initSize = this->size();
if (ui->widget_setting->isHidden()) if (ui->widget_setting->isHidden())
{ {
ui->pushButton_setting->setIcon(QIcon(":/resources/folding.png")); ui->pushButton_setting->setIcon(QIcon(":/resources/folding.png"));
@ -188,7 +393,7 @@ void Widget::on_pushButton_setting_clicked()
ui->widget_setting->hide(); ui->widget_setting->hide();
int currentWidth = this->width(); int currentWidth = this->width();
this->adjustSize(); this->adjustSize();
this->resize(currentWidth, this->height()); // 只保持高度变化 this->resize(initSize); // 只保持高度变化
setSNLineEditFocus(); setSNLineEditFocus();
} }
} }
@ -199,16 +404,19 @@ void Widget::addLogItem(const QString &text)
{ {
delete ui->list_log->takeItem(0); delete ui->list_log->takeItem(0);
} }
ui->list_log->addItem(text); // 添加新条目 QString dateTimeStr = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss");
ui->list_log->addItem(dateTimeStr + " " + text); // 添加新条目
ui->list_log->scrollToBottom(); // 滚动到底部
} }
int Widget::switchProgram(const QString snId, const int mode, const bool isRepair) int Widget::switchProgram(const QString snId, const int mode, const bool isRepair)
{ {
LTrace("Function enter");
static bool isFirstRepair = true; static bool isFirstRepair = true;
if (isRepair && isFirstRepair) if (isRepair && isFirstRepair)
{ {
isFirstRepair = false; isFirstRepair = false;
CountdownMessageBox::showCountdownMessageBox(this, 3, "正在切换返修程序包!"); CountdownMessageBox::showCountdownMessageBox(this, 3, "启用返修程序包!");
} }
else if (!isRepair) else if (!isRepair)
{ {
@ -220,13 +428,38 @@ int Widget::switchProgram(const QString snId, const int mode, const bool isRepai
QTimer *timer = new QTimer(this); QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, [this, timer, snId, workPath]() { connect(timer, &QTimer::timeout, this, [this, timer, snId, workPath]() {
static int times = 0;
if (Common::GetInstance()->getCurrentWorkMode() == -1) if (Common::GetInstance()->getCurrentWorkMode() == -1)
{ {
m_isSwitching = true;
m_udpDataThread->stopClose(); m_udpDataThread->stopClose();
timer->stop(); // 停止定时器 if (!isProcessRunningWithName("IECS"))
// 启动 IECS 程序 {
startIECSProgram(workPath, snId); timer->stop(); // 停止定时器
times = 0;
// 启动 IECS 程序
if (startIECSProgram(workPath, snId) != NoError)
{
ui->lineEdit_snId->setEnabled(true);
ui->pushButton_sendSnId->setEnabled(true);
QMessageBox::warning(this, "程序启动失败!", QString("启动%1失败请检查程序路径").arg(workPath));
return;
}
// 发送 SN ID 和记录日志
m_udpDataThread->sendSnId(snId);
addLogItem(QString("已发送产品SN%1").arg(snId));
}
else
{
times++;
if (times >= 10)
{
times = 0;
timer->stop();
ui->lineEdit_snId->setEnabled(true);
ui->pushButton_sendSnId->setEnabled(true);
QMessageBox::warning(this, "程序启动失败!", QString("启动%1失败进程已存在").arg(workPath));
}
}
} }
}); });
timer->start(1000); timer->start(1000);
@ -235,6 +468,7 @@ int Widget::switchProgram(const QString snId, const int mode, const bool isRepai
void Widget::on_lineEdit_snId_returnPressed() void Widget::on_lineEdit_snId_returnPressed()
{ {
LTrace("Function enter");
QString snId = ui->lineEdit_snId->text(); QString snId = ui->lineEdit_snId->text();
int ret = 0; int ret = 0;
ret = checkSNId(snId); ret = checkSNId(snId);
@ -243,45 +477,44 @@ void Widget::on_lineEdit_snId_returnPressed()
LError("checkSNId error!code:{}", ret); LError("checkSNId error!code:{}", ret);
return; return;
} }
const auto selectedProducts = Common::GetInstance()->getSelectedProducts(); int snMode = -1;
QString productFormat{}; if (!identifyProduct(snId, snMode))
for (auto& products : selectedProducts.keys())
{
if (snId.contains(products))
{
productFormat = products;
break;
}
}
if (productFormat.isEmpty())
{ {
QMessageBox::information(this, "警告", "当前SN与启用设值SN不匹配请检查设置或重新扫码"); QMessageBox::information(this, "警告", "当前SN与启用设值SN不匹配请检查设置或重新扫码");
return; return;
} }
ui->lineEdit_snId->setEnabled(false); ui->lineEdit_snId->setEnabled(false);
ui->pushButton_sendSnId->setEnabled(false);
LInfo("SN ID:{}, Mode:{}", snId, snMode);
auto currWorkMode = Common::GetInstance()->getCurrentWorkMode(); auto currWorkMode = Common::GetInstance()->getCurrentWorkMode();
bool repairFlag = Common::GetInstance()->getRepairFlag();
bool isRepair = false; bool isRepair = false;
// 查找数据库,判断是否需要返修程序 // 查找数据库,判断是否需要返修程序
ret = checkForRepairProgram(selectedProducts[productFormat], snId, isRepair); ret = checkForRepairProgram(snMode, snId, isRepair);
if (ret != NoError) if (ret != NoError)
{ {
LError("checkForRepairProgram error!{}", ret); LError("checkForRepairProgram error!{}", ret);
return; return;
} }
auto selectMode = selectedProducts[productFormat]; if (snMode != currWorkMode || isRepair != repairFlag)
if (selectMode != currWorkMode || isRepair)
{ {
Common::GetInstance()->setRepairFlag(isRepair);
QString reStr = isRepair ? "反修" : "正常";
QString logStr = QString("启动%1-%2").arg(Common::getWorkModeStr(snMode)).arg(reStr);
addLogItem(logStr);
// 切换工作模式 // 切换工作模式
if (currWorkMode != -1) if (currWorkMode != -1)
{ {
m_udpDataThread->sendClose(); m_udpDataThread->sendClose();
} }
//TODO:不相等时m_udpDataThread发送关闭信号等待Common单例类中的标志位变成-1后m_udpDataThread停止发送关闭信号并启动IECS程序 //TODO:不相等时m_udpDataThread发送关闭信号等待Common单例类中的标志位变成-1后m_udpDataThread停止发送关闭信号并启动IECS程序
//同时需要去IECS程序路径中查找数据库判断是否使用返修程序 //同时需要去IECS程序路径中查找数据库判断是否使用返修程序
switchProgram(snId, selectMode, isRepair); switchProgram(snId, snMode, isRepair);
return; return;
} }
m_udpDataThread->sendSnId(snId); m_udpDataThread->sendSnId(snId);
addLogItem(QString("已发送产品SN%1").arg(snId));
} }
void Widget::on_pushButton_sendSnId_clicked() void Widget::on_pushButton_sendSnId_clicked()

@ -2,6 +2,8 @@
#define WIDGET_H #define WIDGET_H
#include <QWidget> #include <QWidget>
#include <QSqlDatabase>
#include "settingwgt.h" #include "settingwgt.h"
#include "udpdatahandler.h" #include "udpdatahandler.h"
@ -23,20 +25,27 @@ private:
int checkForRepairProgram(const int mode, const QString& sn, bool& isFind); int checkForRepairProgram(const int mode, const QString& sn, bool& isFind);
int databaseQuery(const QString& databasePath, const QString& deviceSn, bool& isFind); int databaseQuery(const QString& databasePath, const QString& deviceSn, bool& isFind);
bool identifyProduct(const QString& sn, int& mode);
private slots: private slots:
void RegisterDoneSlot(bool ret); void RegisterDoneSlot(bool ret);
void GetConnStatusSlot(bool ret); void GetConnStatusSlot(bool ret);
bool ProcessJudgment();
bool isProcessRunningWithName(const QString& processNamePart);
void addLogItem(const QString& text); void addLogItem(const QString& text);
int switchProgram(const QString snId, const int mode, const bool isRepair); int switchProgram(const QString snId, const int mode, const bool isRepair);
void on_pushButton_setting_clicked(); void on_pushButton_setting_clicked();
void on_lineEdit_snId_returnPressed(); void on_lineEdit_snId_returnPressed();
void on_pushButton_sendSnId_clicked(); void on_pushButton_sendSnId_clicked();
private: private:
Ui::Widget *ui; Ui::Widget *ui;
SettingWgt *m_settingDlg; SettingWgt *m_settingDlg;
UdpDataHandler *m_udpDataThread; UdpDataHandler *m_udpDataThread;
bool m_showSetting; bool m_showSetting;
bool m_isSwitching; QSqlDatabase m_db;
}; };
#endif // WIDGET_H #endif // WIDGET_H

@ -1,6 +1,7 @@
#ifndef INTERFACE_H #ifndef INTERFACE_H
#define INTERFACE_H #define INTERFACE_H
#include <QString> #include <QString>
#include <QMap>
enum ErrorCode enum ErrorCode
{ {
NoError = 0, NoError = 0,

Loading…
Cancel
Save