码迷,mamicode.com
首页 > 其他好文 > 详细

制作部署安装包:Inno Setup

时间:2016-01-13 15:56:21      阅读:738      评论:0      收藏:0      [点我收藏+]

标签:

原文:制作部署安装包:Inno Setup

前一篇尝试Office 2003 VSTO的开发、部署有提到用VS开发一个简单的VSTO程序。打包C/S程序,我首先想到的是VS里自带的Setup Project。很遗憾,VS2012及后面的版本都剔除了Setup Project,改用InstallShield Limited Edition。

Setup Project配置起来N麻烦,如:配置完成了之后,一旦修改了项目的东西然后重新生成,只有移除原来定义好的快捷方式、主输出,然后重新设置才能应用修改。而ISLE,对于一些简单的打包,基本上都是满足了的,而且整个操作过程都有界面,动动鼠标就行了;里面有部分功能是可以写代码定制的,不过要授权收费!这是我个人的使用心得,安装打包用得不多,有误之处,还请多多指教。

无意中发现了Inno这个小东西(官网地址),然后深深地被它吸引了。麻雀虽小,五脏俱全,可以完全免费使用,最主要的是它允许自己使用Pascal语言编写定制脚本。

网上挺多资料的,但很多都是雷同,且测试时部分有bug。下面贴上自己的一个代码栗子,参考了网上的几篇文章,然后修改整理的。

需要注意的:

1、打包指定文件(夹)时,该文件(夹)必须存在文件,不然编译时提示错误。路径(可使用相对路径)CheckOfficeConsole\DotNetFramework必须要存在文件,可以是任何类型的。

Source: "CheckOfficeConsole\DotNetFramework\*"; DestDir: "{tmp}"; Flags: ignoreversion 

2、检测.net framework,如果不存在则从指定网址下载安装包时,需要用到isxdl.dll。这个dll需要下载并安装ISTool

3、.net framework 的下载地址,我找到了除v3.0、v1版本以外的安装包地址,测试时都可用。未来微软网站也许会对这些资源包地址更新,所以不保证一直可用。

4、安装过程中,可通过Inno的函数读取指定目录的.ini文件,并获得文件里的参数值。这个太赞了有木有!一来可以减少在Inno脚本里硬编码,二来可以在安装过程中初始化相关数据。如:Output目录有一个setup.ini文件,里面的内容为:

[Custom]
dotNetVersion =  v4.5

Inno的读取代码:

function GetCustomConfig(key:string):string;
var 
  myValue:string;
begin
  myValue:=ExpandConstant({ini:{src}\Setup.ini,Custom,+key+})
  result := myValue;
end;

//使用
//.....
 GetCustomConfig(dotNetVersion);
//.....

 

完整版:

 

; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
; Ivan 2015-1-30

#define MyAppName "VSTO Excel by Ivan"
#define MyAppVersion "1.0"
#define MyAppPublisher "My Company, Inc."
#define MyAppURL "http://www.IvanBy.com/"
#define MyAppExeName "CheckOfficeConsole.exe"

[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{6DFC5AE2-4844-4440-A6B3-284E15A14AEA}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
OutputBaseFilename=setup
Compression=lzma
SolidCompression=yes

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked

[Files]
Source: C:\Program Files (x86)\ISTool\isxdl.dll; Flags: dontcopy;
Source: "CheckOfficeConsole\bin\Release\CheckOfficeConsole.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "CheckOfficeConsole\DotNetFramework\*"; DestDir: "{tmp}"; Flags: ignoreversion 
Source: "Excel2010Setup\Excel2010Setup\Express\DVD-5\DiskImages\*"; DestDir: "{app}\2010"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Dont use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}" 

;更改显示在程序中显示的消息文本
[Messages]
BeveledLabel=Ivan Code

[Run]
;Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, ‘&‘, ‘&&‘)}}"; Flags: nowait postinstall skipifsilent
Filename: "{app}\{#MyAppExeName}"

[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;

//取得自定义的配置
//     Setup.ini
//     [Custom]
//   dotNetVersion =  v4.5
function GetCustomConfig(key:string):string;
var 
  myValue:string;
begin
  myValue:=ExpandConstant({ini:{src}\Setup.ini,Custom,+key+})
  result := myValue;
end;

function InitializeSetup(): Boolean;
begin
    //do something 

  result:= true;
end;

function NextButtonClick(CurPage: Integer): Boolean;
var 
  dotNetVersion:string;
begin
    Result := true;

  if (CurPage = wpReady) then begin

    dotNetVersion := GetCustomConfig(dotNetVersion);
    if Length(dotNetVersion) = 0 then begin
       dotNetVersion := v4.0;
    end else if not (Pos(v,dotNetVersion) = 1) then begin
        dotNetVersion := v+dotNetVersion;
    end;
     
    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;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
  ErrorCode: Integer;
begin
  case CurUninstallStep of
    usUninstall:
      begin        
        // 正在卸载
      end;
    usPostUninstall:
      begin
        //卸载完成       
        ShellExec(open, http://www.IvanBy.com, ‘‘, ‘‘, SW_SHOW, ewNoWait, ErrorCode)

      end;
  end;
end;

 

制作部署安装包:Inno Setup

标签:

原文地址:http://www.cnblogs.com/lonelyxmas/p/5127331.html

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