码迷,mamicode.com
首页 > Web开发 > 详细

Innosetup打包自动下载.net framework 动态库及替换卸载程序图标.

时间:2015-07-10 18:52:57      阅读:290      评论:0      收藏:0      [点我收藏+]

标签:

  1. 背景
         在使用了一段时间微软自带的安装包打包工具后,总感觉不太顺利,于是便想着找一种更简单稳定的打包工具,这类工具其实还不少,最终经过各种考量,我们选择了 InnoSetup ,该工具是一个完全免费的Windows打包工具,涉及的功能比较全面,并且采用脚本式编辑,完美支持 Pascal 语言.本文简单描述一下如何自动下载安装 .net framework 框架 及更新卸图标的小技巧,当然本文部分内容借鉴了网上一部分的解决方案.在此整理一下已备忘同时分享给有类似需求的朋友.
  2. 放几张安装过程中自动下载文件的截图方便大家参考.
    技术分享技术分享技术分享

  3. 替换卸载程序图标
                 该工具制作的安装包,默认生成的卸载程序使用的是和安装程序一样的图标,这样感觉不够直观,可通过 "UpdateIcon.dll" 插件完成. 如下脚本所示.    
    [Files]
    Source: "UpdateIcon.dll"; Flags: dontcopy
    Source: "uninstall.ico"; Flags: dontcopy 
    
    [Icons]
    Name: "{group}\卸载"; Filename: "{uninstallexe}"
    
    [Code]
    function UpdateIcon(const hWnd: Integer; const exeFileName, exeIcon, IcoFileName: String; wlangID: DWORD): Boolean; 
    external UpdateIcon@files:UpdateIcon.dll stdcall;
    
    //替换卸载图标
    function UpdateUninstIcon(const IcoFileName: String): Boolean; 
    begin  
        Result:= UpdateIcon(MainForm.Handle, ‘‘, ‘‘, IcoFileName, 0);
    end;
    
    //安装步骤进行开始替换卸载图标
    procedure CurStepChanged(CurStep: TSetupStep); 
    var
        sIcon: String;
    begin
        if CurStep=ssInstall then
            begin  
                sIcon:= ExpandConstant({tmp}\uninstall.ico); //定义卸载图标             
                ExtractTemporaryFile(ExtractFileName(sIcon)); //释放卸载图标
                UpdateUninstIcon(sIcon);//替换卸载图标 
            end;
    end;
  4. 自动下载.net framework 组件并安装
           可通过 “isxdl.dll” 扩展实现,动态从网络上添加一个待下载的文件,并在下载完之后自动运行.见如下示例.
    [Code]
    var 
        dotNetDownloadNeeded: boolean;
        dotNetLocalPath:string;
      
    procedure isxdl_AddFile(URL, Filename: PAnsiChar);
    external isxdl_AddFile@files:isxdl.dll stdcall;
    function isxdl_DownloadFiles(hWnd: Integer): Integer;
    external isxdl_DownloadFiles@files:isxdl.dll stdcall;
    function isxdl_SetOption(Option, Value: PAnsiChar): Integer;
    external isxdl_SetOption@files:isxdl.dll stdcall;
    
    //检测是否存在特定版本的.net framework
    function IsDotNetDetected(version: string; service:cardinal): boolean;
    // Indicates whether the specified version and service pack of the .NET Framework is installed.
    //
    // version -- Specify one of these strings for the required .NET Framework version:
    //    v1.1.4322     .NET Framework 1.1
    //    v2.0.50727    .NET Framework 2.0
    //    v3.0          .NET Framework 3.0
    //    v3.5          .NET Framework 3.5
    //    v4\Client     .NET Framework 4.0 Client Profile
    //    v4\Full       .NET Framework 4.0 Full Installation
    //    v4.5          .NET Framework 4.5
    //
    // service -- Specify any non-negative integer for the required service pack level:
    //    0               No service packs required
    //    1, 2, etc.      Service pack 1, 2, etc. required
    var
        key: string;
        install, release, serviceCount: cardinal;
        check45, success: boolean;
    begin
        // .NET 4.5 installs as update to .NET 4.0 Full
        if version = v4.5 then begin
            version := v4\Full;
            check45 := true;
        end else
            check45 := false;
    
        // installation key group for all .NET versions
        key := SOFTWARE\Microsoft\NET Framework Setup\NDP\ + version;
       
        // .NET 3.0 uses value InstallSuccess in subkey Setup
        if Pos(v3.0, version) = 1 then begin
            success := RegQueryDWordValue(HKLM, key + \Setup, InstallSuccess, install);
        end else begin
            success := RegQueryDWordValue(HKLM, key, Install, install);
        end;
    
        // .NET 4.0/4.5 uses value Servicing instead of SP
        if Pos(v4, version) = 1 then begin
            success := success and RegQueryDWordValue(HKLM, key, Servicing, serviceCount);
        end else begin
            success := success and RegQueryDWordValue(HKLM, key, SP, serviceCount);
        end;
    
        // .NET 4.5 uses additional value Release
        if check45 then begin
            success := success and RegQueryDWordValue(HKLM, key, Release, release);
            success := success and (release >= 378389);
        end;
    
        result := success and (install = 1) and (serviceCount >= service);
    end;
    
    //准备安装.net framework需要的条件(本地还是联网)
    function PreInstallDotNet(dotNetName:string;dotNetDownloadUrl:string):boolean;
    begin
        if (not IsAdminLoggedOn()) then begin
          MsgBox(您电脑安装 Microsoft .NET Framework 需要管理员权限, mbInformation, MB_OK);
          Result := false;
        end else begin
            dotNetLocalPath := ExpandConstant({src}) + \+dotNetName;
            if not FileExists(dotNetLocalPath)  then begin
                dotNetLocalPath := ExpandConstant({tmp}) + \+dotNetName; 
                if not FileExists(dotNetLocalPath)  then begin
                    isxdl_AddFile(dotNetDownloadUrl, dotNetLocalPath);
                    dotNetDownloadNeeded := true;
                end;
            end;
            
            SetIniString(install, dotnetRedist, dotNetLocalPath, ExpandConstant({tmp}\dep.ini));
        end;
        
    end;
    
    //执行安装.net framework
    function DoInstallDotNet():boolean;
    var
      hWnd: Integer;
      ResultCode: Integer;
    begin
        result := true;
        hWnd := StrToInt(ExpandConstant({wizardhwnd}));
    
        // don’t try to init isxdl if it’s not needed because it will error on < ie 3
        if dotNetDownloadNeeded then begin
          isxdl_SetOption(label, 正在下载 Microsoft .NET Framework);
          isxdl_SetOption(des-c-r-i-p-tion, 您还未安装Microsoft .NET Framework. 请您耐心等待几分钟,下载完成后会安装到您的的计算机中。);
          if isxdl_DownloadFiles(hWnd) = 0 then result := false;
        end;
        
        if result = true  then begin
          if Exec(ExpandConstant(dotNetLocalPath), /qb, ‘‘, SW_SHOW, ewWaitUntilTerminated, ResultCode) then begin
             // handle success if necessary; ResultCode contains the exit code
             if not (ResultCode = 0) then begin
               result := false;
             end;
          end else begin
             // handle failure if necessary; ResultCode contains the error code
             result := false;
          end;
        end;
        
    end;
    
    //检测是否安装了等于大于指定版本的.net framework
    function IsIncludeFramework(version: string): boolean;
    var
        isInclued:boolean;     
    begin    
        
        //最高版本的
        if IsDotNetDetected(v4.5,0) then begin
            isInclued := true;         
        end else if version = v4.5 then begin
            PreInstallDotNet(dotNetFx45_Full_setup.exe,http://download.microsoft.com/download/B/A/4/BA4A7E71-2906-4B2D-A0E1-80CF16844F5F/dotNetFx45_Full_setup.exe);
        end else if IsDotNetDetected(v4\Full,0) then begin
            isInclued := true;
        end else if version = v4\Full then begin
            PreInstallDotNet(dotNetFx40_Full_x86_x64.exe,http://download.microsoft.com/download/9/5/A/95A9616B-7A37-4AF6-BC36-D6EA96C8DAAE/dotNetFx40_Full_x86_x64.exe);
        end else if IsDotNetDetected(v4\Client,0) then begin
            isInclued := true;     
        end else if version = v4\Client then begin
             PreInstallDotNet(dotNetFx40_Client_x86_x64.exe,http://download.microsoft.com/download/5/6/2/562A10F9-C9F4-4313-A044-9C94E0A8FAC8/dotNetFx40_Client_x86_x64.exe);
        end else if IsDotNetDetected(v3.5,0) then begin
            isInclued := true;     
        end else if Pos(v3.5,version) = 1 then begin
             PreInstallDotNet(dotNetFx35setup.exe,http://download.microsoft.com/download/7/0/3/703455ee-a747-4cc8-bd3e-98a615c3aedb/dotNetFx35setup.exe);
        end else if IsDotNetDetected(v3.0,0) then begin
            isInclued := true;     
        end else if Pos(v3.0,version) = 1 then begin
             PreInstallDotNet(dotNetFx35setup.exe,http://download.microsoft.com/download/7/0/3/703455ee-a747-4cc8-bd3e-98a615c3aedb/dotNetFx35setup.exe);
        end else if IsDotNetDetected(v2.0.50727,0) then begin
            isInclued := true;     
        end else if Pos(v2,version) = 1 then begin
            PreInstallDotNet(dotnetfx.exe,http://download.microsoft.com/download/5/6/7/567758a3-759e-473e-bf8f-52154438565a/dotnetfx.exe);
        end else if IsDotNetDetected(v1.1.4322,0) then begin
            isInclued:= true;
        end else if Pos(v1,version)=1 then begin
            PreInstallDotNet(dotNetFx35setup.exe,http://download.microsoft.com/download/7/0/3/703455ee-a747-4cc8-bd3e-98a615c3aedb/dotNetFx35setup.exe);
        end;
        
        result := isInclued;
    end;
    
    //点击下一步
    function NextButtonClick(CurPage: Integer): Boolean;
    var
       dotNetVersion:String;
    begin
        Result := true;
      if (CurPage = wpReady) then begin 
        dotNetVersion := v4\Full;   
        if not IsIncludeFramework(dotNetVersion) then begin
          if not DoInstallDotNet() then begin
             MsgBox(当前操作需要安装.NET Framework  + dotNetVersion + 或以上版本。#13#13
              在尝试自动安装期间,似乎出现一些小问题(或用户取消了安装),#13
              请重试尝试安装。, mbInformation, MB_OK);
            result:= false;
          end;
        end;
      end;   
    end;
  5. 关于通用
          可以将以上两个小功能点分别保存为独立的innosetup 脚本文件(“.iss”),然后在主安装包脚本中引入这两个文件.如下所示.
    #include "dotnetSetup.iss"
    #include "updateuninstallIco.iss"
  6. 后记
    a).“Update.dll” 及 “isxdl.dll”如果你实在是找不到,本文提供一个下载链接,可从这里下载.
    b).  本文中部分方法及思路收集于网络,本人只是加以整理用以备忘.

Innosetup打包自动下载.net framework 动态库及替换卸载程序图标.

标签:

原文地址:http://www.cnblogs.com/xie-zhonglai/p/innosetup_auto_setup_framework_and_update_ico.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!