3

在网上搜索之后,我能找到的最接近 InnoSetup 的“覆盖用户未更改的所有文件”的内容是此处的链接:

InnoSetup:不要卸载更改的文件

但是,它不完整,我不是 Pascal 专家。我看不到它是如何保存 tStringList 的(当我测试它时也没有看到)。

我的应用程序将来自十几个来源的大量 XML 文件安装到公共用户的文档文件夹中。(而且,是的,我的源代码使用 ** 子路径运算符。)用户可能会更改一些文件。应用程序可能会更改其中的一些。我不想撤消任何用户工作,但是当我升级时,我确实想替换用户没有触及的任何 XML 文件。如何使用 InnoSetup 做到这一点?(同样,当我卸载时,我似乎应该删除用户/应用程序没有更改的所有文件。)

4

1 回答 1

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 散列;因为它更长,冲突的可能性更小。)

于 2013-10-31T08:53:02.063 回答