一、具体思路

安装过程:安装包的制作包括资源文件的打包,资源文件打包到安装包exe中,安装的时候需要从exe中提取出对应的资源文件,

然后解压文件安装到指定目录,然后就是对安装的可执行程序进行注册表的注册,以及快捷方式的注册。

卸载过程:安装包安装时,通常会带有一个卸载程序,此程序的功能就是执行对安装程序目录文件的删除和注册表的清除。

二、实现

安装过程分为三部分实现,安装配置,安装过程,安装结束启动程序。

安装配置界面如下:

安装过程实现:

Install类负责对打包文件的释放,注册表的写入,快捷方式的写入,以及回调界面进度的职责:

 #pragma once
#include<string>
#include<functional> class Install
{
public:
Install();
virtual ~Install();
static Install& getInstance(){
static Install instance;
return instance;
}
void setStop(){
m_stop = true;
}
bool install(const std::string & install_path, bool is_shortcut);
void setCallBack(const std::function<void(int, const std::string &)> &fun_1,const std::function<void()> &fun_2){
process_fun = fun_1;
process_end = fun_2;
}
private:
bool releaseRes(const std::string & file_name, unsigned short res_id, const std::string & file_type);
bool setShortCutLink(const std::string & path, const std::string & link_name, bool is_desktop);
bool writeToReg();
std::string getDesktopPath();
std::string getStartMenuPath();
private:
std::function<void(int, const std::string &)> process_fun;
std::function<void()> process_end;
std::string m_install_path;
bool m_stop; };

1)导入资源到exe,

.rc文件添加资源,

 IDR_en_US              APK                    "res\\bin\\locales\\en-US.pak"
IDR_zh_CN APK "res\\bin\\locales\\zh-CN.pak" /////////////////////////////////////////////////////////////////////////////
//
// EXE
// IDR_YDDemo EXE "res\\bin\\YDDemo.exe"
IDR_Unstall_App EXE "res\\bin\\Unstall_App.exe"
IDR_debug LOG "res\\bin\\debug.log"
IDR_icudtl DAT "res\\bin\\icudtl.dat"
IDR_natives_blob BIN "res\\bin\\natives_blob.bin"
IDR_snapshot_blob BIN "res\\bin\\snapshot_blob.bin"
IDR_cef APK "res\\bin\\cef.pak"
IDR_cef_100_percent APK "res\\bin\\cef_100_percent.pak"
IDR_cef_200_percent APK "res\\bin\\cef_200_percent.pak"
IDR_cef_extensions APK "res\\bin\\cef_extensions.pak"
IDR_devtools_resources APK "res\\bin\\devtools_resources.pak"
/////////////////////////////////////////////////////////////////////////////
//
// DLL
// IDR_d3dcompiler_43 DLL "res\\bin\\d3dcompiler_43.dll"
IDR_d3dcompiler_47 DLL "res\\bin\\d3dcompiler_47.dll"
IDR_DuiLib_u DLL "res\\bin\\DuiLib_u.dll"
IDR_libcef DLL "res\\bin\\libcef.dll"
IDR_libEGL DLL "res\\bin\\libEGL.dll"
IDR_libGLESv2 DLL "res\\bin\\libGLESv2.dll"
IDR_widevinecdmadapter DLL "res\\bin\\widevinecdmadapter.dll"

定义资源ID

 #define IDR_en_US                       152
#define IDR_zh_CN 153
#define IDR_YDDemo 154
#define IDR_Unstall_App 155
#define IDR_debug 156
#define IDR_icudtl 157
#define IDR_natives_blob 158
#define IDR_snapshot_blob 159
#define IDR_cef 160
#define IDR_cef_100_percent 161
#define IDR_cef_200_percent 162
#define IDR_cef_extensions 163
#define IDR_devtools_resources 164
#define IDR_d3dcompiler_43 165
#define IDR_d3dcompiler_47 166
#define IDR_DuiLib_u 167
#define IDR_libcef 168
#define IDR_libEGL 169
#define IDR_libGLESv2 170
#define IDR_widevinecdmadapter 171

2)释放资源,并且回调安装进度,更新界面的显示

 bool releaseRes(const std::string & file_name, unsigned short res_id, const std::string & file_type);

releaseRes负责释放资源

 bool Install::releaseRes(const std::string & file_name, unsigned short res_id, const std::string & file_type){
DWORD dwWrite = ;
HANDLE hFile = CreateFile(Ecoder::stringToWstring(file_name).c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE){
return FALSE;
}
HRSRC hrsc = FindResource(NULL, MAKEINTRESOURCE(res_id), Ecoder::stringToWstring(file_type).c_str());
HGLOBAL hG = LoadResource(NULL, hrsc);
DWORD dwSize = SizeofResource(NULL, hrsc);
WriteFile(hFile, hG, dwSize, &dwWrite, NULL);
CloseHandle(hFile);
return true;
}

设置回调函数

    std::function<void(int, const std::string &)> process_fun;
std::function<void()> process_end;
 Install::getInstance().setCallBack(std::bind(&MainFrame::setProcessCallBack,this,std::placeholders::_1,std::placeholders::_2),
std::bind(&MainFrame::setupEndCallBack,this));

两个回调函数负责更新资源释放的进度,当然也可以用一个回调函数。

3)注册表操作

写入exe到注册表

     bool writeToReg();

创建快捷方式

    bool setShortCutLink(const std::string & path, const std::string & link_name, bool is_desktop);

结束安装,启动程序。

     std::string str_tmp = m_install_path + "\\";
m_install_path += "\\YDDemo.exe";
ShellExecute(NULL, L"open", Ecoder::stringToWstring(m_install_path).c_str(), NULL, Ecoder::stringToWstring(str_tmp).c_str(), SW_SHOWNORMAL);

卸载过程也是分三部分实现:卸载选择,卸载过程,卸载结束,界面操作如下

界面卸载是通过UnInstall类实现,主要负责注册表的清理,目录文件的删除,程序的自删除以及更新界面进度的职责

 #pragma once
#include<string>
#include<functional> class UnInstall
{
public:
UnInstall();
virtual ~UnInstall();
static UnInstall& getInstance(){
static UnInstall instance;
return instance;
}
void setCallBack(const std::function<void(int, const std::string &)> &fun_1, const std::function<void()> &fun_2){
process_fun = fun_1;
process_end = fun_2;
}
bool unInstall();
bool deleteRegKey();
bool deleteDirFile(const std::string & path);
bool deleteApplicationSelf();
private:
std::function<void(int, const std::string &)> process_fun;
std::function<void()> process_end;
};

具体代码可以参考https://github.com/karllen/cef3-duilib-YDDemo/tree/master/Setup_App,因为这个是我学习的Demo,

功能还不是特别完善,图片素材取自网络,如有侵权,联系作者删除。此程序适合入门duilib的C++ 程序员来学习,

程序实现用了C++11的std::thread,std::share_ptr,std::bind等。

技术交流QQ群,欢迎大家加入:347769318

使用duilib开发简单的Window安装包的更多相关文章

  1. 使用Squirrel创建基于Electron开发的Windows 应用安装包

    我们把自己开发的Electron应用发布之前,需要把app打包成简单的安装包,这样app更容易被获取,以此来发布我们的应用.我们可以参考Wix或其他的安装程序,但是对于Electron应用更好的打包程 ...

  2. Ubuntu 18.04安装arm-linux-gcc交叉编译器(超简单,附安装包下载地址)

    目前网上搜索发现,最多人安装的是4.4.3版本的: arm-linux-gcc-4.4.3.tar.gz下载地址:https://pan.baidu.com/s/1rAIBASIRZAXl-P1UOW ...

  3. ANDROID 开发,安装离线安装包的下载地址及安装方法。

    前言: 建议采用离线安装的方法安装SDK包,在线的方式实在是.....多了不解释. 下面说一下离线安装的方法: 1.下载地址:http://pan.baidu.com/s/1sjuJwYD#path= ...

  4. 为自己编写的windows应用程序制作安装包

    1 写好了一个windows程序之后如何制作安装包 这个在vs中就可以直接发布了,可以制作msi的安装包和exe的安装包. 2 window应用程序安装包做了哪些事情 rpm安装包的话,只是把相应的文 ...

  5. Electron实战:创建ELectron开发的window应用安装包

    前言:研究electron自动更新的时候,在electron的官方文档auto-updater 中,提到了在几个平台mac,Linux,windows下electron 的自动更新方法,其中winds ...

  6. iOS开发——程序员必备&iOS安装包的三种格式 deb、ipa 和 pxl的解释和说明

    iOS安装包的三种格式 deb.ipa 和 pxl的解释和说明 目前 iOS 平台上常见的安装包有三种,deb.ipa 和 pxl.转自链接:http://fanlb.blogbus.com/logs ...

  7. WPF开发时光之痕日记本——终于完工了。。晒晒截图(三)(已上传安装包)

    由于是业余时间学习的 WPF 的相关开发且不怎么会使用 Blend 软件,所以开发这个客户端着实花费了我很长时间,比如文本编辑器的开发,最初是在 Simple.HtmlEditor 的基础上做的修改, ...

  8. 在Visual Studio 2013/2015上使用C#开发Android/IOS安装包和操作步骤

    Xamarin 配置手册和离线包下载 http://pan.baidu.com/s/1eQ3qw8a 具体操作: 安装前提条件 1. 安装Visual Studio 2013,安装过程省略,我这里安装 ...

  9. DevExpress控件库 开发使用经验总结3 制作项目安装包

    2015-01-27 使用DevExpress控件包开发C/S项目完成后,部署前需要制作本地安装包.本文还是使用“SetupFactory”安装工厂来制作安装包.在以前的系列文章中详细介绍过该工具的使 ...

随机推荐

  1. Linux vi 退出&保存/不保存

    无论是否退出 vi,均可保存所做的工作.按 ESC 键,确定 vi 是否处于命令模式. 操作   键入 保存,但不退出vi                          :w 保存并退出vi    ...

  2. struts2-学习笔记(一)

     Struts2学习笔记(一) 一.Struts2概述 1. 是什么? Struts2 是一个非常优秀的MVC框架,基于Model2 设计模型 Struts2是一个M(模型---域--范围模型)V ...

  3. akka tips

    1.actorSelection,当涉及actor远程通信时,可以使用actorSelection. context.actorSelection("akka.tcp://app@other ...

  4. MySQL中变量的总结

    本文对MySQL中局部变量.用户变量.系统变量的理解进行总结. 一.局部变量 局部变量由DECLARE语句声明: DECLARE var_name[,...] type [DEFAULT value] ...

  5. WSGI框架及Paste+Pastedeploy+route+webob开发

    一.前言 WSGI服务器 一个Web服务器网关接口 (WSGI)服务器实现了WSGI接口的Web服务器端运行的Python的Web应用程序. 为什么需要WSGI? 传统的Web服务器不理解或有任何方式 ...

  6. url编码&&PHP大法

    URL编码 Url编码通常也被称为百分号编码(Url Encoding,also known as percent-encoding),是因为它的编码方式非常简单,使用%百分号加上两位的字符--012 ...

  7. HTTP Error 500.19 - Internal Server Error

    1.使用svn对项目进行管理 2.之前都是平安无事,忽然有一天报错:HTTP Error 500.19 - Internal Server Error,如图: 3.经过各种挣扎和求证,最后发现是项目. ...

  8. Asp.net Api中使用OAuth2.0实现“客户端验证”

    一.实现继承自OAuthAuthorizationServerProvider的类,实现以"客户端验证"方式传入的相关认证和access_token发放. public class ...

  9. sessionStorage,UserDataStorage,cookie全兼容写法存在的问题

    最近央视播出了中国诗词大赛,看到了一首诗,送给大家 <春宵·春宵一刻值千金> 作者:苏轼 [宋代] 春宵一刻值千金,花有清香月有阴. 歌管楼台声细细,秋千院落夜沉沉. 好了,言归正传,今天 ...

  10. Python学习之一:Python2.7与opencv2.4安装配置

    安装前准备: 1.确定所安装的电脑是32位还是64位系统:(作者电脑是64bit win10) 2.下载对应的安装包: (1)下载最新Python安装包:https://www.python.org/ ...