vc++开发安装程序实例

C#

浏览数:227

2019-6-8

AD:资源代下载服务

前言 市面上有很多安装程序制作软件;但是,要实现个性化安装程序,还是自己动手来写一个更为妥当。本文介绍基本的安装程序制作的步骤。

安装程序界面:

 安装程序可以分为几个功能点: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++;
    }

 

作者:源之缘