我正在尝试创建一个安装程序来更新单个csv文件,该文件存在于各个位置,具体取决于用户安装了哪些应用程序。 我们的应用程序安装在Program Files中的公司名称文件夹中。
所以,公司> App1,公司> App2,公司> App3等。当csv文件存在时,它直接位于App文件夹中。
我试过了:
[Files]
Source: "file.csv"; DestDir: "{pf}\Company\*";
各种标志和功能无济于事
flag: onlyifdestfileexists
跳过所有内容,因为它不存在
Check: FileExists('file.csv')
什么都不做
Check: FileExistsWildcard('file.csv')
使用FindFirst()调用函数会尝试创建一个名为*的新目录来安装文件,而不是覆盖找到它的目录中的文件,
[Files]
Source: "file.csv"; DestDir: "{pf}\Company\"; Check: FileExistsWildcard('*\file.csv')
问题似乎与通配符*在与DestDir一起使用时没有做任何事情。它只是查找名为" *"的子文件夹,而不是搜索所有子文件夹。 recursesubdirs标志当然适用于迭代Source的子目录,但DestDir没有等价物。
答案 0 :(得分:1)
DestDir
不支持这样的通配符。
如果您事先知道所有可能的子目录的名称(可能是因为这些是您自己的应用程序),那么最简单的方法是包含多个[Files]
条目,每个可能的应用程序一个。然后,您可以使用onlyifdestfileexists
标志。请注意,在多个条目上使用相同的Source
路径时,只会在安装程序中存储该文件的一个副本,因此它不会膨胀。
如果您的应用程序支持安装到不同的位置(大多数情况下),那么您需要稍微修改一下;而不是硬编码DestDir
,你需要让每个条目看起来像这样:
Source: file.csv; DestDir: {code:FindAppPath|App1}; Flags: onlyifdestfileexists
具有相应的[Code]
函数:
function FindAppPath(AppName: String): String;
在此函数中,使用RegQueryStringValue
或其他方法查找正在搜索的应用程序的当前安装位置(通过AppName
,可以是您选择的任意字符串,也可以是正在查找注册表路径的一部分;如果更容易,您可以为每个应用程序编写单独的函数。如果未安装给定的应用程序,则返回''
,然后由于onlyifdestfileexists
标志将跳过安装文件。请注意,每个应用程序仍需要一个条目,因此您需要事先知道可能安装的应用程序的最大数量。
(如果您不想使用此标记,则跳过安装的另一种方法是定义Check
函数,例如。Check: IsAppInstalled('App1')
或Check: IsApp1Installed
。
如果您不知道(或者不想依赖于了解)预先安装的应用程序的最大数量,那么唯一的解决方案就是回归到纯[Code]
。您需要有一个[Files]
条目,如下所示:
Source: file.csv; DestDir: {tmp}; AfterInstall: CopyToApplications
然后实现CopyToApplications
过程以找到所有可能安装的路径(可能再次,可能通过RegQueryStringValue
),然后为每个安装:
FileCopy(ExpandConstant('{tmp}\file.csv'), AddBackslash(PathToApp) + 'file.csv');
您可能还想查看CodeDlg示例脚本,并在此过程进行时使用CreateOutputProgressPage
向用户提供反馈,但如果文件大小足够小,则可能不一定。
请注意,在所有情况下,您可能都希望禁用卸载支持(因为每个应用程序自己的单独卸载程序都会处理它);确保Uninstallable=no
部分中有[Setup]
。