有没有办法使用 Inno Setup 删除 INI 文件中的注释?

问题描述

有没有办法使用 Inno Setup 删除 INI 文件中的注释?我们有一个正在运行更新的现有安装,但我们想使用 Inno Setup 安装程序删除现有注释。可用标志不能用于注释,只能用于设置:

Flags 这个参数是一组额外的选项。多个选项可能 通过用空格分隔它们来使用。以下选项是 支持

createkeyifdoesntexist 仅当文件中不存在密钥时才分配给密钥。如果未指定此标志,则密钥将 不管它是否已经存在,都会被设置。

uninsdeleteentry 卸载程序时删除该条目。这可以与 uninsdeletesectionifempty 标志结合使用。

uninsdeletesection 卸载程序时,删除条目所在的整个部分。显然不会 在 Windows 本身使用的部分上使用它是个好主意 (就像 WIN.INI 中的某些部分)。你应该只在 您的应用程序专用的部分。

uninsdeletesectionifempty 与 uninsdeletesection 相同,但仅在其中没有键时才删除该部分。这个可以组合 带有 uninsdeleteentry 标志。


我想删除 ; 之后、文件末尾或 [Section] 之前以 [AnotherSection] 开头的任何行。

解决方法

使用这样的代码:

const
  CP_UTF8 = 65001;

function DeleteIniSectionComments(Section,FileName: string): Boolean;
var
  Lines: TStrings;
  InSection: Boolean;
  Line: string;
  I,N: Integer;
begin
  Result := False;
  Lines := TStringList.Create;
  try
    if not LoadStringsFromFileInCP(FileName,Lines,CP_UTF8) then
    begin
      Log(Format('Error loading the file %s',[FileName]));
    end
      else
    begin
      Log(Format('Loading file %s with %d lines',[FileName,Lines.Count]));
      InSection := False;
      N := 1;
      I := 0;
      while I < Lines.Count do
      begin
        Line := Trim(Lines[I]);
        if (Line = '') or (Line[1] = ';') then
        begin
          if InSection then
          begin
            Log(Format('Deleting empty or comment line %d',[N]));
            Lines.Delete(I);
          end
            else
          begin
            Inc(I);
          end;
        end
          else
        begin
          if (Line[1] = '[') and (Line[Length(Line)] = ']') then
          begin
            if CompareText(Trim(Copy(Line,2,Length(Line) - 2)),Section) = 0 then
            begin
              Log(Format('Found section %s at line %d',[Section,N]));
              InSection := True;
            end
              else
            begin
              if InSection then
              begin
                Log(Format('Section %s ends at line %d',N]));
                InSection := False;
              end;
            end;
          end;
          Inc(I);
        end;
        Inc(N);
      end;

      Result := SaveStringsToFileInCP(FileName,CP_UTF8);
      if not Result then
      begin
        Log(Format('Error saving the file %s',[FileName]));
      end;
    end;
  finally
    Lines.Free;
  end;
end;

LoadStringsFromFileInCPSaveStringsToFileInCP 来自 Inno Setup - Convert array of string to Unicode and back to ANSI。不过,如果您不需要 UTF-8(毕竟纯 INI 文件使用 Ansi 编码),您可以使用内置的 LoadStringsFromFileSaveStringsToFile

您可以在 DeleteIniSectionCommentsssInstall 步骤中从 CurStepChanged event 调用 ssPostInstall

虽然imo,一旦你有这样的代码并且你的最终目标是实际删除整个部分,那么将代码更改为“删除包括评论在内的整个部分”是有意义的,而不仅仅是删除评论。