vc 制作安装文件

时间:2022-12-30 00:12:41

基本过程如下:
将需要的数据文件放入资源文件中。
判断是否已经安装,如果没有,开始安装,否则直接运行。
提示用户选择安装目录
拷贝文件:将数据文件从资源文件中释放出来;拷贝自身;
创建快捷方式完成安装,设置标志表示安装完成。
下面我说明一些重点环节:

一、把数据文件放入资源文件中和进行释放

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文件或者注册表进行,基本我们就可以实现一个简单的安装功能了。