【问题标题】:Inno Setup Trying to create a new Install DirectX Template Product for Modular InnoSetup Dependency InstallerInno Setup 尝试为模块化 InnoSetup 依赖安装程序创建新的安装 DirectX 模板产品
【发布时间】:2026-02-11 23:00:01
【问题描述】:

我正在使用模块化 Inno 设置

http://www.codeproject.com/Articles/20868/NET-Framework-1-1-2-0-3-5-Installer-for-InnoSetup#xx3672600xx

我正在修改现有的 DirectX 检测器方法

http://www.vincenzo.net/isxkb/index.php?title=DirectX_-_How_to_detect_DirectX_version

我正在尝试创建一个新产品来安装 DirectX 9

这是我目前所拥有的。

//========================================
//detectDirectX.iss
//=======================================


[CustomMessages]
directx_title=DirectX End-User Runtimes (June 2010)

en.directx_size=95.6 MB
de.directx_size=95.6 MB

[Code]
const
    directx_url = 'http://download.microsoft.com/download/8/4/A/84A35BF1-DAFE-4AE8-82AF-AD2AE20B6B14/directx_Jun2010_redist.exe';


procedure DecodeVersion( verstr: String; var verint: array of Integer );
var
  i,p: Integer; s: string;
begin
  // initialize array
  verint := [0,0,0,0];
  i := 0;
  while ( (Length(verstr) > 0) and (i < 4) ) do
  begin
    p := pos('.', verstr);
    if p > 0 then
    begin
      if p = 1 then s:= '0' else s:= Copy( verstr, 1, p - 1 );
      verint[i] := StrToInt(s);
      i := i + 1;
      verstr := Copy( verstr, p+1, Length(verstr));
    end
    else
    begin
      verint[i] := StrToInt( verstr );
      verstr := '';
    end;
  end;

end;

// This function compares version string
// return -1 if ver1 < ver2
// return  0 if ver1 = ver2
// return  1 if ver1 > ver2
function CompareVersion2( ver1, ver2: String ) : Integer;
var
  verint1, verint2: array of Integer;
  i: integer;
begin

  SetArrayLength( verint1, 4 );
  DecodeVersion( ver1, verint1 );

  SetArrayLength( verint2, 4 );
  DecodeVersion( ver2, verint2 );

  Result := 0; i := 0;
  while ( (Result = 0) and ( i < 4 ) ) do
  begin
    if verint1[i] > verint2[i] then
      Result := 1
    else
      if verint1[i] < verint2[i] then
        Result := -1
      else
        Result := 0;

    i := i + 1;
  end;

end;

// DirectX version is stored in registry as 4.majorversion.minorversion
// DirectX 8.0 is 4.8.0
// DirectX 8.1 is 4.8.1
// DirectX 9.0 is 4.9.0

function GetDirectXVersion(): String;
var
  sVersion:  String;
begin
  sVersion := '';

  RegQueryStringValue( HKLM, 'SOFTWARE\Microsoft\DirectX', 'Version', sVersion );

  Result := sVersion;
end;

procedure directX();
var ErrorCode: Integer;
begin
  // in this case program needs at least directx 9.0
  if CompareVersion2( GetDirectXVersion(), '4.9.0') < 0 then
  begin
                AddProduct('directx_Jun2010_redist.exe',
                    '/t:' + ExpandConstant('{tmp}\DirectX') + ' /q /c',
                    CustomMessage('directx_title'),
                    CustomMessage('directx_size'),
                    directx_url,
                    false, false);

          //Is there any way to wait until directx_Jun2010_redist.exe has extracted it self before calling the next line? 
         ShellExec('open', ExpandConstant('{tmp}\DirectX\DXSETUP.exe'), '/silent', '', SW_SHOW, ewWaitUntilTerminated, ErrorCode)
  end;
end;

在[RUN]下的主设置文件whatever.iss

我包含了文件。

#include "scripts\products\custom\detectDirectX.iss"

在[CODE]下的主安装文件whatever.iss

我包含了这个方法

directX();

我遇到的问题是它正在按应有的方式下载并将其放置在 Temp 文件夹中。

        AddProduct('directx_Jun2010_redist.exe',
            '/t:' + ExpandConstant('{tmp}\DirectX') + ' /q /c',
            CustomMessage('directx_title'),
            CustomMessage('directx_size'),
            directx_url,
            false, false);

因为我使用了额外的 pars

'/t:' + ExpandConstant('{tmp}\DirectX') + ' /q /c'

下载后,它会创建一个名为 DirectX 的文件夹并将所有内容提取到其中。这需要一点时间。

似乎在 directx_Jun2010_redist.exe 正在提取..

ShellExec('open', ExpandConstant('{tmp}\DirectX\DXSETUP.exe'), '/silent', '', SW_SHOW, ewWaitUntilTerminated, ErrorCode)

被提前调用并且文件 {tmp}\DirectX\DXSETUP.exe 还不存在..所以它没有被调用。

解压完成后,用户点击安装完成并删除 Temp 文件夹。

有没有办法解决这个问题,以便在 directx_Jun2010_redist.exe 提取文件后,它可以在安装程序完成之前运行 DXSETUP.exe?

【问题讨论】:

  • 您希望何时下载并执行 DirectX 设置?在哪个阶段?考虑一下,该用户可能没有连接到 Internet...
  • 1.这是一个依赖。 2. 在directx_Jun2010_redist.exe 完成提取所有需要的文件之后。如果用户没有连接到互联网,那么安装程序应该会失败,因为它自己的程序需要互联网。

标签: inno-setup pascal


【解决方案1】:

好吧,我想我终于让它正常工作了。我不得不移动一些东西。似乎有些东西在启动时被调用但实际上并没有触发它们直到稍后才被查询。考虑到这一点,我能够解决这个问题。这是代码。

在您的主 setupfile.iss 中,在 [RUN]

下添加以下内容
Filename: "{tmp}\DirectX\DXSETUP.exe"; WorkingDir: "{tmp}\DirectX"; Parameters: "/silent"; Check: checkDirectX; Flags: waituntilterminated;


#include "scripts\products\custom\detectDirectX.iss"

另外,在您的主 setupfile.iss 中,在 [Code]

下添加以下内容
directX();

这里是detectDirectX.iss的代码

[CustomMessages]
directx_title=DirectX End-User Runtimes (June 2010)

en.directx_size=95.6 MB
de.directx_size=95.6 MB

[Code]
const
    directx_url = 'http://download.microsoft.com/download/8/4/A/84A35BF1-DAFE-4AE8-82AF-AD2AE20B6B14/directx_Jun2010_redist.exe';


procedure DecodeVersion( verstr: String; var verint: array of Integer );
var
  i,p: Integer; s: string;
begin
  // initialize array
  verint := [0,0,0,0];
  i := 0;
  while ( (Length(verstr) > 0) and (i < 4) ) do
  begin
    p := pos('.', verstr);
    if p > 0 then
    begin
      if p = 1 then s:= '0' else s:= Copy( verstr, 1, p - 1 );
      verint[i] := StrToInt(s);
      i := i + 1;
      verstr := Copy( verstr, p+1, Length(verstr));
    end
    else
    begin
      verint[i] := StrToInt( verstr );
      verstr := '';
    end;
  end;

end;

// This function compares version string
// return -1 if ver1 < ver2
// return  0 if ver1 = ver2
// return  1 if ver1 > ver2
function CompareDirectXVersion( ver1, ver2: String ) : Integer;
var
  verint1, verint2: array of Integer;
  i: integer;
begin

  SetArrayLength( verint1, 4 );
  DecodeVersion( ver1, verint1 );

  SetArrayLength( verint2, 4 );
  DecodeVersion( ver2, verint2 );

  Result := 0; i := 0;
  while ( (Result = 0) and ( i < 4 ) ) do
  begin
    if verint1[i] > verint2[i] then
      Result := 1
    else
      if verint1[i] < verint2[i] then
        Result := -1
      else
        Result := 0;

    i := i + 1;
  end;

end;

// DirectX version is stored in registry as 4.majorversion.minorversion
// DirectX 8.0 is 4.8.0
// DirectX 8.1 is 4.8.1
// DirectX 9.0 is 4.9.0

function GetDirectXVersion(): String;
var
  sVersion:  String;
begin
  sVersion := '';

  RegQueryStringValue( HKLM, 'SOFTWARE\Microsoft\DirectX', 'Version', sVersion );

  Result := sVersion;
end;


function checkDirectX(): boolean;
begin
  // in this case program needs at least directx 9.0
  if CompareDirectXVersion( GetDirectXVersion(), '4.9.0') < 0 then
  begin
       Result := true;
  end
  else
  begin
    Result := false;
   end;

end;



procedure directX();
begin
  // in this case program needs at least directx 9.0
  if CompareDirectXVersion( GetDirectXVersion(), '4.9.0') < 0 then
  begin
                AddProduct('directx_Jun2010_redist.exe',
                    '/t:' + ExpandConstant('{tmp}\DirectX') + ' /q /c',
                    CustomMessage('directx_title'),
                    CustomMessage('directx_size'),
                    directx_url,
                    false, false);

  end;
end;

我希望这对其他人有所帮助.. 整个想法是我可以发布我的软件而不必担心 DirectX,我的软件至少需要 DirectX 9 一些 XP 用户可能没有更新他们的机器.. 或者有些可能有在 vista 或 7 上删除它,Windows 8 开箱即用,更新版本,所以不用担心。

【讨论】:

  • 我一直在寻找这样的东西。一段时间后,你有没有很好的体验? (想知道从长远来看,让安装程序依赖于来自 MS 的 URL 是个好主意)