I would like to use GetPrivateProfileSection
(from Windows Kernel32.dll
) from an Inno Setup script, which is kind of a Delphi (Pascal) program.
But I don't know how to create the buffer which is an Out parameter in the function and where it puts the useful information that I want to retrieve.
The input buffer is a pointer to string, which you can declare simply as string
in your function import prototype as long as you'll import proper variant of the function, ANSI or Unicode with respect to which variant of Inno Setup you use.
About the returned buffer, it's a string composed from the key value pairs separated by null characters, which you'll need to process in your code. The following function can read an INI section into the string list e.g.:
[Code]
#ifdef UNICODE
#define AW "W"
#else
#define AW "A"
#endif
function GetPrivateProfileSection(lpAppName: string;
lpReturnedString: string; nSize: DWORD; lpFileName: string): DWORD;
external 'GetPrivateProfileSection{#AW}@kernel32.dll stdcall';
function GetIniSection(
const FileName, Section: string; Strings: TStrings): Integer;
var
BufLen: DWORD;
Buffer: string;
begin
// initialize the result
Result := 0;
// first attempt with 1024 chars; use here at least 3 chars so the function can
// return 1 as a signal of insufficient buffer failure
SetLength(Buffer, 1024);
// first attempt to call the function
BufLen := GetPrivateProfileSection(Section, Buffer, Length(Buffer), FileName);
// check the first call function result
case BufLen of
// the function failed for some reason, that the WinAPI does not provide
0: Exit;
// the function returned value of the passed buffer length - 2
// to indicate that it has insufficient buffer
Length(Buffer) - 2:
begin
// second attempt with the maximum possible buffer length
SetLength(Buffer, 32767);
// this time it should succeed
BufLen :=
GetPrivateProfileSection(Section, Buffer, Length(Buffer), FileName);
// if the returned value is 0, or equals to the passed buffer length - 2,
// then even this call failed, so let's give it up
if (BufLen = 0) or (BufLen = Length(Buffer) - 2) then
Exit;
end;
end;
// the function call succeeded, so let's trim the result
// (note, that it will trim also the two terminating null characters
// from the end of the string buffer)
Buffer := Trim(Buffer);
// now replace all the null characters with line breaks
// so we can easily fill the output string list
StringChangeEx(Buffer, #0, #13#10, True);
// fill the output string list
Strings.Text := Buffer;
// and return the number of items in the output string list
Result := Strings.Count;
end;
A possible usage:
var
Strings: TStringList;
begin
Strings := TStringList.Create;
try
{ if the function returns value greater than 0, it found a non-empty }
{ section called SectionName in the C:\MyFile.ini file }
if GetIniSection('C:\MyFile.ini', 'SectionName', Strings) > 0 then
{ process the Strings somehow }
finally
Strings.Free;
end;
end;