背景 在使用了一段时间微软自带的安装包打包工具后,总感觉不太顺利,于是便想着找一种更简单稳定的打包工具,这类工具其实还不少,最终经过各种考量,我们选择了InnoSetup,该工具是一个完全免费的Windows打包工具,涉及的功能比较全面,并且采用脚本式编辑,完美支持 Pascal 语言.本文简单描述一下如何自动下载安装 .net framework 框架 及更新卸图标的小技巧,当然本文部分内容借鉴了网上一部分的解决方案.在此整理一下已备忘同时分享给有类似需求的朋友.替换卸载程序图标 该工具制作的安装包,默认生成的卸载程序使用的是和安装程序一样的图标,这样感觉不够直观,可通过 "UpdateIcon.dll" 插件完成. 如下脚本所示. [Files]Source: "UpdateIcon.dll"; Flags: dontcopySource: "uninstall.ico"; Flags: dontcopy[Icons]Name: "{group}\卸载"; Filename: "{uninstallexe}"[Code]functionUpdateIcon(consthWnd: Integer;constexeFileName, exeIcon, IcoFileName: String; wlangID: DWORD): Boolean;external'UpdateIcon@files:UpdateIcon.dll stdcall';//替换卸载图标functionUpdateUninstIcon(constIcoFileName: String): Boolean;beginResult:= UpdateIcon(MainForm.Handle,'','', IcoFileName,0);end;//安装步骤进行开始替换卸载图标procedureCurStepChanged(CurStep: TSetupStep);varsIcon: String;beginifCurStep=ssInstallthenbeginsIcon:= ExpandConstant('{tmp}\uninstall.ico'); //定义卸载图标ExtractTemporaryFile(ExtractFileName(sIcon));//释放卸载图标UpdateUninstIcon(sIcon);//替换卸载图标end;end;自动下载.net framework 组件并安装 可通过 “isxdl.dll” 扩展实现,动态从网络上添加一个待下载的文件,并在下载完之后自动运行.见如下示例.[Code]vardotNetDownloadNeeded: boolean;dotNetLocalPath:string;procedureisxdl_AddFile(URL, Filename: PAnsiChar);external'isxdl_AddFile@files:isxdl.dll stdcall';functionisxdl_DownloadFiles(hWnd: Integer): Integer;external'isxdl_DownloadFiles@files:isxdl.dll stdcall';functionisxdl_SetOption(Option, Value: PAnsiChar): Integer;external'isxdl_SetOption@files:isxdl.dll stdcall';//检测是否存在特定版本的.net frameworkfunctionIsDotNetDetected(version: string; service:cardinal): boolean;// Indicates whether the specified versionandservice packofthe .NET Framework is installed.//// version -- Specify oneofthese stringsforthe required .NET Framework version://'v1.1.4322'.NET Framework1.1//'v2.0.50727'.NET Framework2.0//'v3.0'.NET Framework3.0//'v3.5'.NET Framework3.5//'v4\Client'.NET Framework4.0Client Profile//'v4\Full'.NET Framework4.0Full Installation//'v4.5'.NET Framework4.5//// service -- Specify any non-negative integerforthe required service pack level://0No service packs required//1,2, etc. Service pack1,2, etc. requiredvarkey: string;install, release, serviceCount: cardinal;check45, success: boolean;begin// .NET4.5installs as updateto.NET4.0Fullifversion ='v4.5'thenbeginversion :='v4\Full';check45 :=true;endelsecheck45 :=false;// installation key groupforall .NET versionskey :='SOFTWARE\Microsoft\NET Framework Setup\NDP\'+version;// .NET3.0uses value InstallSuccessinsubkey SetupifPos('v3.0', version) =1thenbeginsuccess := RegQueryDWordValue(HKLM, key +'\Setup','InstallSuccess', install);endelsebeginsuccess := RegQueryDWordValue(HKLM, key,'Install', install);end;// .NET4.0/4.5uses value Servicing insteadofSPifPos('v4', version) =1thenbeginsuccess := successandRegQueryDWordValue(HKLM, key,'Servicing', serviceCount);endelsebeginsuccess := successandRegQueryDWordValue(HKLM, key,'SP', serviceCount);end;// .NET4.5uses additional value Releaseifcheck45thenbeginsuccess := successandRegQueryDWordValue(HKLM, key,'Release', release);success := successand(release >=378389);end;result := successand(install =1)and(serviceCount >=service);end;//准备安装.net framework需要的条件(本地还是联网)functionPreInstallDotNet(dotNetName:string;dotNetDownloadUrl:string):boolean;beginif(notIsAdminLoggedOn())thenbeginMsgBox('您电脑安装 Microsoft .NET Framework 需要管理员权限', mbInformation, MB_OK);Result :=false;endelsebegindotNetLocalPath := ExpandConstant('{src}') +'\'+dotNetName;ifnotFileExists(dotNetLocalPath)thenbegindotNetLocalPath := ExpandConstant('{tmp}') +'\'+dotNetName;ifnotFileExists(dotNetLocalPath)thenbeginisxdl_AddFile(dotNetDownloadUrl, dotNetLocalPath);dotNetDownloadNeeded :=true;end;end;SetIniString('install','dotnetRedist', dotNetLocalPath, ExpandConstant('{tmp}\dep.ini'));end;end;//执行安装.net frameworkfunctionDoInstallDotNet():boolean;varhWnd: Integer;ResultCode: Integer;beginresult :=true;hWnd := StrToInt(ExpandConstant('{wizardhwnd}'));// don’t trytoinit isxdlifit’snotneeded because it will error on < ie3ifdotNetDownloadNeededthenbeginisxdl_SetOption('label','正在下载 Microsoft .NET Framework');isxdl_SetOption('des-c-r-i-p-tion','您还未安装Microsoft .NET Framework. 请您耐心等待几分钟,下载完成后会安装到您的的计算机中。');ifisxdl_DownloadFiles(hWnd) =0thenresult :=false;end;ifresult = truethenbeginifExec(ExpandConstant(dotNetLocalPath),'/qb','', SW_SHOW, ewWaitUntilTerminated, ResultCode)thenbegin// handle successifnecessary; ResultCode contains the exit codeifnot(ResultCode =0)thenbeginresult :=false;end;endelsebegin// handle failureifnecessary; ResultCode contains the error coderesult :=false;end;end;end;//检测是否安装了等于大于指定版本的.net frameworkfunctionIsIncludeFramework(version: string): boolean;varisInclued:boolean;begin//最高版本的ifIsDotNetDetected('v4.5',0)thenbeginisInclued :=true;endelseifversion ='v4.5'thenbeginPreInstallDotNet('dotNetFx45_Full_setup.exe','http://download.microsoft.com/download/B/A/4/BA4A7E71-2906-4B2D-A0E1-80CF16844F5F/dotNetFx45_Full_setup.exe');endelseifIsDotNetDetected('v4\Full',0)thenbeginisInclued :=true;endelseifversion ='v4\Full'thenbeginPreInstallDotNet('dotNetFx40_Full_x86_x64.exe','http://download.microsoft.com/download/9/5/A/95A9616B-7A37-4AF6-BC36-D6EA96C8DAAE/dotNetFx40_Full_x86_x64.exe');endelseifIsDotNetDetected('v4\Client',0)thenbeginisInclued :=true;endelseifversion ='v4\Client'thenbeginPreInstallDotNet('dotNetFx40_Client_x86_x64.exe','http://download.microsoft.com/download/5/6/2/562A10F9-C9F4-4313-A044-9C94E0A8FAC8/dotNetFx40_Client_x86_x64.exe');endelseifIsDotNetDetected('v3.5',0)thenbeginisInclued :=true;endelseifPos('v3.5',version) =1thenbeginPreInstallDotNet('dotNetFx35setup.exe','http://download.microsoft.com/download/7/0/3/703455ee-a747-4cc8-bd3e-98a615c3aedb/dotNetFx35setup.exe');endelseifIsDotNetDetected('v3.0',0)thenbeginisInclued :=true;endelseifPos('v3.0',version) =1thenbeginPreInstallDotNet('dotNetFx35setup.exe','http://download.microsoft.com/download/7/0/3/703455ee-a747-4cc8-bd3e-98a615c3aedb/dotNetFx35setup.exe');endelseifIsDotNetDetected('v2.0.50727',0)thenbeginisInclued :=true;endelseifPos('v2',version) =1thenbeginPreInstallDotNet('dotnetfx.exe','http://download.microsoft.com/download/5/6/7/567758a3-759e-473e-bf8f-52154438565a/dotnetfx.exe');endelseifIsDotNetDetected('v1.1.4322',0)thenbeginisInclued:=true;endelseifPos('v1',version)=1thenbeginPreInstallDotNet('dotNetFx35setup.exe','http://download.microsoft.com/download/7/0/3/703455ee-a747-4cc8-bd3e-98a615c3aedb/dotNetFx35setup.exe');end;result :=isInclued;end;//点击下一步functionNextButtonClick(CurPage: Integer): Boolean;vardotNetVersion:String;beginResult :=true;if(CurPage = wpReady)thenbegindotNetVersion :='v4\Full';ifnotIsIncludeFramework(dotNetVersion)thenbeginifnotDoInstallDotNet()thenbeginMsgBox('当前操作需要安装.NET Framework'+ dotNetVersion +'或以上版本。'#13#13'在尝试自动安装期间,似乎出现一些小问题(或用户取消了安装),'#13'请重试尝试安装。', mbInformation, MB_OK);result:=false;end;end;end;end;关于通用 可以将以上两个小功能点分别保存为独立的innosetup 脚本文件(“.iss”),然后在主安装包脚本中引入这两个文件.如下所示.#include "dotnetSetup.iss"#include "updateuninstallIco.iss"后记a).“Update.dll” 及 “isxdl.dll”如果你实在是找不到,本文提供一个下载链接,可从这里下载.b). 本文中部分方法及思路收集于网络,本人只是加以整理用以备忘.本文链接:Innosetup打包自动下载.net framework 动态库及替换卸载程序图标.,转载请注明。