Lazarus

Programming => General => Topic started by: BjPascal on July 11, 2018, 03:11:24 pm

Title: TRegIniFile raises exception
Post by: BjPascal on July 11, 2018, 03:11:24 pm
using Lazarus 1.9.0 in Delphi-mode and FPC 3.1.1 on Win7 x64

When using TRegIniFile then the first Readinteger works ok.

reg:= TRegIniFile.Create('\Software\myName\myApp');
i:= reg.ReadInteger(SECT_SETTINGS, 'edRcvUdpPort', 0);
i:= reg.ReadInteger(SECT_SETTINGS, 'edRcvUdpPort', 0);

But the second identical Readinteger generates this
   "Project * raised exception class 'External: ?'"

The same with other read methods. It seems I can use a method only once.
Any idea why and how to fix it?

I imported it from Delphi and don't want to modify the source.

Title: Re: TRegIniFile raises exception
Post by: Trenatos on July 11, 2018, 05:12:47 pm
http://wiki.freepascal.org/Using_INI_Files

The wiki for FPC shows TINIFile.Create(); rather than TRegIniFile.Create();
Title: Re: TRegIniFile raises exception
Post by: BjPascal on July 11, 2018, 06:56:19 pm
I use Registry acces with the option to easily switch to ini files if needed.
Title: Re: TRegIniFile raises exception
Post by: Trenatos on July 11, 2018, 07:27:17 pm
http://wiki.freepascal.org/fcl-registry
Title: Re: TRegIniFile raises exception
Post by: BjPascal on July 12, 2018, 01:25:37 am
I now found the error:
each method-call closes the key. So a subsequent call returns with "handle is invalid".
I fixed regini.inc at the bottom:

procedure TRegIniFile.CloseSection;
begin
//  CloseKey(CurrentKey);
end;

and it now works fine!
Title: Re: TRegIniFile raises exception
Post by: Bart on July 12, 2018, 06:44:53 pm
Worsk fine (without your patch) for me (win32 fpc 3.04 and 3.1.1).

Bart
Title: Re: TRegIniFile raises exception
Post by: Thaddy on July 12, 2018, 06:58:51 pm
https://i1.wp.com/www.learningspy.co.uk/wp-content/uploads/2015/10/nas-01.jpg?fit=300%2C246

Bad excuse. Bart.
Title: Re: TRegIniFile raises exception
Post by: Bart on July 12, 2018, 08:20:22 pm
Tested with fpc 3.0.4 win32 and win64 and win fpc trunk (r39352) win32:

Code: Pascal  [Select][+][-]
  1. program rtest;
  2.  
  3. {$apptype console}
  4. {$ifdef fpc}{$mode objfpc}{$endif}
  5.  
  6. uses
  7.   registry, sysutils;
  8.  
  9. var
  10.   RegIni: TRegIniFile;
  11.   WFileName: String;
  12.   i: Integer;
  13. begin
  14.   RegIni := TRegIniFile.Create(
  15.       'Software\MicroSoft\Windows\CurrentVersion\Explorer');
  16.   try
  17.     for i := 1 to 3 do
  18.     begin
  19.       WFileName := RegIni.ReadString ('Shell Folders', 'Desktop', 'Failure!');
  20.       writeln(format('Try %d: WFileName = "%s"',[i,WFileName]));
  21.     end;
  22.   finally
  23.     RegIni.Free;
  24.   end;
  25. end.

Outputs

Code: [Select]
C:\Users\Bart\LazarusProjecten\bugs\Console\regini>rtest
Try 1: WFileName = "C:\Users\Bart\Desktop"
Try 2: WFileName = "C:\Users\Bart\Desktop"
Try 3: WFileName = "C:\Users\Bart\Desktop"

Bart
Title: Re: TRegIniFile raises exception
Post by: BjPascal on July 13, 2018, 10:25:27 am
Yes Bart that works.

But not this, where the "Section"-name has been moved to the create path to keep subsequent calls of the same section simpler.
Code: Pascal  [Select][+][-]
  1. RegIni := TRegIniFile.Create('Software\MicroSoft\Windows\CurrentVersion\Explorer\Shell Folders');
  2.  for i := 1 to 3 do
  3.      WFileName := RegIni.ReadString ('', 'Desktop', 'Failure!');
  4.  
Title: Re: TRegIniFile raises exception
Post by: wp on July 13, 2018, 10:45:20 am
Yes Bart that works.

But not this, where the "Section"-name has been moved to the create path to keep subsequent calls of the same section simpler.
Code: Pascal  [Select][+][-]
  1. RegIni := TRegIniFile.Create('Software\MicroSoft\Windows\CurrentVersion\Explorer\Shell Folders');
  2.  for i := 1 to 3 do
  3.      WFileName := RegIni.ReadString ('', 'Desktop', 'Failure!');
  4.  
But RegIniFile still is an IniFile after all. Would you do the same with TIniFile?
Title: Re: TRegIniFile raises exception
Post by: Bart on July 13, 2018, 02:48:31 pm
But RegIniFile still is an IniFile after all. Would you do the same with TIniFile?

It may not be best practice, but it should not crash.
TRegIniFile is a derivative of TRegistry, not of TInifile b.t.w.
It should be perfectly OK to query register values multiple times.

B.t.w. I was unaware of the fact you could leave Section parameter empty.
Is that officially supported?

Bart
Title: Re: TRegIniFile raises exception
Post by: Bart on July 13, 2018, 04:34:30 pm
Even with Section parameter empty I still don't get a crash (but on second try reading fails).
Delphi (7) seems to allow that and consecutive reads are OK.

Bart
Title: Re: TRegIniFile raises exception
Post by: Bart on July 13, 2018, 04:49:44 pm
Reported as issue 33980 (https://bugs.freepascal.org/view.php?id=33980).

Bart
Title: Re: TRegIniFile raises exception
Post by: wp on July 13, 2018, 05:07:04 pm
TRegIniFile is a derivative of TRegistry, not of TInifile b.t.w.
I do remember that in my Delphi days I had replaced TIniFile by TRegIniFile in order to easily store the settings to the registry without changing anything else. This must be the reason why I confused it.
Title: Re: TRegIniFile raises exception
Post by: BjPascal on July 15, 2018, 10:33:40 am
Bart,

I have been using the empty section from Delphi-5 to Berlin, simply because it is much clearer to have the registry tree defined in one single constant instead of breaking it up into two. And TRegini has been my favourite because it's a lot simpler to use than anything else.

I found another bug:
When using
TRegIniFile.Create('\Software\myName\myApp');

(with leading backslash) then all write operations will fail, because these always prepend another '\' to it.
The read functions don't have that issue.

Delphi treats both cases properly.
So you might add this to your issue report also.
Title: Re: TRegIniFile raises exception
Post by: Bart on July 15, 2018, 06:33:46 pm
Filed as issue #33993 (https://bugs.freepascal.org/view.php?id=33993).

Bart
Title: Re: TRegIniFile raises exception
Post by: CM630 on August 28, 2020, 11:27:00 am
I have got this code from a Delphi source:

Code: Pascal  [Select][+][-]
  1. ...
  2. uses ... registry...
  3. ...
  4. procedure TForm1.Button1Click(Sender: TObject);
  5. var Ini:TRegIniFile;
  6. begin
  7.   Ini := TRegIniFile.Create('Test Reg Entry');
  8.   Ini.WriteString('General Settings', 'GenSet1', 'GenSet1a');
  9.   Ini.WriteString('General Settings', 'GenSet2', 'GenSet2a');
  10.   Ini.Free; //Lazarus crashes on ini.free
  11. end;    

It works fine, the values are written in registry, but it crashes on Ini.Free. Could it be a bug in Lazarus?
I am using Lazarus 2,0,10; W10 64bit;FPC3,2,0;rev 63525.
Title: Re: TRegIniFile raises exception
Post by: Bart on August 28, 2020, 03:16:26 pm
Please try this in a pure fpc program, no dependencies on LCL/Lazarus/Lazutils.

If it crashes, also try with fpc trunk.

B.t.w. Using TRegIniFile in modern times is a bit weird.
It was introduced when MS introduced the registry, to make porting ini-file settings into the registry a little bit easier. That is now > 20 years ago.
If you need to use the registry, use TRegistry instead (which also kind of works on non-Windows platforms, whereas TRegIniFile is flawed beyond repair on such platforms).

Bart
Title: Re: TRegIniFile raises exception
Post by: Bart on August 28, 2020, 09:13:26 pm
Code: Pascal  [Select][+][-]
  1. uses
  2.   registry;
  3.  
  4. var
  5.   Ini: TRegIniFile;
  6. begin
  7.   Ini := TRegIniFile.Create('fpc_reginifile_test');
  8.   Ini.WriteString('aSection', 'aIdent', 'aValue');
  9.   Ini.WriteSTring('aOtherSection','aOtherIdent','aOtherValue');
  10.   Ini.Free;
  11. end.

Does not crash with either fpc 3.2.0 or fpc trunk.

With 3.2.0 it does not properly write the key/value pairs though, it does with trunk.
It seems that rr44477 wasn't merged to 3.2.0 (it is in fixes 3.2 though).

Bart
Title: Re: TRegIniFile raises exception
Post by: Bart on August 28, 2020, 09:16:04 pm
Also no crash with the same code inside a Lazarus (trunk) event handler.

Bart
Title: Re: TRegIniFile raises exception
Post by: CM630 on August 29, 2020, 09:29:40 am

Thanks, so I will just have to wait, until there is an official release with the fix.

B.t.w. Using TRegIniFile in modern times is a bit weird.
Some of the tools used in our company are written in Delphi. One of them needs improvement, so I got the Delphi code and I got it conveted to Lazarus, but s.o. might try to merge my changes in the Delphi source (they do not have a license for me, AFAIK it is extremely expensive).
If it was up to me I would never write anything in the registry, since this is okay nether with portablility, nor with non-Windows.
Title: Re: TRegIniFile raises exception
Post by: trev on August 29, 2020, 02:29:18 pm
Thanks, so I will just have to wait, until there is an official release with the fix.

You don't have to wait as you could:

1) Download the source and compile the FPC fixes 3.2 branch; or
2) Patch the FPC 3.2.0 release and re-compile.

Use the source, Luke :)
Title: Re: TRegIniFile raises exception
Post by: Bart on August 29, 2020, 10:22:36 pm
Some of the tools used in our company are written in Delphi. One of them needs improvement, so I got the Delphi code and I got it conveted to Lazarus

It would probably be rather simple to rewrite this to use TRegistry instead.
This should then also work in Lazarus.

Bart
Title: Re: TRegIniFile raises exception
Post by: CM630 on August 31, 2020, 04:59:58 pm
You don't have to wait as you could:

1) Download the source and compile the FPC fixes 3.2 branch; or
2) Patch the FPC 3.2.0 release and re-compile.
..
Thanks, I would do it in the older days, when I was much more aware and dependent on Lazarus.
Now this just sounds me like a few hours of googling and reading manuals, I cannot afford to spend that time.


Years ago there used to be nightly build of Lazarus, but they stopped being built.
Title: Re: TRegIniFile raises exception
Post by: CM630 on May 19, 2021, 03:03:02 pm
Hi again.
Lazarus Version 2.0.12, date 2021-04-06; FPC 3.2.0; SVN 64642.


Same code on Win10, 64 bit:
Code: Pascal  [Select][+][-]
  1.  
  2. {$MODE Delphi}
  3. ...
  4. uses
  5.   ...registry;
  6. ...
  7. procedure TForm1.Button1Click(Sender: TObject);
  8. var
  9.   Ini: TRegIniFile;
  10. begin
  11.   Ini := TRegIniFile.Create('fpc_reginifile_test');
  12.   Ini.WriteString('aSection', 'aIdent', 'aValue');
  13.   Ini.WriteSTring('aOtherSection','aOtherIdent','aOtherValue');
  14.   Ini.Free;
  15. end;  



It creates in HKEY_CURRENT_USER a key (folder) fpc_reginifile_test, and another subkey fpc_reginifile_test in it and inside it creates two subkeys aSection and aOtherSection.
This does not seem okay to me?

Title: Re: TRegIniFile raises exception
Post by: Bart on May 19, 2021, 03:22:00 pm
Please test with fpc trunk.

As a side note: TRegIniFile was created long, long time ago to ease the transition from using ini-files to using the registry (win 3.x -> win 95).
Affter more than 25 year, one might expect developers to use TRegistry directly.

The fpc implementation of TRegInifile has been flawed for many, many years and, while it would build for non windows platforms as well, it was so utterly broken on those platforms that it's use is now deprecated and TRegIniFile (and TRegistrIniFile, which is a pointless wrapper around TRegIniFile) are removed for that platform in the future (fpc 4.0).

Bart
Title: Re: TRegIniFile raises exception
Post by: CM630 on May 20, 2021, 02:20:49 pm
Thanks, since TRegIniFile is gonna be killed, I have rewritten the necessary parts to use TRegistry, using
Code: Pascal  [Select][+][-]
  1. {$ifndef fpc}  //Delphi
  2. ... TRegitryIni
  3. {$ELSE} //Lazarus    
  4. ... TRegistry
  5. {$ENDIF}  
.
Hopefully, that will not make compiling back in Delphi impossible.
Title: Re: TRegIniFile raises exception
Post by: Bart on May 20, 2021, 06:53:17 pm
TRegistry is (supposed to be) Delphi compatible.
So if the Lazarus TRegistry code works OK, it should also work in Delphi.

Bart
Title: Re: TRegIniFile raises exception
Post by: wp on May 20, 2021, 07:07:47 pm
Code: Text  [Select][+][-]
  1. uses
  2.   ...registry;
  3. ...
  4. procedure TForm1.Button1Click(Sender: TObject);
  5. var
  6.   Ini: TRegIniFile;
  7. begin
  8.   Ini := TRegIniFile.Create('fpc_reginifile_test');
  9.   Ini.WriteString('aSection', 'aIdent', 'aValue');
  10.   Ini.WriteSTring('aOtherSection','aOtherIdent','aOtherValue');
  11.   Ini.Free;
  12. end;
It creates in HKEY_CURRENT_USER a key (folder) fpc_reginifile_test, and another subkey fpc_reginifile_test in it and inside it creates two subkeys aSection and aOtherSection.
This does not seem okay to me?

Why do you think this is wrong? TRegIniFile is like an ini file, only inside the registry. When you create a TIniFile you create a file with the name given as parameter; when you create a TRegInifile you create a node inside the registry with the name given as parameter. When you write a string to TInifile you have the first parameter as section inside the ini, and the second parameter is the value below this section. The same with TRegIniFile: it adds a node with the name of the first parameter and an item from the second parameter as value.

I tried your code on Delphi - it does the same as Lazarus.
Title: Re: TRegIniFile raises exception
Post by: Bart on May 20, 2021, 07:20:26 pm
@wp:
Look at the attached file in post #24
The structure added is like:
Code: [Select]
-fpc_reginifile_test
 |-fpc_reginifile_test
   |-aSection
   |-aOtherSection

Notice the double "fpc_reginifile_test".

It should not do that, but it does not do that anymore on my fpc 3.2.2RC1.
CM630 is using fpc 3.2.0, and I do recall that there was such a bug in TRegIniFile, and that it was fixed.
It seems the fix already is in the 3.2.2!

Bart
Title: Re: TRegIniFile raises exception
Post by: wp on May 20, 2021, 07:29:04 pm
Notice the double "fpc_reginifile_test".
Right, I did not notice that...
TinyPortal © 2005-2018