[Other] Inno Setup 使用心德-一个完整的项目 包括.NET组建捆绑 去空格等

最近安排我弄程序的打包工作,然后叫我接触Inno Setup打包软件。

说实话,第一次弄,什么都不懂,就不断Baidu,当然很多都没有,只有看文档了!


前面打包程序部分都还好,都完成了,但是后来说要捆绑组建,这个可把我难住了,最开始我是把组建添加进去,然后安装程序后启动组建安装,这样的缺陷多的数不清。

而后,把组建捆绑到tmp中安装,但是也是存在问题,因为用户要是在安装过程中取消了,那自己的程序也没法跑了!

而后又加入了组建的安装检测,在最后一步的时候检测是否正确安装(通过扫描注册表),假如成功则完成,假如不成功则启动程序删除!

这样基本解决了,但是感觉好麻烦,好累赘!


而后又想到了,为什么不在开始就检测呢,如果没有则安装,安装失败则退出整个程序安装!

而后就开始了我的一点点的改动,完成。

最后代码如下:

[Files]
Source: "NET2.exe"; DestDir: "{tmp}"; Flags: ignoreversion

[code]
function NeedInstallDotNet(): Boolean;
var
    success: boolean;
    install: cardinal;
begin
    success := RegQueryDWordValue(HKLM, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v2.0.50727', 'Install', install);
    Result := not(success and (install = 1));
end;
   
function InitializeSetup(): Boolean;
var ResultCode: Integer; 
begin
  Result :=true;
  if (NeedInstallDotNet) then
  begin
    MsgBox('您的电脑需要先安装Microsoft .NET Framework 2.0 SP2组建.' + #13 + '请等待组建加载完成并完成组建安装后再进行程序的安装.',mbError, MB_OK);
    ExtractTemporaryFile('NET2.exe'); 
    Exec(ExpandConstant('{tmp}\NET2.exe'), '', '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode); 
  end;
  if (NeedInstallDotNet) then
  begin
    MsgBox('您的组建安装失败,程序将退出安装.',mbError, MB_OK);
    Result :=false; //安装程序退出
  end else begin
    Result :=true;  //安装程序继续
  end;
end;

完整的项目:

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


#define MyCompany "Broadinter"
#define MyAppName "Prober"
#define MyAppVersion "3.0.0"
#define MyAppPublisher "Broadinter, Inc."
#define MyAppURL "http://www.broadinter.com/"
#define MyAppId "{55E402DD-B073-4CDF-8AA7-D52FDC5B348E}"
#define MyAppServeKiwi "kiwi.exe"
#define MyAppServeWatchdog "kiwi_watchdog.exe"
#define MyFormationDotNetName "NetFx20SP2_x86.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={{#MyAppId}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
AppCopyright=Copyright (C) 2013 {#MyAppPublisher}
DefaultDirName={pf}\{#MyCompany}
DefaultGroupName={#MyCompany}
AllowNoIcons=yes
LicenseFile=eula.rtf
OutputDir=..\Setup
OutputBaseFilename=setup
SetupIconFile=setup.ico
Compression=lzma
SolidCompression=yes
PrivilegesRequired=admin
WizardImageFile=Image.bmp
WizardSmallImageFile=SmallImage.bmp 


[Languages]
Name: "chinesesimplified"; MessagesFile: "ChineseSimplified.isl"




[Files]
Source: "..\Source\Prober\*"; DestDir: "{app}\Prober"; Flags: ignoreversion recursesubdirs createallsubdirs;


Source: "..\Source\Selections\network.conf"; DestDir: "{app}\Prober"; Flags: ignoreversion onlyifdoesntexist uninsneveruninstall; Check: NeedInstallNetworkConfig;
Source: "..\Source\Selections\probe.conf"; DestDir: "{app}\Prober"; Flags: ignoreversion onlyifdoesntexist uninsneveruninstall; Check: NeedInstallProbeConfig; AfterInstall: MyAfterInstall;


Source: "..\Source\Prober_Update\*"; DestDir: "{app}\Prober_Update"; Flags: ignoreversion recursesubdirs createallsubdirs; 
Source: "..\Source\Prober_Watchdog\*"; DestDir: "{app}\Prober_Watchdog"; Flags: ignoreversion recursesubdirs createallsubdirs;
     
Source: "..\Source\Selections\NetFx20SP2_x86.exe"; DestDir: "{tmp}"; Flags: ignoreversion; Check: NeedInstallDotNet;
Source: "..\Source\Selections\IE8-WindowsServer2003-x86-CHS.exe"; DestDir: "{tmp}"; Flags: ignoreversion; Check: NeedInstallIE;
Source: "..\Source\Selections\Flashplayer11_7r700_202_winax.exe"; DestDir: "{tmp}"; Flags: ignoreversion; Check: NeedInstallFlash;




[Run]
Filename: "{app}\Prober\{#MyAppServeKiwi}"; Parameters: "-i Prober"; WorkingDir: "{app}\Prober"; StatusMsg: "正在安装Prober服务..."; BeforeInstall: BeforeInstallDelete;
Filename: "{app}\Prober\{#MyAppServeKiwi}"; Parameters: "-s Prober"; WorkingDir: "{app}\Prober"; StatusMsg: "正在开启Prober服务..."
Filename: "{app}\Prober_Watchdog\{#MyAppServeWatchdog}"; Parameters: "-i Prober_Watchdog"; WorkingDir: "{app}\Prober_Watchdog"; StatusMsg: "正在安装Prober_Watchdog服务..."
Filename: "{app}\Prober_Watchdog\{#MyAppServeWatchdog}"; Parameters: "-s Prober_Watchdog"; WorkingDir: "{app}\Prober_Watchdog"; StatusMsg: "正在开启Prober_Watchdog服务..."
Filename: "{tmp}\IE8-WindowsServer2003-x86-CHS.exe"; Parameters: " "; WorkingDir: "{tmp}"; StatusMsg: "正在安装IE8..."; Check: NeedInstallIE
Filename: "{tmp}\Flashplayer11_7r700_202_winax.exe"; Parameters: "/install"; WorkingDir: "{tmp}"; StatusMsg: "正在安装Flashplayer11..."; Check: NeedInstallFlash




[UninstallRun]
Filename: "{app}\Prober\{#MyAppServeKiwi}"; Parameters: "-p Prober"; WorkingDir: "{app}\Prober"; StatusMsg: "正在停止Prober服务"
Filename: "{app}\Prober\{#MyAppServeKiwi}"; Parameters: "-u Prober"; WorkingDir: "{app}\Prober"; StatusMsg: "正在卸载Prober服务"
Filename: "{app}\Prober_Watchdog\{#MyAppServeWatchdog}"; Parameters: "-p Prober_Watchdog"; WorkingDir: "{app}\Prober_Watchdog"; StatusMsg: "正在停止Prober_Watchdog服务"
Filename: "{app}\Prober_Watchdog\{#MyAppServeWatchdog}"; Parameters: "-u Prober_Watchdog"; WorkingDir: "{app}\Prober_Watchdog"; StatusMsg: "正在卸载Prober_Watchdog服务"




[Code]
var
  //探针配置页面
  UserPage: TInputQueryWizardPage;
  //是否运行了卸载
  IsUninstallRuned: Boolean;
  //是否保存配置文件
  IsSaveConfig: Boolean;
  //配置属性
  ConfigBool: Boolean;    
  //CheckBox
  CB_IE: TNewCheckBox;
  CB_Flash: TNewCheckBox;






{--检检测是否已经安装软件--}
function CheckHaveApp(): Boolean;
var
  ResultStr: String;
  ResultCode: Integer;
begin
  if RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{#MyAppId}_is1', 'UninstallString', ResultStr) then begin
     if (MsgBox('检测到你已安装本软件,是否卸载?', mbConfirmation, MB_YESNO) = IDYES) then begin
        ResultStr := RemoveQuotes(ResultStr);
        Exec(ResultStr, '/silent', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
        //二次检测是否卸载
        if RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{#MyAppId}_is1', 'UninstallString', ResultStr) then begin
          result:=false;
        end else begin
          result:=true;
        end;  
     end;
  end else begin
    result:=true;
  end;
end;


{--检测是否需要安装NET组建--}
function NeedInstallDotNet(): Boolean;
var
    success: boolean;
    install: cardinal;
begin
    success := RegQueryDWordValue(HKLM, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v2.0.50727', 'Install', install);
    Result := not(success and (install = 1));
end;


{--检测是否需要IE组建--}
function NeedInstallIE(): Boolean;
begin
    Result := CB_IE.Checked;
end;


{--检测是否需要Flash组建--}
function NeedInstallFlash(): Boolean;
begin
    Result := CB_Flash.Checked;
end;


{--检测是否需要安装Network配置文件--}
function NeedInstallNetworkConfig(): Boolean;
begin
    if FileExists(ExpandConstant('{app}') + '\Prober\network.conf') then begin
      Result := False;
    end else begin
      Result := True; 
    end;
end;


{--检测是否需要安装Probe配置文件--}
function NeedInstallProbeConfig(): Boolean;
begin
    if FileExists(ExpandConstant('{app}') + '\Prober\probe.conf') then begin
      Result := False;
    end else begin
      Result := True; 
    end;
end;


{--检检测是否已经IE8--}
function CheckHaveIE8(): Boolean;
var
  ResultStr: String;
  ResultCode: Integer;
begin
  RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Internet Explorer', 'Version', ResultStr);
  if ResultStr = '8.0.6001.18702' then begin
     result := False;
  end else begin
    result := True;
  end;
end;


{--启动服务前删除多余数据--}
procedure BeforeInstallDelete();
var
  whileLen: Integer;
begin
    whileLen := 0;
    while  whileLen <> 5 do
    begin
      if(FileExists(ExpandConstant('{app}') + '\Prober\probe.db')) then begin
       DeleteFile(ExpandConstant('{app}'+ '\Prober\probe.db'));
       whileLen:= whileLen+1;
      end else begin
       whileLen := 5;
      end;
    end;
    if(FileExists(ExpandConstant('{app}') + '\Prober\probe.db')) then begin
      MsgBox('文件“\Prober\probe.db”清理失败!',mbError, MB_OK);
    end;
    DelTree(ExpandConstant('{app}'+ '\Prober\log'), True, True, True);
    DelTree(ExpandConstant('{app}'+ '\Prober\mq_ext'), True, True, True);
end;




{--开始前检测--}
function InitializeSetup(): boolean;
var
  ResultStr: String;
  ResultCode: Integer;
  whileLen: Integer;
begin
  CheckHaveIE8;




  //是否已经安装本软件
  whileLen := 0;
  while  whileLen <> 3 do
  begin
    if(CheckHaveApp) then begin
     result:=true;
     whileLen := 3;
    end else begin
       result:=false;
       whileLen:= whileLen+1;
    end;
  end;
  //是否需要组建
  if(result) then
    begin
      if (NeedInstallDotNet) then
        begin
          MsgBox('您的电脑需要先安装Microsoft .NET Framework 2.0 SP2组建.' + #13 + '请等待组建加载完成并完成组建安装后再进行程序的安装.',mbError, MB_OK);
          ExtractTemporaryFile('{#MyFormationDotNetName}'); 
          Exec(ExpandConstant('{tmp}\{#MyFormationDotNetName}'), '', '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode); 
        end;
      if (NeedInstallDotNet) then
        begin
          MsgBox('您的组建安装失败,程序将退出安装.',mbError, MB_OK);
          Result :=false; //安装程序退出
        end 
      else 
        begin
          Result :=true;  //安装程序继续
        end;
    end;
end;


{-- 创建插件页面 --}
procedure CreateTheWizardPages;
var
  Page: TWizardPage;
  Button, FormButton: TNewButton;
  Panel: TPanel;
  HaveIE8Bool: Boolean;
begin
  Page := CreateCustomPage(wpWelcome, '插件安装', '请选择您需要安装的插件');


  HaveIE8Bool := CheckHaveIE8;


  CB_IE := TNewCheckBox.Create(Page);
  CB_IE.Top := ScaleY(35);
  CB_IE.Left :=  ScaleY(40);
  CB_IE.Width := Page.SurfaceWidth div 2;
  CB_IE.Height := ScaleY(17);
  CB_IE.Caption := '安装IE8插件';
  CB_IE.Checked := HaveIE8Bool;
  CB_IE.Enabled := HaveIE8Bool;
  CB_IE.Parent := Page.Surface;


  CB_Flash := TNewCheckBox.Create(Page);
  CB_Flash.Top := CB_IE.Top + CB_IE.Height + ScaleY(8);
  CB_Flash.Left :=  ScaleY(40);
  CB_Flash.Width := Page.SurfaceWidth div 2;
  CB_Flash.Height := ScaleY(17);
  CB_Flash.Caption := '安装Flashplayer11插件';
  CB_Flash.Checked := True;
  CB_Flash.Parent := Page.Surface;


end;


{--- 页面初始化 --}
procedure InitializeWizard;
begin
  {-- 创建插件页 --}
  CreateTheWizardPages;
  {-- 创建配置页 --}
  UserPage := CreateInputQueryPage(wpReady,
    '配置', '请进行如下配置,然后进入下一步',
    '请确保填写正确的信息');
  UserPage.Add('服务端IP', False);
  UserPage.Add('监测点ID', False);
  ConfigBool := True;
end;




{-- 下一步按钮事件响应 --}
function NextButtonClick(CurPageID: Integer): Boolean;
begin
  Result := True;
  if CurPageID = UserPage.ID then begin
    if UserPage.Values[0] = '' then begin
      MsgBox('请填写服务端IP', mbError, MB_OK);
      Result := False;
    end else
      if UserPage.Values[1] = '' then begin
      MsgBox('请填写监测点ID', mbError, MB_OK);
      Result := False;
    end;
  end;
  if CurPageID = wpReady then begin
    if FileExists(ExpandConstant('{app}') + '\Prober\network.conf') and FileExists(ExpandConstant('{app}') + '\Prober\probe.conf') then begin
      ConfigBool := False;
    end;
  end;
end;




{-- 页面跳转时 实现是否允许跳转 --}
function ShouldSkipPage(PageID: Integer): Boolean;
begin
  Result := False;
  if PageID = UserPage.ID then begin
    if ConfigBool = False then begin
      Result := True;
    end;
   end;
end;


{-- 去字符串空格 --}
function StringTrim(a: string): string;
begin
  Result := a;
  while pos(' ',Result)<>0 do
    delete(Result,pos(' ',Result),1);
end;




{-- 方法: 实现对配置文件拷贝后进行处理 --}
procedure MyAfterInstall();
var
  XMLDoc0: Variant;
  XMLDoc1: Variant; 
  s: string;  
begin
  if ConfigBool then begin
    try
      XMLDoc0 := CreateOleObject('MSXML2.DOMDocument');
      XMLDoc0.async := False;
      XMLDoc0.resolveExternals := False;
      XMLDoc0.load(ExpandConstant('{app}') + '\Prober\network.conf');
      XMLDoc0.selectSingleNode('//channel[@name=''balance'']').attributes.getNamedItem('peer_addr').text := StringTrim(UserPage.Values[0]);
      XMLDoc0.save(ExpandConstant('{app}') + '\Prober\network.conf');
    except
      RaiseException('未能正确配置服务端IP,请检查network.conf');
    end;
    try
      XMLDoc1 := CreateOleObject('MSXML2.DOMDocument');
      XMLDoc1.async := False;
      XMLDoc1.resolveExternals := False;
      XMLDoc1.load(ExpandConstant('{app}') + '\Prober\probe.conf');
      XMLDoc1.selectSingleNode('//mid').text := StringTrim(UserPage.Values[1]);
      XMLDoc1.save(ExpandConstant('{app}') + '\Prober\probe.conf');
    except
      RaiseException('未能正确配置监测点ID,请检查probe.conf');
    end;
   end;
end;


{-- 卸载程序时对用户是否保留插件 --}
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
  XMLDoc0: Variant;
  XMLDoc1: Variant; 
begin
  //进入卸载后改变状态
  IsUninstallRuned := true;
  if CurUninstallStep = usUninstall then begin
    if MsgBox('是否需要保留配置文件?', mbConfirmation, MB_YESNO) = IDYES then begin
      IsSaveConfig := True;          
      try
        XMLDoc0 := CreateOleObject('MSXML2.DOMDocument');
        XMLDoc0.async := False;
        XMLDoc0.resolveExternals := False;
        XMLDoc0.load(ExpandConstant('{app}') + '\Prober\network.conf');
        XMLDoc0.save(ExpandConstant('{app}') + '\Prober\network_tmp.conf');


        XMLDoc1 := CreateOleObject('MSXML2.DOMDocument');
        XMLDoc1.async := False;
        XMLDoc1.resolveExternals := False;
        XMLDoc1.load(ExpandConstant('{app}') + '\Prober\probe.conf');
        XMLDoc1.save(ExpandConstant('{app}') + '\Prober\probe_tmp.conf');
      except
      end;
    end else begin
      IsSaveConfig := False;
    end;     
  end;
end;




{-- 删除后操作 对文件进行一定的处理 --}
procedure DeinitializeUninstall();
var
  XMLDoc0: Variant;
  XMLDoc1: Variant;
begin
  //首先判断是否进入了卸载
  if IsUninstallRuned then begin
    if IsSaveConfig then begin
      try          
        DeleteFile(ExpandConstant('{app}'+ '\Prober\probe.db'));
        DelTree(ExpandConstant('{app}'+ '\Prober\log'), True, True, True);
        DelTree(ExpandConstant('{app}'+ '\Prober\mq_ext'), True, True, True);
        DelTree(ExpandConstant('{app}'+ '\Prober_Update'), True, True, True);
        DelTree(ExpandConstant('{app}'+ '\Prober_Watchdog'), True, True, True);
      except
        MsgBox('清空程序日志及数据库缓存失败!', mbInformation, MB_OK);
      end;
      
      try
        XMLDoc0 := CreateOleObject('MSXML2.DOMDocument');
        XMLDoc0.async := False;
        XMLDoc0.resolveExternals := False;
        XMLDoc0.load(ExpandConstant('{app}') + '\Prober\network_tmp.conf');
        XMLDoc0.save(ExpandConstant('{app}') + '\Prober\network.conf');


        XMLDoc1 := CreateOleObject('MSXML2.DOMDocument');
        XMLDoc1.async := False;
        XMLDoc1.resolveExternals := False;
        XMLDoc1.load(ExpandConstant('{app}') + '\Prober\probe_tmp.conf');
        XMLDoc1.save(ExpandConstant('{app}') + '\Prober\probe.conf');
      except
        MsgBox('保留配置文件失败!', mbInformation, MB_OK);
      end;


      try          
        DeleteFile(ExpandConstant('{app}'+ '\Prober\network_tmp.conf'));
        DeleteFile(ExpandConstant('{app}'+ '\Prober\probe_tmp.conf'));
      except
        MsgBox('清空配置文件缓存失败!', mbInformation, MB_OK);
      end; 
       
    end else begin
        DelTree(ExpandConstant('{app}'), True, True, True);
    end;
  end;
end;


你可能感兴趣的:(pascal,去空格,setup,xml配置文件,Inno,捆绑组建)