Sometimes, Windows would redirected it to under user profile, to “\AppData\Roaming\Microsoft\Windows” – anything there, for the user account executing that process?
John_Van_De_Giessen
he said it right for a single user
when the application starts up so GetCurrentDirectory into a separate string
Use the string to save and load the *.INI file of yours
if you have many users, so you need current user directory and make a sub folder for the *.INI file
you can put many sperate users in your many named *.INI files in by the application’s GetCurrentDirectory windows has gone crazy with options
its about piratical stuff
Be wary of what Windows User Account control does - you write to Application.Exename but if this is under C:\Program Files then it is written to some obscure directory perhaps accessible to your code via the directory link you listed while the code runs but really stored in an obscure path such as listed by one of the other respondents. Windows say to put it under places like C:\ProgramData but they restrict access there too. Worse still, when you install your software using an installer, the installer privelages can substitute for your privelages and result in software that works for you but no one else.
Yea it usually does wired stuff with INI placement.
I think Delphi (in the past, maybe now) attempts to create it in the Programs directory, which has NO write access generally.
Do windows redirects it to a virtual "Programs directory” directory but actually in "C:\users"
Anyway, I discovered that the dull path is best to be put in the “.ini” file creation.
Below is the code I utilise (for many years since Windows stopped allowing write to the Programs directory). It gets a directory in “App Data” and I place it in my own sub-directory (“HakaSoft”)
FUNCTION GetLocalAppData:STRING;
BEGIN
SetLength(Result,MAX_PATH);
SHGetSpecialFolderPath(0,PChar(Result),$001C,false);
SetLength(Result,StrLen(PChar(Result)));
IF (Result<>‘’) THEN
BEGIN
Result:= IncludeTrailingBackslash(Result)+'HakaSoft';
// USe your name in replace of HakaSoft above
ForceDirectories(Result);
END
ELSE Result:= IncludeTrailingBackslash(ExtractFilePath(Paramstr(0)));
END;
procedure TMainWin.FormCreate(Sender: TObject);
var NavIni:TIniFile;
begin
// IniFile
NavIni:= TIniFile.Create(GetLocalAppData+‘LOS.ini’);
tt:= NavIni.ReadInteger(‘Window’,‘Top’,-1);
tl:= NavIni.ReadInteger(‘Window’,‘Left’,-1);
tw:= NavIni.ReadInteger(‘Window’,‘Width’,-1);
th:= NavIni.ReadInteger(‘Window’,‘Height’,-1);
NavIni.Free;
i.e. Result:= IncludeTrailingBackslash(Result)+'HakaSoft';
not Result:= IncludeTrailingBackslash(Result)+‘HakaSoft’;
As below:
FUNCTION GetLocalAppData:STRING;
BEGIN
SetLength(Result,MAX_PATH);
SHGetSpecialFolderPath(0,PChar(Result),$001C,false);
SetLength(Result,StrLen(PChar(Result)));
IF (Result<>‘’) THEN
BEGIN
Result:= IncludeTrailingBackslash(Result)+'HakaSoft';
ForceDirectories(Result);
END
ELSE Result:= IncludeTrailingBackslash(ExtractFilePath(Paramstr(0)));
END;
Well, actually, source code should be marked specially:
procedure LaLaLand
begin
something := useful * here;
end;
Using the “left angle bracket + slash + right angle bracket” (hint says: Preformatted text) tool button above the message edit, any already selected text will look like the above.