#include "hostthread.h" #include "qdebug.h" #include "qjsonarray.h" #include "qjsonobject.h" #include #include #include #include #include #include /* # Copyright (c) 1993-2009 Microsoft Corp. # # This is a sample HOSTS file used by Microsoft TCP/IP for Windows. # # This file contains the mappings of IP addresses to host names. Each # entry should be kept on an individual line. The IP address should # be placed in the first column followed by the corresponding host name. # The IP address and the host name should be separated by at least one # space. # # Additionally, comments (such as these) may be inserted on individual # lines or following the machine name denoted by a '#' symbol. # # For example: # # 102.54.94.97 rhino.acme.com # source server # 38.25.63.10 x.acme.com # x client host # localhost name resolution is handled within DNS itself. # 127.0.0.1 localhost # ::1 localhost 127.0.0.1 activate.navicat.com 127.0.0.1 example.com */ static void ipconfigFlushdns() { // 创建 QProcess 对象 QProcess process; // 设置要执行的命令和参数 process.start("ipconfig", QStringList() << "/flushdns"); // 等待命令执行完成 process.waitForFinished(); // 获取命令输出(如果有的话) auto output = process.readAllStandardOutput(); auto errorOutput = process.readAllStandardError(); // 输出结果 if (!output.isEmpty()) { qDebug() << "Command output:" << QString::fromLocal8Bit(output); } if (!errorOutput.isEmpty()) { qDebug() << "Command error:" << errorOutput; } } static bool modifyHostsFile(const QString &hostname, const QString &ipAddress, bool action) { QString hostsFilePath; #ifdef Q_OS_WIN hostsFilePath = "C:/Windows/System32/drivers/etc/hosts"; #else hostsFilePath = "/etc/hosts"; #endif // 打开hosts文件 QFile file(hostsFilePath); if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) { qWarning() << "无法打开文件" << hostsFilePath; return false; } // 读取文件内容 QTextStream stream(&file); QStringList fileLines; QRegularExpression regex( R"RX(^(#?\s*)(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+([a-zA-Z0-9.-]+)(\s+#.*)?$)RX"); bool isExist = false; while (!stream.atEnd()) { QString line = stream.readLine(); // 读取一行 fileLines.append(line); // 保存当前行 QRegularExpressionMatch expressionMatch = regex.match(line); if (expressionMatch.hasMatch()) { const QString url = expressionMatch.captured(3); if (url.compare(hostname) == 0) { if (action) { // 添加 qDebug() << "---------------add" << url; qDebug() << "已存在,进行添加操作: " << url; fileLines.removeOne(line); } else { qDebug() << "---------------remove" << url; qDebug() << "删除操作: " << url; fileLines.removeOne(line); } } } } // 如果是添加操作并且记录不存在,添加新条目 if (!isExist && action) { QString newLine = QString("%1 %2").arg(ipAddress).arg(hostname); fileLines.append(newLine); // 将新的条目添加到文件末尾 qDebug() << "添加新的条目: " << newLine; } // 重写文件内容 file.resize(0); // 清空文件内容 QTextStream out(&file); for (const QString &line : fileLines) { out << line << "\n"; } file.close(); ipconfigFlushdns(); return true; } // HostThread::HostThread() // { // if (modifyHostsFile("example.com", "127.0.0.1")) { // qDebug() << "Hosts 文件已成功更新。"; // } else { // qDebug() << "修改失败。"; // } // } HostThread::HostThread(QObject *parent) {} void HostThread::upDataHost() { TC::HostsApi hostsApi; const auto serverArray = hostsApi.get(); QSet addressSet; // 添加 QSet removeAddressSet; // 取消 for (const QJsonValue &item : serverArray) { if (!item.isObject()) { return; } const QJsonObject object = item.toObject(); const QString name = object["address"].toString(); if (object.contains("value")) { if (object["value"].toString() == "-1" || object["value"].toInt() == -1) { addressSet.insert(name); modifyHostsFile(name, "127.0.0.1", true); } else { removeAddressSet.insert(name); modifyHostsFile(name, "127.0.0.1", false); } } } // if (modifyHostsFile("example.com", "127.0.0.1", true)) { // qDebug() << "Hosts 文件已成功更新。"; // } else { // qDebug() << "修改失败。"; // } } void HostThread::run() { QElapsedTimer timer; // 创建高精度计时器 timer.start(); // 启动计时器 upDataHost(); while (true) { // 校验网络 if (timer.elapsed() >= 30 * 1000) { timer.restart(); upDataHost(); } msleep(1000); // 休息1秒 } }