基本过程如下:
将需要的数据文件放入资源文件中。
判断是否已经安装,如果没有,开始安装,否则直接运行。
提示用户选择安装目录
拷贝文件:将数据文件从资源文件中释放出来;拷贝自身;
创建快捷方式完成安装,设置标志表示安装完成。
下面我说明一些重点环节:
一、把数据文件放入资源文件中和进行释放
1、 加入资源文件
平常我们在VC6的IDE环境中添加资源,VC只会列出一些常见的类型,如菜单、对话框等,其实我们可以添加任意文件。在资源中选择 IMPORT,在对话框中选择我们需要的文件,例如 c:/io.sys,由于不是VC6默认的资源类型,所以会弹出对话框提示输入资源类型,我在这里定义为sf,确定后,IO.SYS文件就已经包含在我们程序的资源中了,ID号,默认为IDR_SF1。
2、 释放资源:
HRSRChRes = FindResource(NULL,MAKEINTRESOURCE(IDR_SF1),_T("sf"));
//获得IO.SYS资源的指针。参数1是程序的句柄,;参数2是资源名称;参数3是资源类型。
DWORDdwSize = SizeofResource(NULL , hRes); //获得指定资源的大小
HGLOBALMemoryHandle = LoadResource(NULL, hRes);//将资源载入内存
if(MemoryHandle!= NULL)
{
BYTE *MemPtr = (BYTE *)LockResource(MemoryHandle); //定位资源位置
CFilefile("c://iosf.sys",CFile::modeCreate &line; CFile::modeWrite);
file.Write(MemoryHandle,dwSize);
//创建一个临时文件,写入资源数据
}
这样,我们就把一个文件保存到资源文件并从资源中释放,最后,我们通过ULTRAEDIT或者WINDIFF进行一下比较,测试是否复制正常。
二、提示目录选择
1、显示目录选择对话框
BROWSEINFO bBinfo;
memset(&bBinfo,0,sizeof(BROWSEINFO)); //定义结构并初始化
bBinfo.hwndOwner=m_hWnd;//设置对话框所有者句柄
char strTmp[255];
bBinfo.lpszTitle="请选择安装路径:";
bBinfo.ulFlags = BIF_RETURNONLYFSDIRS; //设置标志只允许选择目录
LPITEMIDLISTlpDlist;
//用来保存返回信息的IDList,使用SHGetPathFromIDList函数转换为字符串
lpDlist=SHBrowseForFolder(&bBinfo) ; //显示选择对话框
if(lpDlist!=NULL)
{
SHGetPathFromIDList(lpDlist,strTmp);//把项目标识列表转化成目录
TRACE(strTmp);
}
2、 判断路径是否有效
一般大家可能以为上面步骤就已经完成了安装路径选择,但是不行,因为用户有可
能选择的是软驱或者光驱之类的文件夹,所以我们必须判断目录的有效性。
if(GetDriveType(CString(strTmp).Left(1))!=DRIVE_FIXED)
首先取出返回目录的前三个字符,用GetDriveType获得驱动器的类型属性,如果不是硬盘,那么我们就需要做相应的处理了
三、创建程序的快捷方式
1、创建快捷方式
在VC中,微软已经提供了这方面的COM接口:IshellLink,该类提供了对快捷方式的创建、修改等函数,我们需要引用该接口,进行自己需要的操作。
BOOL CreateLink(LPCSTR pszFile, LPCSTR pszLink)
PszFile:程序路径,例如“D:/PWIN98/ EXPLORER.EXE”;
pszLink:快捷方式路径,如果我们在DOS查看快捷方式,就可以发现它其实是一个 后缀名为“LNK”的文件,例如“C:/EXPLORER.LNK”。
现在说明函数主体:
{
CoInitialize(NULL);//初始化COM接口
HRESULT hres;
IShellLink *psl; / /定义一个ISHELLLINK对象
hres = CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLink, (void **)&psl); //创建实例
if (!SUCCEEDED (hres))//如果创建失败,返回
return FALSE;
IPersistFile *ppf;// 定义IpersistFile对象,用来保存ISHELLLINK对象
hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf);
//从ISHELLLINK对象中获得IpersistFile对象的接口。
if (!SUCCEEDED (hres))
{
psl->Release ();//释放ISHELLLINK对象
return FALSE;
}
hres = psl->SetPath (pszFile);
//使用ISHELLLINK的SETPATH方法设置快捷方式中的程序路径
WORD wsz [MAX_PATH]; // 定义Unicode字符串
MultiByteToWideChar (CP_ACP, 0, pszLink, -1, wsz, MAX_PATH);
// 确保快捷方式路径由ANSI字符组成
hres = ppf->Save (wsz, TRUE); //保存快捷方式
ppf->Release ();//释放IpersistFile对象
psl->Release ();//释放ISHELLLINK对象
return TRUE;
}
以上就是一个比较简单创建快捷方式的函数,更多细节请参考MSDN中的说明。
2、获得各种系统目录
只是能够创建快捷方式是不够的,我们还要将快捷方式创建到我们指定的位置当中,例如开始菜单、桌面以及IE快速启动栏,甚至启动程序组中。
为了获得这些特殊目录,我们必须使用SHGetSpecialFolderLocation函数,该函数需要三个参数:
HWND hwndOwner, 母窗口的句柄;int nFolder, 指定的特殊目录;
LPITEMIDLIST *ppidl
以下是代码示例:
LPITEMIDLIST ppidl; //定义IDLIST指针
charlinkpath[255]; //定义字符串,保存目录名
获得桌面路径:
SHGetSpecialFolderLocation(NULL,0 ,&ppidl);
SHGetPathFromIDList(ppidl,linkpath);
获得程序组路径
SHGetSpecialFolderLocation(NULL,CSIDL_PROGRAMS ,&ppidl);
SHGetPathFromIDList(ppidl,linkpath);
获得启动程序项路径
SHGetSpecialFolderLocation(NULL,CSIDL_STARTUP ,&ppidl);
SHGetPathFromIDList(ppidl,linkpath);
获得IE快速启动栏路径
SHGetSpecialFolderLocation(NULL,CSIDL_APPDATA ,&ppidl);
SHGetPathFromIDList(ppidl,linkpath);
strcat(linkpath,"/Microsoft/Internet Explorer/Quick Launch");
如果我们改变SHGetSpecialFolderLocation函数中的nFolder参数,就可以获得不同的特殊目录,更多的信息请查看MSDN帮助。
以上代码在VC6,WIN98以及WIN2K下测试通过,至于其他的细节,例如设置标志,我们可以通过INI文件或者注册表进行,基本我们就可以实现一个简单的安装功能了。