【解析新特性】300W单路输出工业电源>>
电子产品世界 » 论坛首页 » 综合技术 » 创建安装程序的两种方法

共1条 1/1 1 跳转至

创建安装程序的两种方法

菜鸟
2002-06-26 02:56:00    评分
   一、 使 用Visual C++ 编 程 生 成Setup 程 序    生 成Setup 程 序 最 直 接 的 方 法 当 然 是 通 过 编 程 来 实 现。 对 于Windows 平 台 来 说, 没 有 比Visual C++ 更 好 的 开 发 工 具 了( 原 因 很 简 单, 有 谁 能 比Microsoft 更 了 解Windows 平 台 呢 ?)。 下 面 的 例 程 就 是 使 用Visual C++ 5.0 编 译 完 成 的。   Setup 程 序 主 要 处 理 两 个 方 面 的 问 题 :   (1) 用 户 界 面。 评 价 一 个Setup 程 序 的 优 劣 时, 用 户 界 面 是 否 美 观 是 其 中 的 一 个 重 要 因 素。 此 外, 通 过 交 互 式 界 面 还 应 能 够 获 得 用 户 的 相 关 信 息( 比 如 目 标 目 录)。   (2) 文 件 拷 贝 与 程 序 组 的 生 成。 也 就 是 按 照 用 户 输 入 的 信 息, 生 成 相 应 的 目 录 并 完 成 文 件 拷 贝 功 能( 这 要 涉 及 到 解 压 缩 问 题)。 一 般 来 说, 还 应 包 括 将 可 执 行 文 件 的 图 标 添 加 到 指 定 的 程 序 组 中。   1、 为Setup 程 序 设 置 背 景   Setup 程 序 的 用 户 界 面 以 对 话 框 为 主, 不 过 若 有 美 丽 的 背 景 则 能 为 你 的 程 序 增 色 不 少。 你 可 以 选 择 一 个 合 适 的 BMP 文 件, 将 它 插 入 到 工 程 文 件(project) 中, 并 通 过 重 载 主 窗 口 类 的OnPaint() 函 数 显 示 出 来。 值 得 注 意 的 是, 背 景 图 片 不 应 过 于 眩 目, 否 则 会 有 喧 宾 夺 主 之 感。 例 如, 要 加 入 的BMP 文 件 的ID 号 是IDB_BIT。 下 面 给 出 应 加 在OnPaint() 中 的 函 数。   void Background(CDC *pDC)   {    CDC * pmem;    CBitmap * pback;    CBitmap * pold;    BITMAP ff;    pmem=new CDC;    pbit=new CBitmap;    pbit->LoadBitmap(IDB_BIT);    pmem->CreateCompatibleDC(pDC);    pold=(CBitmap *) pmem->SelectObject(pbit);    pbit->GetObject(sizeof(ff),&ff);   pDC->BitBlt(0,0,bm.bmWidth,bm.bmHeight,pmem,0,0, MERGECOPY );    delete pmem->SelectObject(pold);    delete pmem;    return;   }   2、 显 示 全 屏 效 果    一 般 的 主 窗 口 都 有 边 界(border), 如 果 你 更 欣 赏DOS 界 面 中 的 全 屏 效 果, 则 最 好 在 重 载CWnd:: PreCreateWindow(CREATESTRUCT &cs) 时 保 持cs.style 的 缺 省 值, 并 且 在 创 建 主 窗 口 时 使 用CreateEx (WS_EX_TO PMOST,AfxRegisterWndClass(CS_VREDRAW), NULL,WS_VISIBLE|WS_POPUP,0, 0,(GetSystemMetrics (SM_CXSCREEN)),(GetSystemMetrics(SM_CYSCREEN)), HWND_DES KTOP,0);。  3、 保 存 公 用 参 量    通 过 对 话 框, 可 与 使 用 者 交 换 信 息。 那 么, 如 何 将 程 序 运 行 时 必 需 的 参 量( 比 如 说 安 装 目 录) 保 存 起 来 呢 ? 当 然, 可 以 生 成 一 个 配 置 文 件, 不 过 更 为 专 业 的 作 法 是 将 相 关 信 息 存 入 到 系 统 的INI 文 件 中。 如 果 开 发 平 台 是 Windows 95, 则 一 切 都 将 变 得 很 简 单, 因 为 你 面 对 的 就 是 win.ini 文 件, 该 文 件 在Windows 目 录 下。Visual C++ 提 供 了 如 下 的 一 组 函 数 来 操 作 该 文 件。   (1)CWinApp::GetProfileString   CString GetProfileString( LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTST R lpszDefault = NULL );    用 来 读 取lpszSection 区 域 内 的lpszEntry 参 数, 其 缺 省 值 为lpszD efault。   (2)CWinApp::WriteProfileString   BOOL WriteProfileString( LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszValue );    用 来 写 入lpszSection 区 域 内 的lpszEntry 参 数, 其 值 为lpszValue。    如 果 你 的 开 发 平 台 是Winnt, 则 要 麻 烦 一 点。 假 如 你 的 变 量 保 存 在e:\\winnt\sdi.ini 中, 则 在 使 用 以 上 函 数 之 前 必 须 调 用 :   free((void*)m_pszProfileName);   m_pszProfileName=_tcsdup(_T("e:\\winnt\\sdi.ini"));    如 果 要 存 取 的 变 量 并 不 多, 则 也 可 将 它 们 保 存 在 注 册 关 键 字(registry key) 中。 假 如 你 的 变 量 保 存 在Moon 注 册 关 键 字( 一 般 是 你 公 司 的 名 字) 下, 则 在 使 用 以 上 函 数 之 前 必 须 调 用 :   free((void*)m_pszRegistryKey);   m_pszRegistryKey=_tcsdup(_T("HKEY_CURRENT_ USER\\Software\\moon"));   4、 文 件 的 拷 贝 与 解 压 缩    如 果 你 的 安 装 程 序 是 针 对 软 盘 的, 则 存 储 空 间 就 成 了 必 须 考 虑 的 问 题。 原 封 不 动 地 把 应 用 程 序 拷 贝 上 去 未 免 太 傻 了, 较 为 合 适 的 方 法 是 将 应 用 程 序 压 缩 在 软 盘 中 , 安 装 时 再 解 压 缩 到 相 应 的 目 标 目 录 中。Visual C++ 提 供 了 一 套 以LZ 开 头 的 函 数, 用 来 操 作 用Compress 命 令 压 缩 的 文 件 : 你 可 以 用LzOpenFile() 打 开 原 文 件 和 目 标 文 件, 然 后 用 LzCopy() 解 压 缩 拷 贝。 该 组 函 数 调 用Windows 系 统 的lzexpand.dll 动 态 链 接 库, 所 以 编 译 链 接 时 一 定 要 注 意 加 入 头 文 件 lzexpand.h, 并 插 入 接 口 库lz32.lib。    还 有 个 更 为 简 单 的 办 法, 即 先 用 像arj.exe 这 类 的 共 享 压 缩 程 序 压 缩 原 程 序, 然 后 调 用system("arj ...") 来 完 成 解 压 缩, 整 个 解 压 缩 过 程 在 后 台 进 行, 用 户 不 会 知 道 你 到 底 用 的 是 什 么 方 法。   5、 显 示 拷 贝 进 度    很 多 专 业 安 装 程 序 在 进 行 文 件 拷 贝 时 都 会 显 示 进 度 栏, 甚 至 还 带 有 动 画。 如 何 实 现 这 种 效 果 呢 ? 办 法 是 在 拷 贝 的 同 时 创 建 一 个modeless 对 话 框。 这 种 对 话 框 用create() 函 数 创 建, 类 似 于 创 建 了 一 个 与 主 线 程 独 立 的 新 线 程。 这 样 就 可 在 拷 贝 文 件 的 同 时 在 对 话 框 中 显 示 出 拷 贝 进 度 。Visual C++ 提 供 了 两 个 很 有 用 的 控 件, 即CAnimateCtrl 和 CProgressCtrl。 可 在 对 话 框 中 画 出 这 两 个 控 件, 并 用 ClassWizard 加 入 相 应 的 类。 其 中,CAnimateCtrl 是 用 来 显 示.avi 文 件 的, 使 用 它 即 可 在 每 个 文 件 拷 贝 成 功 后 启 动 一 个“ 小 纸 片 飞 过” 的 文 件 ;CProgressCtrl 用 来 显 示 拷 贝 进 度, 当 各 个 拷 贝 成 功 后 使 表 示 进 度 的 蓝 条 前 进 到 适 当 的 位 置。   6、 程 序 组 和 程 序 项 的 生 成    程 序 组 的 生 成 实 际 上 是 与 负 责 管 理 程 序 组 的Program Manager 进 行DDE 对 话, 你 可 以 通 过 该 对 话 来 添 加 相 应 的 程 序 组 和 应 用 程 序 的 图 标。 同 时 由 于 该 对 话 是 单 向 的, 所 以 负 责 处 理 反 馈 消 息 的callback() 函 数 不 进 行 任 何 处 理。 下 面 给 出 其 源 程 序 及 其 用 法。   HDDEDATA CALLBACK DDECallback( UINT uType, // transaction type    UINT uFmt, // clipboard data format    HCONV hconv, // handle to the conversation    HSZ hsz1, // handle to a string    HSZ hsz2,    // handle to a string    HDDEDATA hdata, // handle to a global memory object    DWORD dwData1,    // transaction-specific data    DWORD dwData2    // transaction-specific data   )   {return NULL;}   SendDdeCmd(LPSTR cmd)   {    LPDWORD dwDDEInst=0L;    UINT ui;    HSZ hszService,hszTopic,hszItem;    HCONV hConv;    HDDEDATA hexecData;    ui=DdeInitialize((unsigned long *)&dwDDEInst, DDECallback,CBF_FAIL_ALLS VRXACTIONS,0L);    if(ui!=DMLERR_NO_ERROR)    {return FALSE;}    hszService=DdeCreateStringHandle( (DWORD) dwDDEInst,"PROGMAN",CP_WINANS I);    hszTopic=DdeCreateStringHandle((DWORD)dwDDEInst, "PROGMAN",CP_WINANSI);    hszItem=DdeCreateStringHandle((DWORD)dwDDEInst,"GROUP", CP_WINANSI);    hConv=DdeConnect((DWORD)dwDDEInst,hszService, hszTopic,NULL);   DdeFreeStringHandle((unsigned long)dwDDEInst, hszService);   DdeFreeStringHandle((unsigned long)dwDDEInst, hszTopic);   DdeFreeStringHandle((unsigned long)dwDDEInst, hszItem);   if(!hConv)   return FALSE;   hexecData=DdeCreateDataHandle((DWORD)dwDDEInst,(unsigned char *)cmd,lstr len(cmd)+1,0,NULL,0,0);   DdeClientTransaction((unsigned char *)hexecData, (DWORD)-1,hConv,NULL,0, XTYP_EXECUTE,1000,NULL);   DdeDisconnect(hConv);   DdeUninitialize((unsigned long)dwDDEInst);   return TRUE;   }    如 果 你 想 加 入 一 个 名 叫“demo” 的 程 序 组, 其 中 包 含 有 名 称 为“test” 的 程 序 项, 并 执 行c:\demo\test.exe, 使 用 的 是“test.ico” 图 标, 则 可 按 如 下 方 式 调 用 该 函 数 :   SendDdeCmd("[CreateGroup (demo)] [AddItem (c:\demo\test.exe, test,c:\dem o\test.ico)]")    二、 利 用 工 具 软 件 创 建 安 装 程 序    使 用Visual C++ 编 程 能 够 生 成 功 能 强 大 的Setup 程 序。 不 过, 如 果 你 更 喜 欢 利 用 现 成 的 工 具, 则 不 妨 试 一 试 用 于 创 建 安 装 程 序 的 工 具 软 件InstallShield5 Free Edition。 该 软 件 提 供 了 一 种 类 似 于Basic 的 编 程 语 言, 清 晰 易 懂。    创 建 一 个 新 的 安 装 程 序 时, 可 从Project Wizard 开 始, 首 先 启 动 的 是 一 个Welcome 对 话 框, 它 包 括 以 下 几 项 内 容 :   (1)Application Name (edit box)    在 这 个 对 话 框 中 输 入 你 想 要 安 装 的 应 用 程 序 的 名 字, InstallShield 将 用 该 名 字 注 册 登 记 并 生 成 你 的 程 序 组。   (2)Development Environment (list box)    选 择 开 发 该 应 用 程 序 的 环 境( 如Visual C++)。   (3)Application Type (list box)    选 择 你 的 应 用 程 序 的 类 别。   (4)Application Version (edit box)    选 择 你 的 应 用 程 序 的 版 本。   (5)Application Executable (edit box)    输 入 应 用 程 序 的 主 运 行 文 件, 或 单 击 ... 寻 找 该 文 件。   (6) 单 击“ 下 一 步”,select dialogs    选 择 你 的 安 装 程 序 所 需 要 的 对 话 框, 如 果 你 暂 时 还 不 能 确 定 的 话, 则 可 按Preview 键 预 览 一 下。   (7) 单 击“ 下 一 步”, 选 择 适 合 于 该 应 用 程 序 的 操 作 系 统 平 台。 你 可 以 选 择Win 95、Winnt 3.x 或Winnt4.0。   (8) 单 击“ 下 一 步”, 选 择 安 装 程 序 使 用 的 语 言。 在 这 种free 版 本 中, 你 所 能 作 的 唯 一 选 择 就 是“ 英 语”。   (9) 如 果 你 想 在 你 的 安 装 程 序 中 包 括 多 种 安 装 类 型 选 择, 则 单 击“ 下 一 步”。 启 动 的 对 话 框 中 提 供 了 上 述 功 能, 从 中 你 可 选 择Compact、 Typical、 Custom 及Network 等 多 种 安 装 类 型。   (10) 单 击“ 下 一 步”, 选 择 你 想 要 安 装 的 组 件, 这 些 组 件 的 不 同 组 合 即 是 你 在 上 面 选 择 的 不 同 安 装 类 型。   (11) 单 击“ 下 一 步”, 选 择 你 想 要 创 建 的 文 件 组, 该 文 件 组 是 你 的 应 用 程 序 所 包 括 文 件 的 逻 辑 分 组, 这 种 逻 辑 分 组 对 应 于 上 面 的 组 件。   (12) 单 击“ 下 一 步”, 概 括( 即“Summary” ) 你 所 输 入 的 信 息 。 如 果 不 满 意, 则 还 可 以 修 改 ; 如 果 满 意 的 话, 则 按“ 完 成” 键, 一 个 安 装 程 序 的 框 架 就 大 功 告 成 了。    下 面 介 绍 制 作 供 安 装 程 序 使 用 的 工 程 文 件。    实 际 上,Project Wizard 已 经 为 你 作 好 了 大 部 分 的 工 作。 为 了 创 建 一 个 完 整 的 安 装 程 序, 首 先 要 弄 清 楚 工 程 文 件 中 各 个 项 目 间 的 关 系。 这 要 从File Group 说 起。File Group 是 应 用 程 序 文 件 的 逻 辑 分 组, 在 每 个 文 件 夹 下 都 有link 项, 用 右 键 单 击 该 位 置, 选 择 插 入 项, 则 可 将 你 的 应 用 文 件 进 行 适 当 分 组。 每 个File Group 中 含 有 若 干 属 性 值, 单 击 该 属 性 则 可 对 其 进 行 修 改。 比 如, 对 于Compress 项, 你 可 以 选 择 是 否 对 该File Group 下 的 文 件 进 行 压 缩。 几 个File Group 可 以 同 属 于 一 个Component, 通 过 划 分Component 你 可 以 区 分 不 同 的 安 装 方 式。 每 个Component 也 有 若 干 属 性 : 其 中,Destination 项 供 你 选 择 该Component 将 要 安 装 到 的 目 标 目 录 ;Installation 项 供 你 选 择 遇 到 相 同 文 件 名 时 的 处 理 方 式 ;SetupType 项 供 你 选 择 不 同 的 安 装 类 型 所 安 装 的 组 件(Component)。 下 面, 你 将 进 入Script Files 项, 它 是 你 的 安 装 程 序 的 脚 本 程 序, 如 果 你 只 想 创 建 一 个 标 准 的 安 装 程 序, 则 只 需 对 其 作 很 小 的 改 动 即 可。 由 于 系 统 没 有 为 你 生 成 创 建 程 序 组 的 部 分, 所 以 必 须 手 工 修 改function SetupFolders() 函 数, 在 DialogShowSdSelectFolder() 中, 安 装 脚 本 已 经 将 要 生 成 的 目 标 程 序 组 存 入 到 变 量svDefGroup 中, 所 以 你 只 需 在SetupFolders() 中 加 入 以 下 几 行 内 容( 假 设 你 想 加 入 一 个 名 为“demo” 的 项, 执 行c:\demo.exe 文 件, 使 用 的 图 标 是“c:\demo.ico”, 工 作 目 录 为“c:\test”, 用“Ctrl + Alt + 1” 作 为 热 键, 并 且 该 程 序 项 将 作 为 该 程 序 组 的 第 一 项, 该 程 序 执 行 时 将 被 最 大 化)。   STRING szProgram ="c:\demo.exe"   STRING szParam = " "   LongPathToQuote (szProgram, TRUE);   LongPathToShortPath (szParam);   STRING szCommandLine = szProgram + " " + szParam;   AddFolderIcon(svDefGroup, "demo",szCommandLine, "c:\test","c:\demo.ico", 0, "Ctrl +Alt + 1", REPLACE |RUN_MAXIMIZED);    现 在 修 改Resource 项, 其 中String Table 存 储 的 是 显 示 在 对 话 框 里 的 各 种 字 符 变 量。 例 如,FOLDER_NAME 是 你 的 程 序 组 的 缺 省 名 字,PRODUCT_KEY 是 你 的 程 序 项 的 运 行 文 件, PRODUCT_NAME 是 你 的 程 序 项 的 名 字,TITLE_CAPTIONBAR 将 显 示 在 你 的 安 装 程 序 背 景 窗 口 的 上 边 框 内,TITLE_MAIN 将 显 示 在 你 的 安 装 程 序 背 景 窗 口 上。 对 于Win 95、Winnt 4.0 的 用 户,UNINST_DISPLAY_NAME 将 显 示 在 控 制 面 板 的“ 添 加/ 删 除 程 序” 的 列 表 中。    在Setup file 这 一 项 中, 你 可 以 修 改 安 装 程 序 开 始 时 显 示 的 图 片, 只 需 将 编 辑 好 的 文 件 插 入 到Splash Screen 的Language Independent 下, 并 改 名 为Setup.bmp 即 可。    如 果 你 已 经 正 确 地 添 如 了 上 述 各 项 内 容, 则 下 面 所 要 做 的 事 情 就 是 打 开Media 项 单 击 右 键 选 择 其 中 的 Media Build Wizard 以 便 创 建 应 用 程 序 的 物 理 存 储 结 构。 如 果 你 选 择 的 是 软 盘 方 式, 则 自 动 生 成 按 照Disk 划 分 的 目 标 程 序。 至 此, 利 用 工 具 软 件InstallShield 创 建 安 装 程 序 的 过 程 宣 告 结 束。 ------------------------------------------------------------------------送大家一个关于中国电信收费由3分钟1毛八变成一分钟1毛2的一些数据来源: 记者: 有人说按一分钟记费不合理,而且对你们的统计结果,就是"经过调查表明, 市民每打一次电话,通话时长在1分钟以下的占60%,两分钟以内的占30%, 3分钟以上的只占10%表示怀疑,能否详细解释一下? 电信有关负责人: 当然可以!实际上,这是我们亲自实践调查得出的科学结论 记者: 能详细解释一下你们的调查过程吗? 电信有关负责人: 可以,为了得到第一手材料,我们在全国范围内随机抽取了100位用户, 并且拨通了他们的电话,询问他们对电信费用的看法,其中,有60%的是这样说的..... 记者: 说什么? 电信有关负责人: "操中国电信你妈!" 然后就挂机了,实际上,开头的60个电话都是这样 的 记者: ....... 电信有关负责人: 所以接下来的30个电话我们改变了一下问话的方式 ,我们以可以免费参 加抽奖来吸引被询问的用户,为了详细说明抽奖的细则和说明, 我们用了1分30秒,然后提问 :您对电信费用的看法?用了10秒,用户回答:操中 国电信你妈!;用了3秒,共计1分43秒,按四 舍五入为2分钟. 记者: ........ 电信有关负责人: 最后的10个电话我们总结了经验教训,派上了几个声音甜甜的电信小姐对 用户询问, 小姐的第一句话是:先生你很你寂寞吗?要我陪你聊聊吗?.....然后,这10个电话 时间统统超过了3分钟.... 记者: 那这最后10个人说什么? 电信有关负责人: 他们都认识到了自己的错误!纷纷表示'操中国电信你妈'是不对的,是 极其不明智的选择 记者: 看来你们的教育指导获得了成功! 电信有关负责人: 不!他们认为与其操中国电信他妈不如操中国电信的小姐... 记者: .........靠! I 服了 YOU!



关键词: 创建     安装     程序     两种     方法     dwDDEInst         

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]