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

Is there a way to delete a comment in an INI file using Inno Setup?

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

Flags This parameter is a set of extra options. Multiple options may be used by separating them by spaces. The following options are supported:

createkeyifdoesntexist Assign to the key only if the key doesn't already exist in the file. If this flag is not specified, the key will be set regardless of whether it already existed.

uninsdeleteentry Delete the entry when the program is uninstalled. This can be combined with the uninsdeletesectionifempty flag.

uninsdeletesection When the program is uninstalled, delete the entire section in which the entry is located. It obviously wouldn't be a good idea to use this on a section that is used by Windows itself (like some of the sections in WIN.INI). You should only use this on sections private to your application.

uninsdeletesectionifempty Same as uninsdeletesection, but deletes the section only if there are no keys left in it. This can be combined with the uninsdeleteentry flag.


我想删除 [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', [Section, N]));
                InSection := False;
              end;
            end;
          end;
          Inc(I);
        end;
        Inc(N);
      end;

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

LoadStringsFromFileInCPSaveStringsToFileInCP 来自 。虽然如果你不需要 UTF-8(纯 INI 文件毕竟使用 Ansi 编码),你可以使用内置的 LoadStringsFromFileSaveStringsToFile.

您可以在 ssInstallssPostInstall 步骤中从 CurStepChanged event 调用 DeleteIniSectionComments

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