一、具体思路
安装过程:安装包的制作包括资源文件的打包,资源文件打包到安装包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等。
时间: 2024-11-13 10:06:48