使用Windows Api+Qt做的一个系统备份工具
重新编辑于2019.05.08,代码有所改变,详细信息请参阅附件链接,不做详述
由于公司应用大量装机的情况,以前使用ghost软件来处理,但是自从uefi模式出现后ghost已经不能很好的应用了,虽然现在有Acronis软件替代,但是生成的备份文件没有很好的工具去修改,所以遇到需要添加镜像驱动和补丁的时候带来非常大的麻烦。系统自带的dism工具确实好用,但是每次都需要输入命令行输入,效率不能提高。因此根据现在的实际情况,清明三天假连学带做了这款窗口版的备份还原工具,功能目前很很简单,只有备份分区(文件夹)和还原分区功能,下一步会添加驱动添加功能。废话不说,上代码。
//DismTools.h qt widget 头文件 #pragma once#include <QWidget>#include <QThread>#include "ui_DismTools.h"#include <QString>#include <QLabel>#include "BackUp.h"#include "Restore.h"#include "BcdBoot.h"class DismTools : public QWidget{ Q_OBJECTpublic: DismTools(QWidget *parent = Q_NULLPTR); ~DismTools() { thread.quit(); thread.wait(); }private: Ui::DismToolsClass ui;private slots:void on_BackUp_clicked();void on_BackUp_finished(const QString&);void on_Restore_clicked();void on_Restore_finished(const QString&);private: QThread thread; BackUp *bk; Restore *restore; BcdBoot *boot;signals: void backSig(const QString &,const QString &); void restoreSig(const QString &, const QString &); void bcdbootSig(const QString &); //PWSTR pszTmpDir = L"C:\\tmp";};
//dismtools.cpp 代码#pragma execution_character_set("utf-8")#include "DismTools.h"#include "BackUp.h"#include <QFileInfo>#include <QFileDialog>DismTools::DismTools(QWidget *parent) : QWidget(parent){ ui.setupUi(this); connect(ui.backUp, &QPushButton::clicked, this, &DismTools::on_BackUp_clicked); connect(ui.restore, &QPushButton::clicked, this, &DismTools::on_Restore_clicked);}void DismTools::on_BackUp_clicked(){ QString dir = QFileDialog::getExistingDirectory(this, tr("选择备份分区"), "/home", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); QFileInfo fi(dir); if (!fi.exists()) { return; } QString fileName = QFileDialog::getSaveFileName(this, QString("保存镜像文件"), "/home/", QString("镜像文件 (*.wim)")); QFileInfo fi1(fileName); bk = new BackUp(); bk->moveToThread(&thread); connect(&thread, &QThread::finished, bk, &QObject::deleteLater); connect(this, &DismTools::backSig, bk, &BackUp::doBackUp); connect(bk, &BackUp::resultReady, this, &DismTools::on_BackUp_finished); thread.start(); ui.label->setText("镜像备份中..."); ui.backUp->setDisabled(true); emit backSig(fileName, dir);}void DismTools::on_BackUp_finished(const QString &finished){ ui.label->setText(finished); QMessageBox::warning(this, "", finished); ui.backUp->setDisabled(false);}void DismTools::on_Restore_clicked(){ QString dir = QFileDialog::getExistingDirectory(this, tr("选择恢复分区"), "/home", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); QFileInfo fi(dir); if (!fi.exists()) { return; } QString fileName = QFileDialog::getOpenFileName(this, QString("选择镜像文件"), "/home/", QString("镜像文件 (*.wim)")); QFileInfo fi1(fileName); restore = new Restore(); restore->moveToThread(&thread); connect(&thread, &QThread::finished, restore, &QObject::deleteLater); connect(this, &DismTools::restoreSig, restore, &Restore::doRestore); connect(restore, &Restore::resultReady, this, &DismTools::on_Restore_finished); thread.start(); ui.label->setText("镜像恢复中..."); ui.restore->setDisabled(true); emit restoreSig(fileName, dir);}void DismTools::on_Restore_finished(const QString &finished){ ui.label->setText(finished); QMessageBox::warning(this, "", finished); ui.restore->setDisabled(false); int ret = QMessageBox::question(this, "", QString("是否添加引导项?"), QMessageBox::Ok,QMessageBox::No); if (ret = 0) { QString souces = QFileDialog::getExistingDirectory(this, tr("选择Windows系统根目录"), "/home", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); QString bootPath = QFileDialog::getExistingDirectory(this, tr("选择Windows启动分区"), "/home", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); boot = new BcdBoot(); boot->doBcdBoot(souces, bootPath); connect(boot, &BcdBoot::resultReady, this, [=](const QString &result) { QMessageBox::information(this, "", result); }); return; }}//backup代码#pragma once#pragma execution_character_set("utf-8")#include <qobject.h>#include <QString>#include <QMessageBox>#include "windows.h"#include "wimgapi.h"class BackUp:public QObject{ Q_OBJECTpublic slots: void doBackUp(const QString &pszWimFile,const QString &pszCaptureDir);signals: void resultReady(const QString &result);};
//backup.cpp#include "BackUp.h"#include <QMessageBox>void BackUp::doBackUp(const QString &pszWimFile, const QString &pszCaptureDir){ bool sucess = true; const wchar_t * WimFile = reinterpret_cast<const wchar_t *>(pszWimFile.utf16()); const wchar_t * CaptureDir = reinterpret_cast<const wchar_t *>(pszCaptureDir.utf16()); DWORD dwFlags = 0, dwDisposition = WIM_CREATE_ALWAYS, dwDesiredAccess = WIM_GENERIC_WRITE, dwCreateFlags = 0, dwCaptureFlags = WIM_FLAG_VERIFY, dwCompressionType = WIM_COMPRESS_LZX, dwCreationResult = 0, dwError = 0; HANDLE hWim = WIMCreateFile(WimFile, dwDesiredAccess, dwDisposition, dwCreateFlags, dwCompressionType, &dwCreationResult); sucess = hWim; if (!sucess) { //QMessageBox::critical(this, QString("Error!"), QString("BackUp Error with code Create Fail")); //QMessageBox::critical(NULL, QString("Error!"), QString("Create Image Fail")); emit resultReady(QString("文件创建失败")); return; } //WIMSetTemporaryPath(hWim, pszTmpDir); HANDLE hImage = WIMCaptureImage(hWim, CaptureDir, dwCaptureFlags); sucess = hImage; if (!sucess) { //QMessageBox::critical(NULL, QString("Error!"), QString("BackUp Error with code BackUp Status")); emit resultReady(QString("备份失败")); return; } WIMCloseHandle(hImage); WIMCloseHandle(hWim); emit resultReady(QString("备份成功"));}
}
bcdboot 代码就不贴了,简单的都不不好意思。。。
附件有详细代码 测试环境 vs2017+qt msvc2017 +wadk环境,由于制作内部使用,因此界面比较丑陋,有时间优化吧
运行效果图
附件链接:代码
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。