使用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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM