在浏览网页后,我发现最接近InnoSetup的“覆盖用户没有更改的所有文件”的链接就是这里的链接:
InnoSetup: don't uninstall changed files
然而,它不完整,我不是Pascal专家。我没有看到它如何保存tStringList(当我测试它时它没有。)
我的应用程序将来自十几个来源的大量XML文件安装到公共用户的文档文件夹中。 (并且,是的,我的来源使用**子路径运算符。)用户可能会更改某些文件。应用程序可能会更改其中一些。我不想撤消任何用户工作,但是当我升级时,我确实想要替换用户未触及的任何XML文件。我怎么能用InnoSetup做到这一点? (同样地,似乎当我卸载时,我应该删除用户/应用程序未更改的所有文件。)
答案 0 :(得分:3)
除非您确切知道应用程序可能会做出哪些更改,并且用户不会进行类似更改,并且您愿意并且能够进行编辑,否则可能没有任何好方法可以区分用户编辑和应用程序编辑。写[Code]
以通过读取文件内容来检测差异。
但是,如果您自己仍拥有这些文件的副本,则可以将其替换为旧文件的特定版本。你可能会这样做的一个例子(这只是当场写的;我还没有测试过):
[Files]
Source: SomeFile.xml; ...; Check: IsOverwritable('123456FEDCBA,ABD48291')
[Code]
function IsOverwritable(HashText: String): Boolean;
var
Filename, Hash: String;
Hashes: TStringList;
begin
Filename := ExpandConstant(CurrentFileName);
if not FileExists(Filename) then begin
Result := True;
end else begin
Hash := GetMD5OfFile(Filename);
Hashes := TStringList.Create();
Hashes.CommaText := HashText;
Result := Hashes.IndexOf(Hash) >= 0;
Hashes.Free();
end;
end;
添加之后,您只需要将Check
调用中使用的参数替换为逗号分隔的MD5值列表(例如,使用md5sum
收集)的所有可能版本的由您希望用替换版本覆盖的应用程序的先前版本分发的文件。
如果该文件不存在,则会安装该文件。如果它确实存在,并且其哈希值与指定的哈希值匹配,则它将被覆盖。否则它将被单独留下。
请注意,尽管具有不同的内容,但由于具有相同的MD5哈希,文件将被错误地覆盖的可能性很小,因为哈希可能会发生冲突。然而,偶然发生这种情况的可能性很小,你通常可以忽略它。 (另一个选择是使用SHA-1哈希而不是MD5哈希;因为这个时间越长,冲突的可能性就越小。)