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



我是Inno Setup的新手,我一直在阅读一些线程,但找不到如何做以下操作。

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

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

Thanks in advance

dontcopy标记文件,然后以编程方式安装在CurStepChanged(ssInstall)(或ssPostInstall)中。

  • 使用ExtractTemporaryFile将文件解压缩到临时文件夹
  • 使用FindFirst/FindNext函数查找子文件夹
  • 使用FileCopy将文件从临时文件夹复制到找到的子文件夹。
  • Loga lot.

这将工作良好,只有当文件不太大。否则,安装程序将令人不快地挂起。对于大文件,为了获得良好的用户体验,需要更复杂的解决方案。

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

如果将SaveToFile添加到脚本末尾:

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

…那么您应该在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')

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

[Files] Source: "C:UsersXXXXXdll*"; DestDir: "{commonappdata}XXXX2023"; Check:CheckDir2023;

然后使用以下命令检查文件夹是否存在:

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

最新更新