#include #include #include #include #include #include #include #include #include #include #include "hostthread.h" #include "messagequeue.h" #include "processthread.h" #include "qdatetime.h" #include "qobject.h" #include "qtsingleapplication.h" #include "updaterthread.h" #include "websocketclient.h" std::vector GetProcessIDsByName(const std::wstring &processName) { std::vector pids; // 创建进程快照 HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot == INVALID_HANDLE_VALUE) { //std::cerr << "Failed to take snapshot of processes" << Qt::endl; return pids; } // 设置进程信息结构体 PROCESSENTRY32 pe32; pe32.dwSize = sizeof(PROCESSENTRY32); // 获取第一个进程 if (Process32First(hSnapshot, &pe32)) { do { // 检查进程名是否匹配 if (processName == pe32.szExeFile) { pids.push_back(pe32.th32ProcessID); // 存储匹配的进程ID } } while (Process32Next(hSnapshot, &pe32)); // 获取下一个进程 } // 关闭快照句柄 CloseHandle(hSnapshot); return pids; } void addToStartup() { QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat); QString appPath = QCoreApplication::applicationFilePath(); // 获取应用程序路径 settings.setValue("BaseMainApp", appPath); // 将应用程序路径添加到注册表 } void setAutoStart(bool enable) { QString appPath = QDir::toNativeSeparators(QCoreApplication::applicationFilePath()); QString taskName = "YourAppName"; // 替换为你的应用程序名称 if (enable) { QString tempPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation); QString xmlFilePath = QDir::toNativeSeparators(tempPath + "/task.xml"); QFile xmlFile(xmlFilePath); if (xmlFile.open(QIODevice::WriteOnly | QIODevice::Text)) { QString xmlContent = QString(R"( Auto start task for %1 true PT10S S-1-5-32-544 HighestAvailable IgnoreNew false false true true false false false true true false false false PT0S 7 %2 )") .arg(taskName, appPath); // 将内容写入为 UTF-16LE 格式 QTextStream out(&xmlFile); out.setCodec("UTF-16LE"); out.setGenerateByteOrderMark(true); out << xmlContent; xmlFile.close(); QStringList arguments; arguments << "/c" << "schtasks" << "/create" << "/tn" << taskName << "/xml" << xmlFilePath << "/f"; qDebug() << "Executing command with arguments:" << arguments; QProcess process; process.start("cmd.exe", arguments); process.waitForFinished(); QString error = QString::fromLocal8Bit(process.readAllStandardError()); QString output = QString::fromLocal8Bit(process.readAllStandardOutput()); if (!error.isEmpty()) { qDebug() << "Error output:" << error; } if (!output.isEmpty()) { qDebug() << "Standard output:" << output; } xmlFile.remove(); } } else { QStringList arguments; arguments << "/c" << "schtasks" << "/delete" << "/tn" << taskName << "/f"; QProcess::execute("cmd.exe", arguments); } } void redirectOutputToLogFile() { // 重定向 qDebug、qWarning 和 qCritical 的输出 qInstallMessageHandler([](QtMsgType type, const QMessageLogContext &context, const QString &msg) { // 获取当前日期 Q_UNUSED(context) if (type == QtWarningMsg) { return; } QString dateString = QDate::currentDate().toString("yyyy-MM-dd"); // 获取应用程序的日志文件路径 QString logFileName = "./log/" + dateString + "_base.txt"; // 创建 QFile 对象 QFile logFile(logFileName); // 打开文件进行写入,如果文件不存在则创建 if (!logFile.open(QIODevice::Append | QIODevice::Text)) { qWarning() << "Unable to open log file for writing:" << logFile.errorString(); return; } QTextStream out(&logFile); QString timeString = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"); switch (type) { case QtDebugMsg: out << timeString << " [DEBUG] " << msg << "\n"; break; case QtWarningMsg: out << timeString << " [WARNING] " << msg << "\n"; break; case QtCriticalMsg: out << timeString << " [CRITICAL] " << msg << "\n"; break; case QtFatalMsg: out << timeString << " [FATAL] " << msg << "\n"; // abort(); // 终止程序 case QtInfoMsg: break; } logFile.close(); }); } int main(int argc, char *argv[]) { // QApplication a(argc, argv); SharedTools::QtSingleApplication a("BaseMainApp", argc, argv); QDir dir; dir.mkdir("log"); // 创建日志目录 addToStartup(); // 开机启动 #ifdef QT_DEBUG setAutoStart(false); #else setAutoStart(true); redirectOutputToLogFile(); // 日志 #endif a.setOrganizationName("BaseMainApp"); a.setApplicationName("BaseMain"); a.setApplicationVersion("1.1.5"); a.setQuitOnLastWindowClosed(false); QCommandLineParser parser; parser.addHelpOption(); parser.addVersionOption(); QCommandLineOption debugOption("debug", "Enable debug mode"); parser.addOption(debugOption); parser.process(a); qDebug() << QCoreApplication::organizationName() << QCoreApplication::applicationName() << QCoreApplication::applicationFilePath(); QString appFilePath = QCoreApplication::applicationFilePath(); QString appName = QFileInfo(appFilePath).fileName(); qDebug() << "Application Path:" << appFilePath; qDebug() << "Application Name:" << appName; if (a.isRunning()) { a.sendMessage("", 1000); return 0; } // 多重判断 防止异常 HANDLE hMutex = CreateMutex(NULL, TRUE, L"Global\\Unique_BaseMainApp"); // 检查是否已经有实例在运行 if (hMutex == NULL || GetLastError() == ERROR_ALREADY_EXISTS) { return 0; // 退出当前程序,避免多个实例运行 } // 多重判断 auto pids = GetProcessIDsByName(appName.toStdWString().c_str()); if (pids.size() > 1) { qDebug() << appName << " size:" << pids.size(); } qSetMessagePattern("[%{time process}][%{line}]" "%{if-debug}D%{endif}" "%{if-info}I%{endif}" "%{if-warning}W%{endif}" "%{if-critical}C%{endif}" "%{if-fatal}F%{endif}:" "%{message} %{file}"); QTranslator translator; const QStringList uiLanguages = QLocale::system().uiLanguages(); for (const QString &locale : uiLanguages) { const QString baseName = "basemain_" + QLocale(locale).name(); if (translator.load(":/i18n/" + baseName)) { a.installTranslator(&translator); break; } } WebSocketClient::getInstance(); HostThread host; UpdaterThread thread; ProcessThread Process; MessageQueue messageQueue; QObject::connect(&Process, &ProcessThread::messageBox, &messageQueue, &MessageQueue::addMessage); QObject::connect(&Process, &ProcessThread::finished, &Process, &QObject::deleteLater); // thread.start(); // Process.start(); // host.start(); return a.exec(); }