[英]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
)中以编程方式安装它。
ExtractTemporaryFile
to extract the file to a temporary folder.使用ExtractTemporaryFile
将文件提取到临时文件夹。FindFirst
/ FindNext
functions to find the subfolders.使用FindFirst
/ FindNext
函数查找子文件夹。FileCopy
to copy the file from a temporary folder to the found subfolder(s).使用FileCopy
将文件从临时文件夹复制到找到的子文件夹。Log
a lot. Log
很多。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.