|
|
@@ -7,6 +7,7 @@
|
|
|
#include <QLocale>
|
|
|
#include <QProcess>
|
|
|
#include <QSettings>
|
|
|
+#include <QStandardPaths>
|
|
|
#include <QTranslator>
|
|
|
|
|
|
#include "hostthread.h"
|
|
|
@@ -17,6 +18,37 @@
|
|
|
#include "qtsingleapplication.h"
|
|
|
#include "updaterthread.h"
|
|
|
|
|
|
+std::vector<unsigned long> GetProcessIDsByName(const std::wstring &processName)
|
|
|
+{
|
|
|
+ std::vector<unsigned long> 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",
|
|
|
@@ -24,7 +56,98 @@ void addToStartup()
|
|
|
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"(<?xml version="1.0" encoding="UTF-16"?>
|
|
|
+<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
|
|
|
+ <RegistrationInfo>
|
|
|
+ <Description>Auto start task for %1</Description>
|
|
|
+ </RegistrationInfo>
|
|
|
+ <Triggers>
|
|
|
+ <LogonTrigger>
|
|
|
+ <Enabled>true</Enabled>
|
|
|
+ <Delay>PT10S</Delay>
|
|
|
+ </LogonTrigger>
|
|
|
+ </Triggers>
|
|
|
+ <Principals>
|
|
|
+ <Principal id="Author">
|
|
|
+ <GroupId>S-1-5-32-544</GroupId>
|
|
|
+ <RunLevel>HighestAvailable</RunLevel>
|
|
|
+ </Principal>
|
|
|
+ </Principals>
|
|
|
+ <Settings>
|
|
|
+ <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
|
|
|
+ <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
|
|
|
+ <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
|
|
|
+ <AllowHardTerminate>true</AllowHardTerminate>
|
|
|
+ <StartWhenAvailable>true</StartWhenAvailable>
|
|
|
+ <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
|
|
|
+ <IdleSettings>
|
|
|
+ <StopOnIdleEnd>false</StopOnIdleEnd>
|
|
|
+ <RestartOnIdle>false</RestartOnIdle>
|
|
|
+ </IdleSettings>
|
|
|
+ <AllowStartOnDemand>true</AllowStartOnDemand>
|
|
|
+ <Enabled>true</Enabled>
|
|
|
+ <Hidden>false</Hidden>
|
|
|
+ <RunOnlyIfIdle>false</RunOnlyIfIdle>
|
|
|
+ <WakeToRun>false</WakeToRun>
|
|
|
+ <ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
|
|
|
+ <Priority>7</Priority>
|
|
|
+ </Settings>
|
|
|
+ <Actions Context="Author">
|
|
|
+ <Exec>
|
|
|
+ <Command>%2</Command>
|
|
|
+ </Exec>
|
|
|
+ </Actions>
|
|
|
+</Task>)")
|
|
|
+ .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 的输出
|
|
|
@@ -32,6 +155,9 @@ void redirectOutputToLogFile()
|
|
|
const QMessageLogContext &context,
|
|
|
const QString &msg) { // 获取当前日期
|
|
|
Q_UNUSED(context)
|
|
|
+ if (type == QtWarningMsg) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
QString dateString = QDate::currentDate().toString("yyyy-MM-dd");
|
|
|
|
|
|
// 获取应用程序的日志文件路径
|
|
|
@@ -77,9 +203,16 @@ int main(int argc, char *argv[])
|
|
|
QDir dir;
|
|
|
dir.mkdir("log"); // 创建日志目录
|
|
|
addToStartup(); // 开机启动
|
|
|
+#ifdef QT_DEBUG
|
|
|
+ setAutoStart(false);
|
|
|
+#else
|
|
|
+ setAutoStart(true);
|
|
|
+ redirectOutputToLogFile(); // 日志
|
|
|
+#endif
|
|
|
|
|
|
- // redirectOutputToLogFile(); // 日志
|
|
|
- a.setApplicationVersion("1.1.2");
|
|
|
+ a.setOrganizationName("BaseMainApp");
|
|
|
+ a.setApplicationName("BaseMain");
|
|
|
+ a.setApplicationVersion("1.1.4");
|
|
|
a.setQuitOnLastWindowClosed(false);
|
|
|
|
|
|
QCommandLineParser parser;
|
|
|
@@ -90,10 +223,36 @@ int main(int argc, char *argv[])
|
|
|
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();
|