简体   繁体   English

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

[英]Install the same file to all subdirectories in Inno Setup

I am newbie with Inno Setup and I have been reading some threads but could not find how to do the following.我是 Inno Setup 的新手,我一直在阅读一些线程,但找不到如何执行以下操作。

I simply would like to search for folders within a directory and in each folder detected install the same file with no selection of wizard page shown to the user.我只是想在目录中搜索文件夹,并在检测到的每个文件夹中安装相同的文件,而不向用户显示向导页面的选择。 Not recursive, only files inside the detected folders and not subfolders.不是递归的,只有检测到的文件夹中的文件,而不是子文件夹。

I meant to install the same file in all folders detected while giving no option to the user to choose from.我的意思是在检测到的所有文件夹中安装相同的文件,同时没有给用户选择的选项。 However, all other pages in the installer would be displayed as usual.但是,安装程序中的所有其他页面将照常显示。

Thanks in advance提前致谢

Tag the file with dontcopy flag and then install it programmatically in CurStepChanged(ssInstall) (or ssPostInstall ).dontcopy标志标记文件,然后在CurStepChanged(ssInstall) (或ssPostInstall )中以编程方式安装它。

This will work well, only if the file is not huge.仅当文件不是很大时,这才能很好地工作。 Otherwise the installer will unpleasantly hang.否则安装程序将挂起令人不快。 For a good user experience with huge files, more complex solution is needed.为了获得大文件的良好用户体验,需要更复杂的解决方案。

#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;

Alternatively, if you have a fixed set of folders, you can generate entry for each folder in the [Files] section using 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;

If you add SaveToFile to the end of the script :如果SaveToFile添加到脚本的末尾

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

... then you should see in Preprocessed.iss that the code generates a script like this: ...然后您应该在Preprocessed.iss中看到代码生成了这样的脚本:

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

Thanks a lot Martin!非常感谢马丁! I did it another way that may be of help to other users.我做了另一种可能对其他用户有帮助的方法。 I set a file for every potential folder I want to detect (it was only for four).我为每个我想检测的潜在文件夹设置了一个文件(它只有四个)。

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

Then I use the following to check if the folder exists:然后我使用以下内容检查文件夹是否存在:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM