Link to home
Start Free TrialLog in
Avatar of mathes
mathes

asked on

problem with tinifile.create

Hi experts,

with the following code I want to create a *.ini file.
Hpowever after running this syntactically correct program, I never
can find the created *.ini file on my harddisk. (The explorer of Windows 98 says "file not found").

Can you please tell me, what I am doing wrong here?

With kind regards

Mathes

unit tini;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, IniFiles;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);

  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  sl: tstringlist;
function EnumFiles(path: string; findFile: string): string;
function findFileOnAllHarddisks(fileName: string): string;

implementation

{$R *.DFM}

function EnumFiles(path: string; findFile: string): string;
var
  fd1: TWin32FindData;
  c1: cardinal;
  s1: string;
begin
  if fileExists(path + findFile) then begin
    result := path + findFile;
    exit;
  end;
  c1 := FindFirstFile(PChar(path + '*.*'), fd1);
  if c1 <> INVALID_HANDLE_VALUE then
  try
    repeat
      s1 := string(fd1.cFileName);
      if (s1 <> '.') and (s1 <> '..') and (fd1.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY <> 0) then
      begin
        result := EnumFiles(path + s1 + '\', findFile);
        if result <> '' then break;
      end;
    until not FindNextFile(c1, fd1);
  finally Windows.FindClose(c1) end;
end;


function findFileOnAllHarddisks(fileName: string): string;
var
  c1, c2: cardinal;
  ch1: char;
begin
  result := '';
  c2 := GetLogicalDrives;
  for ch1 := 'A' to 'Z' do
    if odd(c2 shr (ord(ch1) - ord('A'))) then begin
      c1 := GetDriveType(PChar(ch1 + ':\'));
      if c1 = DRIVE_FIXED then begin
        result := EnumFiles(ch1 + ':\', fileName);
        if result <> '' then break;
      end;
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  myprogIni: TIniFile;
  s: string;
begin
  s := findFileOnAllHarddisks('myprog.exe'); //find location of myprog.exe
  s := extractfilepath(s);
  s := s + 'myprog.ini';                     // in the same directory of myprog.exe...
  myprogIni := TIniFile.Create(s);           // .... create myprog.ini
  myprogIni.Free;
end;

end.
Avatar of scrapdog
scrapdog
Flag of United States of America image

Try writing something to the INI file, and see if that creates it.
Avatar of kretzschmar
Hi Mathes,

to access/Create a ini file in the same directory of your Prog with the same name as your Prog, you can use this Statement:

  MyIniFile := TiniFile.Create(ChangeFileExt(Paramstr(0),'.INI'));

meikl
Hi Mathes,

If try to create empty txt files on your disk windows is friendly enough to destroy them by default. This is also true for ini files, put some entries and your ini will be saved leave it empty as you've done and it will be destroyed.

MS did a lot to clutter our disks but if we try to do it ourselves they punish us for even trying :O)))).

Hope this helps.
:O)
brUINTje.

Hi Mathes,

Appendix
the INI-File will created (if not exits) by writing something ini it like

MyIniFile := TiniFile.Create(ChangeFileExt(Paramstr(0),'.INI'));   MyIniFile.WriteString('StartParams','MyAppHomeDir',ExtractFilePath(ParamStr(0)));


meikl
Avatar of mathes
mathes

ASKER

Dear experts,

thank you for your help. You found the reason why it didn't work.
Obviously this inifile needs some content, but you can't create an
inifile without entries. And the concpt of meikl with changefileext and paramstr
is very interesting, too.

with kind regards

mathes


Avatar of mathes

ASKER

Dear experts,

thank you for your help. You found the reason why it didn't work.
Obviously this inifile needs some content, but you can't create an
inifile without entries. And the concpt of meikl with changefileext and paramstr
is very interesting, too.

with kind regards

mathes


you can find the location of my progexe.exe if the program myprog.exe is your own program by doing this...

var
  path : string;
  MyIniName : string;
begin
  path := ExtractPathName(Application.FileName);
  MyIniName := path = 'myini.ini';
  Ini.Create(myininame);
  ini.free;
end;

-Viktor
--Ivanov
Just one comment about ini files. If you create a new inifile object and write stuff to it, be aware that nothing appears on your hard disk until a different ini file is opened, or you close your app.

This is because Windows caches one ini file at a time.

You can demonstrate this by creating a text file with nothing in it from windows explorer.

Now in code, create an ini file object from the empty file.
Write something using writestring.

Now load the file into a stringlist, observing it is still empty.

Now create a different inifile object, write something to it.
Reload the original ini file into a stringlist, and it will contain your entry.

You only really have to be aware of this if for example you save a project file (say) in an INI format by using AssignFile and WriteLn, but read it in using a TIniFile object. Before loading, write a proc called FlushIniCache or something which opens a dummy ini file and reads a dummy string (the file does not need to exist)

Also, Windows does not delete zero bytes file by default.
Hi Phillip,

I do have one question left over, is writing a value with writestring then sufficient for saving a ini file on disk?

See the following code no error checking (use at your own risk :O) )

2 buttons and an edit box on a form

procedure TForm1.Button1Click(Sender: TObject);
var
  myprogIni: TIniFile;
  s  : string;
begin
  s := findFileOnAllHarddisks('myprog.exe'); //find location of myprog.exe
  s := extractfilepath(s);
  s := s + 'myprogral.ini'; // in the same directory of myprog.exe...
  myprogIni := TIniFile.Create(s); // .... create myprog.ini
  myprogIni.WriteString('Path of my program', 'program-path', 'c:\mypath.ini');
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  winposhIni: TIniFile;
  i, position: integer;
  temp: string;
  sl : tstringlist;
begin
  if fileexists('c:\myprogral.ini') then begin
    myprogIni := TIniFile.Create('c:\myprogral.ini');
    sl := tstringlist.create;
    myprogIni.ReadSectionValues('Path of my program', sl);
    for i := 0 to sl.count - 1 do
      temp := sl.strings[i];
    position := pos('=', temp);
    delete(temp, 1, position);
    edit1.text := temp;
    myprogIni.Free;
    sl.free;
  end;
end;

When I leave out the writestring in button1click I don't get a ini file in the explorer, whereas I use writestring I do get it saved to use in the button2click, that's where my conclusion came from that windows is removing the empty file itself.

Always curious :O?
brUINTje.

Ah, I see what you are saying.

TIniFile.Create('myfile.ini') does not create a file at all.

Here is the source code for the constructor:

constructor TCustomIniFile.Create(const FileName: string);
begin
  FFileName := FileName;
end;

Here is the code for WriteString. It is the Win API call to WritePrivateProfileString that actually creates the file. It uses FFileName which was set in the constructor.

procedure TIniFile.WriteString(const Section, Ident, Value: string);
begin
  if not WritePrivateProfileString(PChar(Section), PChar(Ident),
    PChar(Value), PChar(FFileName)) then
    raise Exception.CreateFmt(SIniFileWriteError, [FileName]);
end;


Thanks Philip :O)
Is that enough to get an A graded answer from you?
OKidOKi
Think it's fair enough to put it up for say.......... 20 pts.
:O)
ASKER CERTIFIED SOLUTION
Avatar of philipleighs
philipleighs

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hmm...
Philip I did put up a seperate Q for your answer to my question in this thread hahahahahahhahaa
Should look at the "for Philip" Question in the Delphi area it's rated for 20 pts and when you answer you'll get an A

:O) Always happy!
Bruintje