线程函数
#ifndef PLAN_TEXT_H
#define PLAN_TEXT_H
#include <QObject>
#include <windows.h>
#include <QString>
#include <QVariantList>
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = nullptr);
~Worker();
void setRootKey(HKEY hKey, const QString &subKey);
signals:
void registryDataCollected(const QVariantList &data); // 信号:携带收集到的注册表数据
void finished(); // 信号:遍历完成
public slots:
void process(); // 槽:开始处理
private:
void traverseRegistry(HKEY hKey, const QString &subKey, QVariantList &data);
HKEY m_hKeyRoot;
QString m_subKey;
};
#endif // PLAN_TEXT_H
对应实现
// worker.cpp
#include "plan_text.h"
Worker::Worker(QObject *parent)
: QObject(parent),
m_hKeyRoot(nullptr)
{
}
Worker::~Worker()
{
}
void Worker::setRootKey(HKEY hKey, const QString &subKey)
{
m_hKeyRoot = hKey;
m_subKey = subKey;
}
void Worker::process()
{
QVariantList registryData;
traverseRegistry(m_hKeyRoot, m_subKey, registryData);
emit registryDataCollected(registryData); // 发出信号,传递收集的数据
emit finished(); // 发出完成信号
}
void Worker::traverseRegistry(HKEY hKey, const QString &subKey, QVariantList &data)
{
HKEY hSubKey;
if (RegOpenKeyExW(hKey, (LPCWSTR)subKey.utf16(), 0, KEY_READ, &hSubKey) == ERROR_SUCCESS) {
DWORD index = 0;
wchar_t keyName[256];
DWORD keyNameSize = 256;
// 枚举子键
while (RegEnumKeyExW(hSubKey, index, keyName, &keyNameSize, nullptr, nullptr, nullptr, nullptr) == ERROR_SUCCESS) {
QString fullSubKey = subKey + "\\" + QString::fromWCharArray(keyName);
data.append(fullSubKey); // 将子键路径添加到数据列表
traverseRegistry(hSubKey, QString::fromWCharArray(keyName), data); // 递归遍历子键
keyNameSize = 256;
index++;
}
RegCloseKey(hSubKey);
}
}
主窗口:
#ifndef WIDGET_H
#define WIDGET_H
#include <QMainWindow>
#include <QPushButton>
#include <QThread>
#include "plan_text.h"
class Worker;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void onStartRegistryTraversal(); // 启动遍历
void onRegistryDataCollected(const QVariantList &data); // 接收数据
void onTraversalFinished(); // 遍历完成
private:
QPushButton *startButton; // 手动创建的按钮
QThread *m_thread;
Worker *m_worker;
};
#endif // WIDGET_H
cpp实现
// mainwindow.cpp
#include "widget.h"
#include <QVBoxLayout>
#include <QDebug>
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
m_thread(nullptr),
m_worker(nullptr)
{
// 设置主窗口
this->setWindowTitle("Registry Traversal");
// 创建按钮
startButton = new QPushButton("Start Traversal", this);
// 创建布局并添加按钮
QVBoxLayout *layout = new QVBoxLayout();
layout->addWidget(startButton);
// 创建一个中心窗口,并设置布局
QWidget *centralWidget = new QWidget(this);
centralWidget->setLayout(layout);
this->setCentralWidget(centralWidget);
// 连接按钮点击信号到槽函数
connect(startButton, &QPushButton::clicked, this, &MainWindow::onStartRegistryTraversal);
}
MainWindow::~MainWindow()
{
if (m_thread && m_thread->isRunning()) {
m_thread->quit();
m_thread->wait();
}
}
void MainWindow::onStartRegistryTraversal()
{
startButton->setEnabled(false); // 禁用按钮,防止重复点击
m_thread = new QThread;
m_worker = new Worker;
m_worker->setRootKey(HKEY_LOCAL_MACHINE, "SOFTWARE"); // 设置起始注册表键
// 将worker移动到线程中
m_worker->moveToThread(m_thread);
// 连接信号和槽
connect(m_thread, &QThread::started, m_worker, &Worker::process);
connect(m_worker, &Worker::registryDataCollected, this, &MainWindow::onRegistryDataCollected);
connect(m_worker, &Worker::finished, this, &MainWindow::onTraversalFinished);
connect(m_worker, &Worker::finished, m_thread, &QThread::quit);
connect(m_worker, &Worker::finished, m_worker, &Worker::deleteLater);
connect(m_thread, &QThread::finished, m_thread, &QThread::deleteLater);
m_thread->start(); // 启动线程
}
void MainWindow::onRegistryDataCollected(const QVariantList &data)
{
// 在这里处理收集到的注册表数据,例如显示在UI上
foreach (const QVariant &item, data) {
qDebug() << item.toString();
}
}
void MainWindow::onTraversalFinished()
{
startButton->setEnabled(true); // 重新启用按钮
QMessageBox::information(this, "完成", "注册表遍历已完成!");
}