inno setup

推荐使用Inno Setup Dependency Installer安装需要的依赖
github

检测.net framework

  1. 自定义安装步骤
    通过重写function InitializeSetup(): Boolean; 来实现自定义安装,
    需要注意,此方法返回值如果为false,则将终止后续安装流程

  2. 返回值
    返回值约定为Result

  3. 自动安装
    在[Run]配置节点中加入需要安装的配置
    例:

Filename: {tmp}\vc_redist_x86.exe; Parameters: "/q:a /c:""install /l /q"""; WorkingDir: {tmp}; Flags: skipifdoesntexist; StatusMsg: "Installing Microsoft Visual C++ Runtime ..."
  1. 自定义代码
    在[Code]配置中添加自定义方法

  2. 检测注册表是否存在

重要

根据 24K纯开源 的文章得知
64位系统需要将原本的HKLM改成HKLM64

//检测vs++2015
Result:=RegValueExists(HKLM64, 'SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x86', 'Version');  
//检测.netframeword4.5.2
Result:=RegValueExists(HKLM64, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full', 'Version'); 

.net frameword 4.5.2
推荐阅读

//检测.net framework 4.5.2
function IsDotNET40Detected():boolean;
var key:string;
var releaseVersion:cardinal;
begin
  key:='SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full';
  if (IsWin64()) then begin
    Result := RegQueryDWordValue(HKLM64, key, 'Release', releaseVersion);
    
    end 
  else
    begin
      Result:= RegQueryDWordValue(HKLM, key, 'Release', releaseVersion);
    end; 
  //MsgBox( Format('%u',[releaseVersion]), mbConfirmation, MB_YESNO);
  Result :=  (releaseVersion >= 379893);  //4.5.2
end;
  1. 定义退出安装程序的脚本
// ss
procedure ExitProcess(exitCode:integer);
  external 'ExitProcess@kernel32.dll stdcall';
  1. 将资源释放到临时目录并调用
    首先在[Files]中定义需要的资源
    例:
Source: "C:\Users\ives\Desktop\Output\vc_redist_x86.exe"; DestDir: "{tmp}"; Flags: ignoreversion;

添加检测所需要的脚本 ,在[code]中定义

function IsVC2015():boolean;
begin
  if (IsWin64()) then begin
    Result:=RegValueExists(HKLM64, 'SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x86', 'Version'); 
    end
  else
  begin
    Result:=RegValueExists(HKLM, 'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86', 'Version');
  end 
end;  

最后在上面提到的InitializeSetup中调用

function InitializeSetup(): Boolean; 
var Path:string; 
    ResultCode: Integer; 
begin 
    //检测vc++2015 
    if (IsVC2015()=false) then
    begin
        if MsgBox('正在安装必备组件vc_redist_x86,请稍后……', mbConfirmation, MB_YESNO) = idYes then
        begin
        ExtractTemporaryFile('vc_redist_x86.exe'); 
        Exec(ExpandConstant('{tmp}\vc_redist_x86.exe'), '', '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode);
        end; 
    end;
    Result:=true
end;

标题

[Messages]
SetupWindowTitle=xxxx客户端

桌面快捷方式

[Icons]
Name: "{userdesktop}\{#MyAppName}";Filename: "{app}\{#MyAppExeName}"; WorkingDir: "{app}"

控制面板图标

[Setup]
UninstallDisplayIcon=F:\20-Workspace\HDTools\HDTools.Win\appicon.ico
[Icons]
Name: "{group}\卸载 {#MyAppName}"; Filename: "{uninstallexe}"

//在注册表中插入DisplayIcon项,指定安装卸载页面的程序图标;
function SetUninstallIcon(iconPath:string): Boolean;
var
  InstalledVersion,SubKeyName: String;
begin
if (IsWin64()) then begin
SubKeyName :=  'Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{使用appid替换}_is1';
    RegWriteStringValue(HKLM64,SubKeyName,'DisplayIcon',iconPath);
  end else begin
SubKeyName :=  'Software\Microsoft\Windows\CurrentVersion\Uninstall\{使用appid替换}_is1';
    RegWriteStringValue(HKLM,SubKeyName,'DisplayIcon',iconPath);
  end;
end;


procedure CurPageChanged(CurPageID: Integer);
begin
  if CurPageID = wpFinished then
  begin
    SetUninstallIcon(ExpandConstant('{app}\appicon.ico'));
  end;
end;

卸载自动关闭程序

//检测程序是否正在运行
function IsAppRunning(const FileName: string): Boolean;
var
  FWMIService: Variant;
  FSWbemLocator: Variant;
  FWbemObjectSet: Variant;
begin
  Result := false;
  FSWbemLocator := CreateOleObject('WBEMScripting.SWBEMLocator');
  FWMIService := FSWbemLocator.ConnectServer('', 'root\CIMV2', '', '');
  FWbemObjectSet := FWMIService.ExecQuery(Format('SELECT Name FROM Win32_Process Where Name="%s"',[FileName]));
  Result := (FWbemObjectSet.Count > 0);
  FWbemObjectSet := Unassigned;
  FWMIService := Unassigned;
  FSWbemLocator := Unassigned;
end;
//关闭进程
//调用cmd关闭程序
function EndProcess():Boolean;
var appWnd: HWND;
var ErrorCode: Integer;
begin
  ShellExec('open', ExpandConstant('{cmd}'), '/c taskkill /f /t /im '+'{#MyAppExeName}', '', SW_HIDE, ewNoWait, ErrorCode);
end;
//卸载
function InitializeUninstall(): Boolean;
  begin
    Result:= true;
    if  IsAppRunning('{#MyAppExeName}') then
    begin
      if MsgBox('卸载程序检测到 {#MyAppName} 正在运行!'#13''#13'单击“是”按钮关闭程序并继续卸载;'#13''#13'单击“否”按钮退出卸载!', mbConfirmation, MB_YESNO) = IDYES then
      begin
        EndProcess();
        Result:= true;
      end
      else
        Result:= false;
    end;
  end;

命令行编译

"E:\Inno Setup 5\iscc.exe" /cc "Pack.iss"

//用户选择的安装目录,只能在安装完成后使用
path := ExpandConstant('{app}');

//安装文件所在目录
path := ExpandConstant('{src}');

//安装程序完整路径
path := ExpandConstant('{srcexe}');

检测方法来自检测.net版本

posted @ 2019-12-27 20:32  Hey,Coder!  阅读(539)  评论(0编辑  收藏  举报