一
实例
1.1 安装程序
![](https://p-blog.csdn.net/images/p_blog_csdn_net/skdev/ad1adfdad8cb4093b7be5097d1526377.png)
![](https://p-blog.csdn.net/images/p_blog_csdn_net/skdev/61e6ade2656b47289c7bc1532995380c.png)
![](https://p-blog.csdn.net/images/p_blog_csdn_net/skdev/27a6488de87e41cf89c860e1db080c8f.png)
![](https://p-blog.csdn.net/images/p_blog_csdn_net/skdev/4e3508fb45754d7096f06372e14f3d8f.png)
![](https://p-blog.csdn.net/images/p_blog_csdn_net/skdev/52c7afa23e954870b39a2d3d2b4d20c1.png)
1.2 卸载程序
![](https://p-blog.csdn.net/images/p_blog_csdn_net/skdev/23cd08beca714f809ba9f762d48fe978.png)
二
思路
2.1 安装程序
1 如何将目的程序附加在安装程序里?一般安装程序只有一个可执行文件,因而目的程序也放在安装程序里面,通过将目标程序放在资源文件,可以使目标程序像资源一样使用。目标程序在资源的类型是#define RC_BINARYTYPE 256,格式如下:
//#resource.h
#define
RC_BINARYTYPE 256
#define
ID_MAIN 3000 //ID_MAIN表示主程序的资源ID
//xxx.rc
#include “resource.h”
ID_MAIN
RC_BINARYTYPE “XXX.exe” //目标程序
2 如何将资源里的文件解压到目标路径?①用FindResource,LoadResource,LockResource等将资源加载到缓冲区,②然后用CreateFile,WriteFile,CloseFile等将缓冲区的数据写到目标路径。
3 如何对用COMPRESS压缩的文件进行解压?用LZOpenFile,LZCopy,LZClose等解压。
4 如何创建开始菜单和桌面的快捷方式?用SHGetSpecialFolderPath(NULL,StartMenuPath,CSIDL_PROGRAMS,0);获取开始菜单路径,用SHGetSpecialFolderPath(NULL,StartDeskPath,CSIDL_DESKTOP,0);获取桌面路径。用IshellLink创建快捷方式
2.2 卸载程序
1 删除已安装的所有文件。DeleteFile
2 删除快捷方式。DeleteFile
3 删除卸载程序本身。
三
代码
/*名称:WriteResourceToFile
功能:将资源中指定的文件写到filename
参数:hInstance句柄,idResource资源ID,filename生成的文件
*/
void WriteResourceToFile(HINSTANCE hInstance,int idResource,char const *filename)
{
HRSRC hResInfo=FindResource(hInstance,MAKEINTRESOURCE(idResource),MAKEINTRESOURCE(RC_BINARYTYPE));
HGLOBAL hgRes=LoadResource(hInstance,hResInfo);
void *pvRes=LockResource(hgRes);
DWORD cbRes=SizeofResource(hInstance,hResInfo);
HANDLE hFile=CreateFile(filename,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
DWORD cbWritten;
WriteFile(hFile,pvRes,cbRes,&cbWritten,0);
CloseHandle(hFile);
}
/*名称:DecompressFile
功能:对COMPRESS压缩文件进行解压
参数:source压缩的文件,解压成的文件
*/
void DecompressFile(char const *source,char const *dest)
{
OFSTRUCT ofs;
ofs.cBytes=sizeof(ofs);
int zhfSource=LZOpenFile(const_cast<char*>(source),&ofs,OF_READ);
int zhfDest=LZOpenFile(const_cast<char*>(dest),&ofs,OF_CREATE|OF_WRITE);
LZCopy(zhfSource,zhfDest);
LZClose(zhfSource);
LZClose(zhfDest);
}
#include <shlobj.h>
#pragma comment(lib,"shell32.lib")
/*名称:CreateProgFolder
功能:创建开始菜单程序组
参数:程序组名称
*/
int
CreateProgFolder(LPSTR folder)
{
char foldbuff[MAX_PATH];
SHGetSpecialFolderPath(NULL,foldbuff,CSIDL_PROGRAMS,0); //创建开始
sprintf(foldbuff,"%s//%s",foldbuff,folder);
CreateDirectory(foldbuff,NULL);
return 1;
}
/*名称:CreateProgLink
功能:创建开始菜单的快捷方式
参数:lpszSrcPath源文件路径,linkname快捷方式名称,lpszWorkingPath工作目录,Desc注释
*/
int CreateProgLink(LPSTR lpszSrcPath,LPSTR linkname,LPSTR lpszWorkingPath,LPSTR Desc)
{
char StartMenuPath[MAX_PATH];
SHGetSpecialFolderPath(NULL,StartMenuPath,CSIDL_PROGRAMS,0); //创建开始
sprintf(StartMenuPath,"%s//%s",StartMenuPath,linkname);
CreateLink(lpszSrcPath,StartMenuPath,lpszWorkingPath,Desc);
return 1;
}
/*名称:CreateDeskLink
功能:创建桌面的快捷方式
参数:lpszSrcPath源文件路径,linkname快捷方式名称,lpszWorkingPath工作目录,Desc注释
*/
int CreateDeskLink(LPSTR lpszSrcPath,LPSTR linkname,LPSTR lpszWorkingPath,LPSTR Desc)
{
char StartDeskPath[MAX_PATH];
SHGetSpecialFolderPath(NULL,StartDeskPath,CSIDL_DESKTOP,0); //创建开始
sprintf(StartDeskPath,"%s//%s",StartDeskPath,linkname);
CreateLink(lpszSrcPath,StartDeskPath,lpszWorkingPath,Desc);
return 1;
}
/*名称:CreateLink
功能:创建快捷方式
参数:lpszSrcPath源文件路径,lpszPathLink快捷方式路径,lpszWorkingPath工作目录,Desc注释
*/
HRESULT
CreateLink(LPCSTR lpszSrcPath,LPSTR lpszPathLink,LPSTR lpszWorkingPath,LPSTR lpszDesc)
{
HRESULT hres ;
IShellLink * psl ;
IPersistFile * ppf ;
WORD wsz[ MAX_PATH] ;
CoInitialize(NULL);
hres = CoCreateInstance( CLSID_ShellLink, NULL,
CLSCTX_INPROC_SERVER, IID_IShellLink,
(void **)&psl) ;
if( FAILED( hres))
return FALSE ;
//设置目标应用程序
psl -> SetPath( lpszSrcPath) ;
psl -> SetDescription(lpszDesc);
psl -> SetWorkingDirectory(lpszWorkingPath);
//从IShellLink获取其IPersistFile接口
//用于保存快捷方式的数据文件 (*.lnk)
hres = psl -> QueryInterface( IID_IPersistFile, (void**)&ppf);
if( FAILED( hres))
{
psl -> Release( ) ;
return FALSE ;
}
// 确保数据文件名为ANSI格式
MultiByteToWideChar( CP_ACP, 0, lpszPathLink, -1,wsz, MAX_PATH) ;
//调用IPersistFile::Save
//保存快捷方式的数据文件 (*.lnk)
hres = ppf -> Save( wsz, STGM_READWRITE) ;
//释放IPersistFile和IShellLink接口
ppf -> Release( ) ;
psl -> Release( ) ;
//记录
WriteFile(hFileLog,lpszPathLink,strlen(lpszPathLink),&bNum,NULL);
WriteFile(hFileLog,"/r/n",2,&bNum,0);
return 1;
}
卸载程序自我删除,需用到一个动态链库,具体应用参考“参考文献”
void SelfDelete(HINSTANCE hInstance)
{
WriteResourceToFile(hInstance,ID_DLL,"instdll.dll");
//生成命令行
//查找rudll32.exe
char commandLine[MAX_PATH*3];
GetWindowsDirectory(commandLine,sizeof(commandLine));
lstrcat(commandLine,"//rundll32.exe");
if(GetFileAttributes(commandLine)==0xFFFFFFFF)
{
GetSystemDirectory(commandLine,sizeof(commandLine));
lstrcat(commandLine,"//rundll32.exe");
}
//添加rundll32.exe参数
lstrcat(commandLine," instdll.dll,_MagicDel@16 ");
char thisName[MAX_PATH];
GetModuleFileName(hInstance,thisName,sizeof(thisName));
lstrcat(commandLine,thisName);
PROCESS_INFORMATION procInfo;
STARTUPINFO startInfo;
memset(&startInfo,0,sizeof(startInfo));
startInfo.dwFlags=STARTF_FORCEOFFFEEDBACK;
CreateProcess(0,commandLine,0,0,FALSE,NORMAL_PRIORITY_CLASS,0,0,&startInfo,&procInfo);
}