将相同的文件安装到 Inno Setup 中的所有子目录

Install the same file to all subdirectories in Inno Setup

我是 Inno Setup 的新手,我一直在阅读一些主题,但找不到如何执行以下操作。

我只是想在目录中搜索文件夹,并在检测到的每个文件夹中安装相同的文件,而不向用户显示向导页面的选择。非递归,仅检测到的文件夹内的文件而不是子文件夹内的文件。

我的意思是在检测到的所有文件夹中安装相同的文件,而不给用户任何选项。但是,安装程序中的所有其他页面将照常显示。

提前致谢

使用 dontcopy flag and then install it programmatically in CurStepChanged(ssInstall)(或 ssPostInstall)标记文件。

这会很好用,前提是文件不是很大。否则安装程序会令人不快地挂起。为了在处理大文件时获得良好的用户体验,需要更复杂的解决方案。

#define TheFileName "thefile.txt"

[Files]
Source: "{#TheFileName}"; Flags: dontcopy

[Code]

procedure CurStepChanged(CurStep: TSetupStep);
var
  RootPath: string;
  TempPath: string;
  DestPath: string;
  FindRec: TFindRec;
  Count: Integer;
begin
  if CurStep = ssInstall then
  begin
    Log('Extracting {#TheFileName}...');
    ExtractTemporaryFile('{#TheFileName}');
    TempPath := ExpandConstant('{tmp}\{#TheFileName}');
    RootPath := ExpandConstant('{app}');
    Log(Format('Searching in "%s"...', [RootPath]));
    Count := 0;
    if not FindFirst(RootPath + '\*', FindRec) then
    begin
      Log(Format('"%s" not found.', [RootPath]));
    end
      else
    begin
      try
        repeat
          if (FindRec.Name <> '.') and (FindRec.Name <> '..') and
             (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0) then
          begin
            Log(Format('Found "%s".', [FindRec.Name]));
            DestPath := RootPath + '\' + FindRec.Name + '\{#TheFileName}';
            if FileCopy(TempPath, DestPath, False) then
            begin
              Log(Format('The file was installed to "%s".', [DestPath]));
              Inc(Count);
            end
              else
            begin
              Log(Format('Error installing the file to "%s".', [DestPath]));
            end;
          end;
        until not FindNext(FindRec);
      finally
        FindClose(FindRec);
      end;

      if Count = 0 then
      begin
        Log(Format('No subfolder to install file "%s" to was found in "%s".', [
          '{#TheFileName}', RootPath]));
      end
        else
      begin
        Log(Format('File "%s" was installed to %d subfolder(s) of "%s".', [
          '{#TheFileName}', Count, RootPath]));
      end;
    end;
  end;
end;

或者,如果您有一组固定的文件夹,则可以使用 preprocessor:

[Files] 部分为每个文件夹生成条目
[Files]
#define FolderEntry(Name) \
    "Source: ""C:\source\*""; DestDir: ""{app}\" + Name + """; " + \
         "Check: CheckDir('" + Name + "')"
#emit FolderEntry('2023')
#emit FolderEntry('2024')
#emit FolderEntry('2025')
[Code]
function CheckDir(DirName: string): Boolean;
begin
  Result := DirExists(ExpandConstant('{app}') + '\' + DirName);
end;

如果你add SaveToFile to the end of the script:

#expr SaveToFile(AddBackslash(SourcePath) + "Preprocessed.iss")

...那么您应该在 Preprocessed.iss 中看到代码生成如下脚本:

[Files]
Source: "C:\source\*"; DestDir: "{app}23"; Check: CheckDir('2023')
Source: "C:\source\*"; DestDir: "{app}24"; Check: CheckDir('2024')
Source: "C:\source\*"; DestDir: "{app}25"; Check: CheckDir('2025')

非常感谢马丁!我用另一种方式做了,可能对其他用户有帮助。 我为每个我想检测的潜在文件夹设置了一个文件(只有四个)。

[Files] Source: "C:\Users\XXXXX\dll\*"; DestDir: "{commonappdata}\XXXX23"; Check:CheckDir2023;

然后我使用以下方法检查文件夹是否存在:

function CheckDir2023 : Boolean;
   begin
     if (DirExists(ExpandConstant('{commonappdata}\xxxxxx23\'))) then
       begin
         Result := True;
       end
     else
     begin
       Result := False;
     end;
   end;