Question

Can I use the TIniFile class from Delphi in any way to write comments to my INI files ?

[VALUES]
; first number
a=5
; something else
b=25
...
...

In the examples (EXAMPLE) I found on the web there are sometimes nice comment lines added, but not shown how to create, read , write these lines ....

Was it helpful?

Solution

The TIniFile class is a loose wrapper around the Windows API functions the provide INI file services. That API does not support writing comments and so TIniFile cannot do so either.

If you want to emit files with comments, you will have to find a different INI file library, or roll your own.

OTHER TIPS

Neither TIniFile or TMemIniFile supports reading or writing INI file comments.

If you need to add or retrieve comments, you'll need to use a TStringList instead, and use the Names and Values functionality to read and write values. You can save the file with SaveToFile and load it with LoadFromFile, but it takes more work to handle the default values and various ReadXX methods yourself.

Actually, you can do it with TIniFile:

WriteString('Section', '; Comment'#13#10 + 'Name', 'Value');

Here's with a check that the value doesn't exist:

if ReadString('Section', 'Name', #13#10) = #13#10 then
  WriteString('Section', '; Comment'#13#10 + 'Name', 'Value');

(TIniFile has ValueExists function, but it reads the whole section and searches for the key. I prefer this small check.)

Only can suggest use WriteString like following:

ini.WriteString('VALUES','; first number','');

The result is not exactly the same you expected, but anyway you will be able to add some comments.

I know its a old question, but i'll add my funcion to add comment to ini file. Fell free to improve . Sorry about grammar mistakes.English is not my primary language

class Procedure TCoreIniAsTextFile.AddComment(ini: TiniFile; Comment: array of string; Section: string = ''; Key: string = '');
Const
  LIST_NUMERIC_SIZE: Integer = 3;
var
  IniAsText         : Tstrings;
  i                 : Integer;
  j                 : Integer;
  Buffer            : string;
  // Method to remove previous comment
  Procedure WriteComment(StartLine: Integer);
var
  Linha             : Integer;
  LinBuf            : string;
begin
  repeat
    // add a space to avoid a except in the following line
    // if a line is blank
    LinBuf := Trim(IniAsText[StartLine]) + ' ';
    if LinBuf[1] = ';' then // is a comment
      IniAsText.Delete(StartLine);
  until (LinBuf[1] <> ';') or (IniAsText.Count = 0);
  // add new comment
  for Linha := High(Comment) downto Low(Comment) do
    begin
      IniAsText.Insert(StartLine, ';' + Comment[Linha]);
    end;

  IniAsText.Insert(StartLine, ''); // add a line for esthetic purposes  
  IniAsText.SaveToFile(ini.FileName);
end;
// function to add zeros to left 1 -> 001
function StrZeroReg(num: Int64; nsize: Integer): string;
begin
  Result := IntToStr(num);
  Result := StringOfChar('0', nsize - Length(Result)) + Result;
end;  
begin
  IniAsText := nil; // to avoid a warning below
  Section := Uppercase(Section);
  Key := Uppercase(Key);
  try
    IniAsText := TStringList.Create;
    if not FileExists(ini.FileName) then
      IniAsText.SaveToFile(ini.FileName);  // Create a blank file 

    IniAsText.LoadFromFile(ini.FileName);

    // If no section or key direct comment to file header
    if (Section = EmptyStr) and (Key = EmptyStr) then
      begin
        WriteComment(0);
        Exit;
      end;

    // If key is passed section is required 
    if (Section = EmptyStr) and (Key <> EmptyStr) then
      begin
        if not ini.SectionExists(Section) then
          raise Exception.Create('Section is required to write key comment');
      end;

    //If section is passed, but not key assume coment is to section 
    if (Section <> EmptyStr) and (Key = EmptyStr) then
      begin
        // section must exists
        if not ini.SectionExists(Section) then
          raise Exception.Create('Section ' + Section + ' does not exists');

        // search for section location in file 
        for i := 0 to IniAsText.Count - 1 do
          begin
            Buffer := Trim(Uppercase(IniAsText[i]));
            if (Buffer = '[' + Section + ']') then
              begin
                WriteComment(i);
                Exit;
              end;
          end;

        // sanity check
        raise Exception.Create('Section ' + Section + ' does not exists');
        exit;
      end;

    // If key and section is passed assume is a key comment
    if not ini.ValueExists(Section, Key) then
      begin

        // some ini libraries save stringlists to ini and save values as
        // valuea001,valuea002,...,valueannn . then search KEY000 as compatibility
        if ini.ValueExists(Section, Key + StrZeroReg(0, LIST_NUMERIC_PALCES)) then
          Key := Key + StrZeroReg(0, LIST_NUMERIC_PALCES)
        else // if not found Key000
          raise Exception.Create('KEY ' + Section + '\' + Key + ' does not exists');
      end;

    // search combination of section + key 
    for i := 0 to IniAsText.Count - 1 do
      begin
        Buffer := Trim(Uppercase(IniAsText[i]));
        if (Buffer = '[' + Section + ']') then
          begin
            for j := i + 1 to IniAsText.Count - 1 do
              begin
                Buffer := Trim(Uppercase(IniAsText[j])) + ' '; // space to avoid a exception 
                // Buffer[1] <> ';' to avoid commented lines 
                // Key + '=', Buffer) = 1 to avoid false cognats but will fail if param is 
                // param =value (valid to some libraries)
                if (Buffer[1] <> ';') and (Pos(Key + '=', Buffer) = 1) then
                  begin
                    WriteComment(j);
                    Exit;
                  end;
              end
          end;
      end;

  finally
    if Assigned(IniAsText) then
      IniAsText.Free;
  end;
end;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top