使用duilib开发简单的Window安装包

一、具体思路

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

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

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

二、实现

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

安装配置界面如下:

安装过程实现:

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

 1 #pragma once
 2 #include<string>
 3 #include<functional>
 4 
 5 class Install
 6 {
 7 public:
 8     Install();
 9     virtual ~Install();
10     static Install& getInstance(){
11         static Install instance;
12         return instance;
13     }
14     void setStop(){
15         m_stop = true;
16     }
17     bool install(const std::string & install_path, bool is_shortcut);
18     void setCallBack(const std::function<void(int, const std::string &)>  &fun_1,const std::function<void()> &fun_2){
19         process_fun = fun_1;
20         process_end = fun_2;
21     }
22 private:
23     bool releaseRes(const std::string & file_name, unsigned short res_id, const std::string & file_type);
24     bool setShortCutLink(const std::string & path, const std::string & link_name, bool is_desktop);
25     bool writeToReg();
26     std::string getDesktopPath();
27     std::string getStartMenuPath();
28 private:
29     std::function<void(int, const std::string &)> process_fun;
30     std::function<void()> process_end;
31     std::string m_install_path;
32     bool m_stop;
33 
34 };

1)导入资源到exe,

.rc文件添加资源,

 1 IDR_en_US              APK                    "res\\bin\\locales\\en-US.pak"
 2 IDR_zh_CN              APK                    "res\\bin\\locales\\zh-CN.pak"
 3 
 4 /////////////////////////////////////////////////////////////////////////////
 5 //
 6 // EXE
 7 //
 8 
 9 IDR_YDDemo                  EXE                     "res\\bin\\YDDemo.exe"
10 IDR_Unstall_App             EXE                     "res\\bin\\Unstall_App.exe"
11 IDR_debug                   LOG                     "res\\bin\\debug.log"
12 IDR_icudtl                  DAT                     "res\\bin\\icudtl.dat"
13 IDR_natives_blob            BIN                     "res\\bin\\natives_blob.bin"
14 IDR_snapshot_blob           BIN                     "res\\bin\\snapshot_blob.bin"
15 IDR_cef                     APK                     "res\\bin\\cef.pak"
16 IDR_cef_100_percent         APK                     "res\\bin\\cef_100_percent.pak"
17 IDR_cef_200_percent         APK                     "res\\bin\\cef_200_percent.pak"
18 IDR_cef_extensions          APK                     "res\\bin\\cef_extensions.pak"
19 IDR_devtools_resources      APK                     "res\\bin\\devtools_resources.pak"
20 /////////////////////////////////////////////////////////////////////////////
21 //
22 // DLL
23 //
24 
25 IDR_d3dcompiler_43          DLL                     "res\\bin\\d3dcompiler_43.dll"
26 IDR_d3dcompiler_47          DLL                     "res\\bin\\d3dcompiler_47.dll"
27 IDR_DuiLib_u                DLL                     "res\\bin\\DuiLib_u.dll"
28 IDR_libcef                  DLL                     "res\\bin\\libcef.dll"
29 IDR_libEGL                  DLL                     "res\\bin\\libEGL.dll"
30 IDR_libGLESv2               DLL                     "res\\bin\\libGLESv2.dll"
31 IDR_widevinecdmadapter      DLL                     "res\\bin\\widevinecdmadapter.dll"

定义资源ID

 1 #define IDR_en_US                       152
 2 #define IDR_zh_CN                       153
 3 #define IDR_YDDemo                      154
 4 #define IDR_Unstall_App                 155
 5 #define IDR_debug                       156
 6 #define IDR_icudtl                      157
 7 #define IDR_natives_blob                158
 8 #define IDR_snapshot_blob               159
 9 #define IDR_cef                         160
10 #define IDR_cef_100_percent             161
11 #define IDR_cef_200_percent             162
12 #define IDR_cef_extensions              163
13 #define IDR_devtools_resources          164
14 #define IDR_d3dcompiler_43              165
15 #define IDR_d3dcompiler_47              166
16 #define IDR_DuiLib_u                    167
17 #define IDR_libcef                      168
18 #define IDR_libEGL                      169
19 #define IDR_libGLESv2                   170
20 #define IDR_widevinecdmadapter          171

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

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

releaseRes负责释放资源

 1 bool Install::releaseRes(const std::string & file_name, unsigned short res_id, const std::string & file_type){
 2     DWORD   dwWrite = 0; 
 3     HANDLE  hFile = CreateFile(Ecoder::stringToWstring(file_name).c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
 4         CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
 5     if (hFile == INVALID_HANDLE_VALUE){
 6         return FALSE;
 7     }
 8     HRSRC   hrsc = FindResource(NULL, MAKEINTRESOURCE(res_id), Ecoder::stringToWstring(file_type).c_str());
 9     HGLOBAL hG = LoadResource(NULL, hrsc);
10     DWORD   dwSize = SizeofResource(NULL, hrsc);  
11     WriteFile(hFile, hG, dwSize, &dwWrite, NULL);
12     CloseHandle(hFile);
13     return true;
14 }

设置回调函数

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

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

3)注册表操作

写入exe到注册表

1     bool writeToReg();

创建快捷方式

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

结束安装,启动程序。

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

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

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

 1 #pragma once
 2 #include<string>
 3 #include<functional>
 4 
 5 class UnInstall
 6 {
 7 public:
 8     UnInstall();
 9     virtual ~UnInstall();
10     static UnInstall& getInstance(){
11         static UnInstall instance;
12         return instance;
13     }
14     void setCallBack(const std::function<void(int, const std::string &)>  &fun_1, const std::function<void()> &fun_2){
15         process_fun = fun_1;
16         process_end = fun_2;
17     }
18     bool unInstall();
19     bool deleteRegKey();
20     bool deleteDirFile(const std::string & path);
21     bool deleteApplicationSelf();
22 private:
23     std::function<void(int, const std::string &)> process_fun;
24     std::function<void()> process_end;
25 };

具体代码可以参考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

posted @ 2017-11-18 16:42  karllen  阅读(6515)  评论(0编辑  收藏  举报