搜索Inno Setup DestDir

时间:2015-12-07 04:00:47

标签: windows-installer installer inno-setup acrobat pascalscript

我正在尝试使用Inno Setup来分发另一个应用程序用作插件的文件。如果找不到插件目的地,它仍然应该自己安装到Program Files目录中,为用户提供手动指令。

Tlama致敬,提供了类似问题中使用的一些代码:Inno Setup find subfolder

以下脚本列出了我希望实现的基本设置,以及脚本不完整的注释。我只是在脑子里。 : - )

  1. 如何将找到的目录传回StampTargetDir(目前只是一个MsgBox)

  2. 如何搜索指定目录名下的所有子目录(即'邮票')

  3. 如何将所有子目录(#2)的搜索限制为仅生成{pf}{localappdata}的几个命名子目录(即" Adob​​e"和&# 34;的Acrobat&#34)

  4. [Files]下进行文件插件安装,条件是找到'邮票' 。目录

  5. P.S。我知道搜索有一些明显的缺点。但是"邮票"目录不太可能在其他领域使用(见#3)。

    [Files]
    ; Install all the files in a user specified location.
    Source: "C:\mydir\readme.pdf"; DestDir: "{app}"; Flags: ignoreversion
    Source: "C:\mydir\stamp.pdf"; DestDir: "{app}"; Flags: ignoreversion
    ; If found, install the stamp file in the Adobe Acrobat or Reader Stamp directory.
    Source: "C:\mydir\stamp.pdf"; DestDir: "{code:StampTargetDir}"; Flags: ignoreversion
    
    
    [Tasks]
    Name: pf; Description: "&All users on this computer."; GroupDescription: "Configure Acrobat stamp plug-in:"; Flags: exclusive
    Name: local;  Description: "&Only the current user (me)."; GroupDescription: "Configure Acrobat stamp plug-in:"; Flags: exclusive unchecked
    Name: none;  Description: "&Do not configure stamps (manual setup)."; GroupDescription: "Configure Acrobat stamp plug-in:"; Flags: exclusive unchecked
    
    [Code]
    function GetFirstMatchingSubfolder(const Path: string; out Folder: string): Boolean;
    var
      S: string;
      FindRec: TFindRec;
    begin
      Result := False;
      if FindFirst(ExpandConstant(AddBackslash(Path) + '*'), FindRec) then
      try
        repeat
          // *** THIS DOES NOT SEARCH SUBDIRECTORIES ***
          if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0) and
            (FindRec.Name <> '.') and (FindRec.Name <> '..') and
            (FindRec.Name = 'Stamps') then
          begin
            Result := True;
            Folder := AddBackslash(Path) + FindRec.Name;
          end;
        until
          not FindNext(FindRec);
      finally
        FindClose(FindRec);
      end;
    end;
    
    function StampTargetDir(Param: String): String;
    begin
      if IsTaskSelected('pf') then
        // *** THIS NEEDS TO BE 'Stamps' DIRECTORY FOUND UNDER {pf}
        Result := ExpandConstant('{app}') + '\pf'
      else if IsTaskSelected('local') then
        // *** THIS NEEDS TO BE 'Stamps' DIRECTORY FOUND UNDER {localappdata}
        // Assuming {localappdata} is the user's Application Data Folder
        // Typically C:\Documents and Settings\username\Application Data.
        Result := ExpandConstant('{app}') + '\local'
      else
        Result := ExpandConstant('{app}') + '\none'
    end;
    
    // *** This procedure is just for testing. The results of
    // GetFirstMatchingSubfolder should be used by StampTargetDir
    procedure InitializeWizard;
    var
      S: string;
    begin
      // *** THIS DOES NOT LIMIT SEARCH TO {pf}\Adobe or {pf}\Acrobat ***    if GetFirstMatchingSubfolder(ExpandConstant('{pf}'), S) then
        MsgBox('An extra copy will go in here: ' + S, mbInformation, MB_OK);
    end;
    

1 个答案:

答案 0 :(得分:2)

  1. 要将路径从InitializeWizard传递到StampTargetDir,请使用全局变量。虽然我建议您最好使用CurStepChanged(ssInstall)而不是InitializeWizard,除非您需要比实际安装期间更早的路径。

  2. GetFirstMatchingSubfolder

  3. 中使用递归
  4. 最干净的解决方案是使用特定的根运行GetFirstMatchingSubfolder多次(对于Adobe和Acrobat,运行两次)

  5. 使用Check parameter

  6. 代码可以是:

    [Files]
    Source: "C:\mydir\stamp.pdf"; DestDir: "{code:GetStampsFolderPath}"; \
        Check: WasStampsFolderFound; Flags: ignoreversion
    
    [Code]
    
    const
      StampsFolderName = 'Stamps';
    
    var
      StampsFolderPath: string;
    
    function WasStampsFolderFound(): Boolean;
    begin
      Result := (StampsFolderPath <> '');
    end;
    
    function GetStampsFolderPath(Params: string): string;
    begin
      Result := StampsFolderPath;
    end;
    
    function GetFirstMatchingSubfolderRecursively(const Path: string; Name: string; out Folder: string): Boolean;
    var
      FindRec: TFindRec;
      FolderPath: string;
    begin
      Result := False;
      Log(Format('Searching in %s', [Path]));
    
      if FindFirst(AddBackslash(Path) + '*', FindRec) then
      try
        repeat
          if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0) then
          begin
            FolderPath := AddBackslash(Path) + FindRec.Name;
            if CompareText(FindRec.Name, Name) = 0 then
            begin
              Result := True;
              Folder := FolderPath;
              Log(Format('Match: %s', [Folder]));
            end
              else
            if (FindRec.Name <> '.') and (FindRec.Name <> '..') then
            begin
              Result := GetFirstMatchingSubfolderRecursively(FolderPath, Name, Folder);
            end;
          end;
        until Result or (not FindNext(FindRec));
      finally
        FindClose(FindRec);
      end;
    end;
    
    procedure CurStepChanged(CurStep: TSetupStep);
    var
      RootPath: string;
    begin
      Log(Format('CurStepChanged %d', [CurStep]));
    
      if CurStep = ssInstall then
      begin
        if IsTaskSelected('pf') then
        begin
          // this should be pf32 or pf64 specifically,
          // depending on where Adobe installs the applications
          RootPath := ExpandConstant('{pf}\');
        end
          else
        if IsTaskSelected('local') then
        begin
          RootPath := ExpandConstant('{localappdata}\');
        end;
    
        if RootPath = '' then
        begin
          Log(Format('No task selected, will not search for %s', [StampsFolderName]));
        end
          else
        begin
          Log(Format('Searching for %s folder under %s', [StampsFolderName, RootPath]));
    
          if GetFirstMatchingSubfolderRecursively(RootPath + 'Adobe', StampsFolderName, StampsFolderPath) or
             GetFirstMatchingSubfolderRecursively(RootPath + 'Acrobat', StampsFolderName, StampsFolderPath) then
          begin
            Log(Format('Found %s folder at %s', [StampsFolderName, StampsFolderPath]));
          end
            else
          begin
            Log(Format('%s folder not found anywhere', [StampsFolderName]));
          end;
        end;
      end;
    end;