使用Windows Api+Qt做的一个系统备份工具

由于公司应用大量装机的情况,以前使用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_OBJECT

public:
	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_OBJECT

public 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("备份成功"));
}
//restore.h 代码
#pragma once
#pragma execution_character_set("utf-8")
#include <QObject>
#include <QString>
#include "Windows.h"
#include "wimgapi.h"

class Restore : public QObject
{
	Q_OBJECT

public slots:
	void doRestore(const QString &pszWimFile, const QString &pszCaptureDir);
signals:
	void resultReady(const QString &result);
};

//restore.cpp
#include "Restore.h"

void Restore::doRestore(const QString &pszWimFile, const QString &pszCaptureDir)
{

	bool sucess = true;
	const wchar_t * WimFile = reinterpret_cast<const wchar_t *>(pszWimFile.utf16());
	const wchar_t * pszApplyDir = reinterpret_cast<const wchar_t *>(pszCaptureDir.utf16());
	HANDLE hWim = NULL,
		hImage = NULL;
	DWORD  dwCreateFlags = 0,
		dwCreateResult = 0,
		dwImageIndex = 1,
		dwError = 0;
	WIM_INFO WimInfo = { 0 };

	hWim = WIMCreateFile(WimFile,          // Existing .wim file to append the image to
		WIM_GENERIC_READ,    // Access mode
		WIM_OPEN_EXISTING,   // Open disposition
		dwCreateFlags,
		0,                   // Compression type is ignored for WIM_OPEN_EXISTING.
		&dwCreateResult);

	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;
	}

	WIMGetAttributes(hWim, &WimInfo, sizeof(WimInfo));
	if (WimInfo.ImageCount < dwImageIndex)
	{

		emit resultReady(QString("镜像读取失败"));
		return;
	}

	WIMSetTemporaryPath(hWim, pszApplyDir);
	hImage = WIMLoadImage(hWim, dwImageIndex);

	sucess = hImage;
	if (!sucess)
	{
		//QMessageBox::critical(NULL, QString("Error!"), QString("BackUp Error with code BackUp Status"));

		emit resultReady(QString("不能获取镜像索引"));
		return;
	}

	WIMApplyImage(hImage, pszApplyDir, WIM_FLAG_FILEINFO);
	//sucess = WIMApplyImage(hImage, pszApplyDir, WIM_FLAG_NO_APPLY);
	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环境,由于制作内部使用,因此界面比较丑陋,有时间优化吧

运行效果图

附件链接:代码

原文地址:http://blog.51cto.com/amgodchan/2095438

时间: 2024-10-05 05:44:43

使用Windows Api+Qt做的一个系统备份工具的相关文章

MFC_1——采用windows API函数来生成一个窗口显示helloword

//采用windows API函数来生成一个窗口显示helloword: #include <windows.h> LRESULT CALLBACK myWndProc(HWND hWindow, UINT msg, WPARAM wParam, LPARAM lParam); //进入WinMain函数 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)

用MVVM做了一个保存网页的工具-上篇

前言: 你是否有过收藏了别人博客或文章,当想用的时候却找不到?你是否有过收藏了别人博客或文章,却因为没有网络而打不开网页?OK,下面是我做的一个工具,有兴趣的同学们可以download 玩下,哈哈^.^

Qt做的一个Bing(微软必应)壁纸工具

微软Bing壁纸是我非常喜欢的壁纸,怎么说呢它的壁纸非常细腻逼真,总是让人心动,我就不安利了,反正比三百六X鸟好多了.不幸的是Win10更新到最新版以后微软bing缤纷桌面不能运行了,失望加无奈..  难道我就这么的放弃我的壁纸了么,不,党告诉我,你可以靠自己,你可以创新,然后就自己动手做了一款工具来自动下载Bing壁纸工具. 纯...纯到没有界面,纯到没有任何提示,纯到24小时自动更换壁纸,纯. 整体而言,就是用json network slots ,就简单贴下主要代码部分,附件有构建好的应用

windows API 开发飞机订票系统 图形化界面 (三)

来吧,接下来是各个功能的函数的实现代码. 首先,程序运行时加载读入账户信息和航班信息.接下来就该读取文件了. 我把账户资料和航班信息储存在了.txt文件里 那么问题就来了,挖掘机...额,不对,应该怎么读入账户资料和航班信息? 每一行是结构体的一个成员,我读入的方式是一行一行读入. 两个读入函数代码如下: 1 //读入账户信息 2 BOOL ReadAccountData(HWND hwndDlg){ 3 4 FILE *fp; 5 6 passenger = (Passenger *)mall

windows API 开发飞机订票系统 图形化界面 (四)

接下来的是录入航班.修改航班信息功能的实现: 1 //录入航班 2 BOOL EntryFlight(HWND hEntryDlg){ 3 4 TCHAR szDiscount[16]; 5 TCHAR szFare[16],szSeat_Number[16]; 6 TCHAR szFlight_Number[16], szDate[16]; 7 TCHAR szDeparture[16], szDestination[16]; 8 TCHAR szTakeOff_Time[16], szLan

做了一个 喜欢翻译 工具

自创翻译工具 喜欢翻译 https://search.readmorejoy.com/fanyi 自创交互,调用大公司API 周末小作品,就这么一个小作品,已经有了自己的特色 长远看,此仅仅是万里长征第一步,未来无可限量 想象 感谢博客园 原文地址:https://www.cnblogs.com/pycoding/p/11483145.html

没事情做写一个批量管理工具吧

目前主要有两种类型的批量工具: 1基于ssl的 func :需要agent 命令加密 2基于ssh的 ansible:不需要agent 密令不加密 sever端需要保存客户端账户密码 或者秘钥 当然func是极其安全的 但是也过于重量级和繁琐 目前流行的都是 基于ssh的 工具 我们在做OS config 这一层次的操作 simple is good 安全问题 我们可以通过碉堡机 这种架构方式完成 上面就是整个的流程 当然如果要做的能用 需要把用户跟主机的信息存在数据库里面 通过主机组的方式管理

系统备份工具 ATI 下载。。

目前备份最快,稳定性最好,无非就是ATI,今天提供的版本是自动注册单文件版!双击直接注册并打开页面,经实测特别好用,备份速度确实快,打包的是单文件,用着也较方便! 下载地址:https://pan.baidu.com/s/1pLduumR

不仅想做系统清理工具,更要做你的贴心管家

CleanMyMac 或许是 Mac 上最知名的系统清理工具,从 2012 年初版开始,CleanMyMac 一直都在更智能彻底地帮助用户清理 Mac. 从颇受小白用户喜爱的「自动清理」特性开始,仅需一键即可快速而安全地清理系统各角落垃圾,释放宝贵硬盘空间.而在 CleanMyMac 2 加入中文支持并由苏州思杰马克丁代理引入中国后,也受到了国内许多用户的喜爱.几年努力所积累下来的名誉,让这家位处乌克兰的 MacPaw 公司一跃成为 Mac 平台最具影响力的开发商之一. 今天,MacPaw 终于