vc++开发安装程序实例
前言 市面上有很多安装程序制作软件;但是,要实现个性化安装程序,还是自己动手来写一个更为妥当。本文介绍基本的安装程序制作的步骤。
安装程序界面:
安装程序可以分为几个功能点:1 资源的嵌入、释放。2 资源的解压。3 生成快捷方式。
1 资源导入和释放
导入 在VS资源视图,点击“”添加资源“,再选择“导入资源”,将需要安装的程序导入即可。导入的资源一般是安装程序的压缩包。
释放:将资源释放到指定目录
//将指定资源释放到指定目录下生成特定文件 //ResName 资源名称;ResType:资源类型;FileName:释放后的文件名。 BOOL FreeMyData(LPCTSTR ResName, LPCTSTR ResType, LPCTSTR FileName, int Type) { BOOL bRet = TRUE; HINSTANCE hInst = AfxGetInstanceHandle(); //先判断我们指定的资源是否存在 HRSRC hResInfo = FindResource(hInst, ResName, ResType); if (hResInfo == NULL) return FALSE; HANDLE hFile = NULL; DWORD dwWritten = 0; //开始调入指定的资源到内存 HGLOBAL hResData = LoadResource(hInst, hResInfo); LPVOID pvResData = LockResource(hResData); DWORD dwResSize = SizeofResource(hInst, hResInfo); //再创建目标文件并保存数据至文件 if (Type == 1)//系统加隐藏属性 如果指定类型为1,那么加上系统和隐藏属性,防止普通用户对文件进行破坏 { hFile = CreateFile(FileName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM, NULL); WriteFile(hFile, pvResData, dwResSize, &dwWritten, NULL); } else { hFile = CreateFile(FileName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); WriteFile(hFile, pvResData, dwResSize, &dwWritten, NULL); } if (hFile == INVALID_HANDLE_VALUE)//创建文件失败 { FreeResource(hResData); return FALSE; } //释放有关内存资源 CloseHandle(hFile); FreeResource(hResData); return TRUE; }
调用示例:
2 资源的解压 暨对zip文件解压。本文采用开源代码解压文件。具体调用不再详述。压缩源代码下载。
3 生成快捷方式 生成快捷方式分为两步:1 获取存放快捷文件的目录; 2 生成快捷方式文件(.lnk)。
1 获取存放目录 一般在“桌面“和“开始菜单”创建快捷方式。“桌面“其实对应于Windows系统特定的目录,一般而言该目录为“C:\Users\admin\Desktop”。windows提供了函数获取该目录。对于“开始菜单”处理亦是如此。
//得到当前桌面路径 BOOL SetupHelper::GetDesktopPath(wchar_t *pszDesktopPath) { LPITEMIDLIST ppidl = NULL; if (SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &ppidl) == S_OK) { BOOL flag = SHGetPathFromIDList(ppidl, pszDesktopPath); CoTaskMemFree(ppidl); return flag; } return FALSE; } //得到 开始->程序组 的路径 BOOL SetupHelper::GetProgramsPath(wchar_t *pszProgramsPath) { LPITEMIDLIST ppidl; if (SHGetSpecialFolderLocation(NULL, CSIDL_PROGRAMS, &ppidl) == S_OK) { BOOL flag = SHGetPathFromIDList(ppidl, pszProgramsPath); CoTaskMemFree(ppidl); return flag; } return FALSE; }
2 生成快捷方式文件(.lnk)
需要调用系统函数生成lnk文件。
/* 函数功能:对指定文件在指定的目录下创建其快捷方式 函数参数: lpszFileName 指定文件,为NULL表示当前进程的EXE文件。 lpszLnkFileDir 指定目录,不能为NULL。 lpszLnkFileName 快捷方式名称,为NULL表示EXE文件名。 wHotkey 为0表示不设置快捷键 pszDescription 备注 iShowCmd 运行方式,默认为常规窗口 */ BOOL SetupHelper::CreateFileShortcut(LPWSTR lpszFileName, LPWSTR lpszLnkFileDir, LPWSTR lpszLnkFileName, LPWSTR lpszWorkDir, WORD wHotkey, LPWSTR lpszDescription, int iShowCmd ) { if (lpszLnkFileDir == NULL) return FALSE; HRESULT hr; IShellLink *pLink; //IShellLink对象指针 IPersistFile *ppf; //IPersisFil对象指针 //创建IShellLink对象 hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pLink); if (FAILED(hr)) return FALSE; //从IShellLink对象中获取IPersistFile接口 hr = pLink->QueryInterface(IID_IPersistFile, (void**)&ppf); if (FAILED(hr)) { pLink->Release(); return FALSE; } //目标 if (lpszFileName == NULL) pLink->SetPath(_wpgmptr); else pLink->SetPath(lpszFileName); //工作目录 if (lpszWorkDir != NULL) pLink->SetPath(lpszWorkDir); //快捷键 if (wHotkey != 0) pLink->SetHotkey(wHotkey); //备注 if (lpszDescription != NULL) pLink->SetDescription(lpszDescription); //显示方式 pLink->SetShowCmd(iShowCmd); //快捷方式的路径 + 名称 wchar_t szBuffer[MAX_PATH] = {0}; if (lpszLnkFileName != NULL) //指定了快捷方式的名称 wsprintf(szBuffer, L"%s\\%s.lnk", lpszLnkFileDir, lpszLnkFileName); else { //没有指定名称,就从取指定文件的文件名作为快捷方式名称。 wchar_t *pstr; if (lpszFileName != NULL) pstr = wcsrchr(lpszFileName, '\\'); else pstr = wcsrchr(_wpgmptr, '\\'); if (pstr == NULL) { ppf->Release(); pLink->Release(); return FALSE; } //注意后缀名要从.exe改为.lnk wsprintf(szBuffer, L"%s\\%s", lpszLnkFileDir, pstr); int nLen = wcslen(szBuffer); szBuffer[nLen] = L'l'; szBuffer[nLen+1] = L'n'; szBuffer[nLen +2] = L'k'; } //保存快捷方式到指定目录下 hr = ppf->Save(szBuffer, TRUE); ppf->Release(); pLink->Release(); return SUCCEEDED(hr); }
调用示例
//生成桌面快捷方式 wchar_t szPath[MAX_PATH] = {0}; SetupHelper::GetDesktopPath(szPath); int ret = 0; if (SetupHelper::CreateFileShortcut(filePathExe.GetBuffer(), szPath, L"IOT集群调度系统", NULL, MAKEWORD(VK_F12, HOTKEYF_CONTROL), L"集群调度终端")) { ret++; }
专注C#、C++。擅长WPF、WinForm、QT等技术。
研究ofd多年,开发了一些列产品。
技术交流QQ群:565438497。