Im trying to load my ini file with basic settings called settings.ini:
[settings]
protocol=http
ip=localhost
port=2001
Then i do (the function is marked as [async]):
function TDataModule1.ReadIniFile(const FileName, Section, Key: string): string;
var
IniFile: TMiletusINIFile;
begin
Result := 'error';
WriteLn('Entered read ini');
try
IniFile := TMiletusINIFile.Create(FileName);
try
if TAwait.ExecP<Boolean>(IniFile.SectionExists(Section)) then
begin
WriteLn('Found section');
if TAwait.ExecP<Boolean>(IniFile.ValueExists(Section, Key)) then
begin
Result := TAwait.ExecP<String>(IniFile.ReadString(Section, Key, Result));
end
else
raise Exception.CreateFmt('Key "%s" not found in section "%s"', [Key, Section]);
end
else
raise Exception.CreateFmt('Section "%s" not found', [Section]);
finally
IniFile.Free;
end;
except
on E: Exception do
begin
Writeln(Format('Error reading INI file: %s', [E.Message]));
end;
end;
end;
I have placed my inifile in: root of the project, TMSWeb/Debug and Win32/Debug
You haven't said in what way does this not work (e.g. how are you using this method) but if you are marking a method as async, then you are creating a promise despite the string return value.
Here I have explained this in a bit more detail: Hashing and Cryptography in WEB Core - #14 by Tunde
It might be confusing at first but once the idea gets accross, you'll be able to navigate async-await better.
What you can do is wrap your ReadIniFile as a promise, resolve with the string result and then from other async methods you can await your ReadIniFile with a string return value.
That unfortunately doesn't provide more information. What are you passing to your ReadIniFile method as a parameter? Because the core of your code should work as long as you pass the correct path, section and key to it. The following works here, it's based on your code but I wrapped it into a promise as I mentioned it should be:
TForm1 = class(TMiletusForm)
WebButton1: TWebButton;
WebMemo1: TWebMemo;
[async]
procedure WebButton1Click(Sender: TObject);
function ReadIni(AFileName: string; ASection: string; AKey: string): TJSPromise;
private
{ Private declarations }
public
{ Public declarations }
end;
function TForm1.ReadIni(AFileName, ASection, AKey: string): TJSPromise;
begin
Result := TJSPromise.new(procedure (AResolve, AReject: TJSPromiseResolver) async
var
IniFile: TMiletusINIFile;
res: string;
begin
try
res := 'error';
IniFile := TMiletusINIFile.Create(AFileName);
try
if TAwait.ExecP<Boolean>(IniFile.SectionExists(ASection)) then
begin
WriteLn('Found section');
if TAwait.ExecP<Boolean>(IniFile.ValueExists(ASection, AKey)) then
begin
res := TAwait.ExecP<String>(IniFile.ReadString(ASection, AKey, res));
AResolve(res);
end
else
raise Exception.CreateFmt('Key "%s" not found in section "%s"', [AKey, ASection]);
end
else
raise Exception.CreateFmt('Section "%s" not found', [ASection]);
finally
IniFile.Free;
end;
except
on E: Exception do
begin
AReject(Format('Error reading INI file: %s', [E.Message]));
end;
end;
end);
end;
procedure TForm1.WebButton1Click(Sender: TObject);
var
res: string;
begin
res := TAwait.ExecP<string>(ReadIni('.\settings.ini', 'settings', 'ip'));
WebMemo1.Lines.Add(res);
end;
Just to avoid further misunderstanding, can you confirm that you are using the code in a Miletus application? Because it won't work for a normal WEB application.
Assuming you are using a Miletus application, which OS are you targeting? Could be a platform specific issue that we need to take a look at, we only tested on Windows 10.
If you can upload a small sample project that reproduces this issue that would also help.
If your question is to load from an INI file stored on hard disk, this functionality does not exist at this moment. In web apps, the best practice is to use local storage. You won't have access to the local drive without a user prompt anyway (for obvious security reasons).