limelect 48 Posted March 18, 2022 Crazy but true. I have a solution moved to TMemIniFile but need your help to understand var TIFFileini: TIniFile; begin TIFFileini:= TIniFile;.Create('ComPortServer.ini'); if TIFFileini.SectionExists('Tst0') then Label1.Caption:='yes' else Label1.Caption:='No'; INI file [Tst0] HardFlow=0 ANY IDEA WHY I GET NO ???????????? D10.2.3 never had such a problem Share this post Link to post
Uwe Raabe 2057 Posted March 18, 2022 Does it help when you add the complete path to the file instead only the file name? 1 Share this post Link to post
Der schöne Günther 316 Posted March 18, 2022 Doesn't TIniFile fall back to some extremely ancient Windows methods? I would have expected an encoding problem with your text file. Can you provide the original .ini file? Share this post Link to post
limelect 48 Posted March 18, 2022 (edited) @Der schöne Günther 2 lines this is the INI Crazy as it sounds I gave a full path I got yes then I deleted the full path I got yes. Well now I am buffeled Is it Delphi that gives me a beautiful day? What I think there might have been hidden characters although no reason for it Edited March 18, 2022 by limelect Share this post Link to post
Lajos Juhász 293 Posted March 18, 2022 23 minutes ago, limelect said: Is it Delphi that gives me a beautiful day? What I think there might have been hidden characters although no reason for it ..or just the current folder was not the one where the ini file is located. Share this post Link to post
PeterBelow 238 Posted March 18, 2022 16 minutes ago, limelect said: @Der schöne Günther 2 lines this is the INI Crazy as it sounds I gave a full path I got yes then I deleted the full path I got yes. Well now I am buffeled Is it Delphi that gives me a beautiful day? What I think there might have been hidden characters although no reason for it If you don't use a full path the program will look for the file in whatever it considers to be the "current directory" at the moment. That can depend on many things, e.g. on how you start the program, and it can even change during the program run, e.g. by using a file dialog. If you do want to keep your sanity (and control of the situation) always use full pathes. A program should use a specific folder for its files, e.g. one created under TPath.GetDocumentsPath or TPath.GetHomePath. Share this post Link to post
Attila Kovacs 629 Posted March 18, 2022 25 minutes ago, limelect said: then I deleted the full path I got yes. I'd bet your program saved it at the end without the full path, so you just have copied the right one to the right place ? 1 Share this post Link to post
limelect 48 Posted March 18, 2022 1. current folder is where execution is. 2 first I checked in the IDE 3 then I executed outside the ide (in the folder) 4 a few hours it was NO. it seems something with Windows as this is the only explanation since now it is OK. Or Delphi compilation no other explanation. 1 Share this post Link to post
limelect 48 Posted March 18, 2022 Let's just clarify the point I am with Delphi since #1 and have never seen such a thing. Share this post Link to post
qubits 20 Posted March 18, 2022 probably a windows thing.. check inside profiles like, Users\YourUserName\AppData\Local\VirtualStore\Program Files (x86)\ ive seen windows move things.. Share this post Link to post
David Heffernan 2345 Posted March 18, 2022 TIniFile uses deprecated Windows APIs that haven't been safe to use since 32 bit Windows was release nearly 30 years ago. So yeah use TMemIniFile which has a native Delphi INI parser that won't cause you such trouble. Never ever use TIniFile is the rule here. Share this post Link to post
Remy Lebeau 1398 Posted March 18, 2022 (edited) 3 hours ago, PeterBelow said: If you don't use a full path the program will look for the file in whatever it considers to be the "current directory" at the moment. That is actually incorrect in the case of TIniFile. Internally, it uses the Win32 PrivateProfile API, and if you don't specify a full path then it will use the Windows folder, not the calling process' working directory: Quote If the lpFileName parameter does not contain a full path and file name for the file, WritePrivateProfileString searches the Windows directory for the file. If the file does not exist, this function creates the file in the Windows directory. If lpFileName contains a full path and file name and the file does not exist, WritePrivateProfileString creates the file. The specified directory must already exist. This is not the case with TMemIniFile. Quote If you do want to keep your sanity (and control of the situation) always use full pathes. Agreed. Edited March 18, 2022 by Remy Lebeau 1 Share this post Link to post
corneliusdavid 214 Posted March 18, 2022 There are lots of other good suggestions here but I'll just add one thing to check. By default, Delphi projects set their Output directory to .\$(Platform)\$(Config) meaning that while your project (and possibly your .INI file) are in a folder like \MyProject, the .EXE would be in \MyProject\Win32\Debug (for a Win32 app compiled with the Debug configuration). When it runs, it's running from \MyProject\Win32\Debug and therefore doesn't see the .INI file two folders up. When you specified the full path, it likely saved it (as @Attila Kovacspointed out) so that next time it ran, it found the second copy of the .INI file. This has caught me a few times and now I always check the project's Output directory setting. The possible reason you haven't seen this before is either you had set the Output directory (and forgot about it) or you were using a much earlier version of Delphi (before multiple platforms) that left .EXEs in the same folder as the project. Share this post Link to post
corneliusdavid 214 Posted March 18, 2022 1 minute ago, Remy Lebeau said: if you don't specify a full path then it will use the Windows folder, not the calling process' working directory Oh, that's right--I forgot about that! I often prepend the filename with the application's path in which case the above scenario I described happens. Share this post Link to post
Steven Kamradt 20 Posted March 19, 2022 Another trick is to use ExtractFilePath(paramstr(0)) to get the executable location. It really depends on your use case and how the executable is deployed. using your example above, this would be: TIFFileini:= TIniFile.Create(ExtractFilePath(paramstr(0))+'ComPortServer.ini'); Share this post Link to post
Remy Lebeau 1398 Posted March 21, 2022 On 3/18/2022 at 6:36 PM, Steven Kamradt said: Another trick is to use ExtractFilePath(paramstr(0)) to get the executable location. It really depends on your use case and how the executable is deployed. It is really not a good idea to store your data files in your program's installation folder, especially if it is installed under ProgramFiles. Windows has dedicated folders set aside for storing data files, you should create your own subfolder underneath them, such as %APPDATA%\MyApp, etc. Share this post Link to post
dummzeuch 1505 Posted March 21, 2022 1 hour ago, Remy Lebeau said: It is really not a good idea to store your data files in your program's installation folder, especially if it is installed under ProgramFiles. That depends. Our internal programs all do that. They aren't installed under program files, though. 3 Share this post Link to post
Fr0sT.Brutal 900 Posted March 22, 2022 14 hours ago, Remy Lebeau said: It is really not a good idea to store your data files in your program's installation folder, especially if it is installed under ProgramFiles. Windows has dedicated folders set aside for storing data files, you should create your own subfolder underneath them, such as %APPDATA%\MyApp, etc. Classic holy war "self-contained bundle aka portable vs scattered installation according to OS rules". I prefer the first. Ideally both options should be available to have to choose from Share this post Link to post
dummzeuch 1505 Posted March 22, 2022 51 minutes ago, Fr0sT.Brutal said: Classic holy war "self-contained bundle aka portable vs scattered installation according to OS rules". I prefer the first. Ideally both options should be available to have to choose from That's why the mentioned internal programs support redirection with a section like this: [redirect] inifile=some\path\to\another\inifile (and usually nothing else) This will redirect the access to the inifile to a different file. It supports environment variables in the file name and the name can be relative to the main ini file. It gets even more flexible by allowing to redirect sections or even single entries. I'm using something similar in dzPrepBuild to keep version information in sync between several executables belonging to the same project, e.g. GExperts: [Version Info] AutoIncBuild=0 Build=redirect:..\..\SVN_Version.ini,SVN,HighestVersion MajorVer=redirect:..\GExperts_version.ini,Version Info,MajorVer MinorVer=redirect:..\GExperts_version.ini,Version Info,MinorVer Release=redirect:..\GExperts_version.ini,Version Info,Release [Version Info Keys] FileVersion=1.3.4.0 FileDescription=GExperts for Delphi 2007 OriginalFilename={ProjectName}.dll InternalName=GExperts for Delphi 2007 Comments=redirect:..\GExperts_version.ini,Version Info Keys,Comments CompanyName=redirect:..\GExperts_version.ini,Version Info Keys,CompanyName LegalCopyright=redirect:..\GExperts_version.ini,Version Info Keys,LegalCopyright LegalTrademarks=redirect:..\GExperts_version.ini,Version Info Keys,LegalTrademarks ProductName=redirect:..\GExperts_version.ini,Version Info Keys,ProductName ProductVersion=redirect:..\GExperts_version.ini,Version Info Keys,ProductVersion Of course if is that is done excessively you will end up with an unmaintainable set of files. 1 Share this post Link to post
PeterBelow 238 Posted March 22, 2022 16 hours ago, dummzeuch said: That depends. Our internal programs all do that. They aren't installed under program files, though. That requires write access for the user account to the folder the program is in, and that makes it vulnerable to malware attacks. Share this post Link to post
dummzeuch 1505 Posted March 22, 2022 1 hour ago, PeterBelow said: That requires write access for the user account to the folder the program is in, and that makes it vulnerable to malware attacks. Yes, I'm aware of that. Share this post Link to post
corneliusdavid 214 Posted March 22, 2022 There's no one perfect way that everyone should use. Personally, I use two different approaches: If a program uses a database, I keep all the configuration settings in there except for the path/server/port of what is needed to connect to the database and those are set in an .INI file in the same folder as the application during installation. The installer has admin rights so it can create files under Program Files, and the database settings should never be changed--except by an administrator. In this case the INI filename is simply: ChangeFileExt(Application.ExeFilename, '.INI') If a program doesn't use a database and has several options to configure when the program is in use by regular users, the INI filename is: FAppDataPath := TPath.Combine(TPath.GetPublicPath, ChangeFileExt(ExtractFileName(Application.ExeName), EmptyStr)); ForceDirectories(FAppDataPath); FAppConfigFilename := TPath.Combine(FAppDataPath, ChangeFileExt(ExtractFileName(Application.ExeName), '.ini')); This puts the file in a folder under %ProgramData%\MyApp making it global for any users on the computer. 1 Share this post Link to post
Fr0sT.Brutal 900 Posted March 23, 2022 On 3/22/2022 at 11:34 AM, dummzeuch said: It gets even more flexible by allowing to redirect sections or even single entries. Pretty smart! File redirect is like Git-config's include but pulling specific sections is a more powerful feature. 17 hours ago, corneliusdavid said: If a program uses a database, I keep all the configuration settings in there except for the path/server/port of what is needed to connect to the database This is good but requires an account for each user. Moreover, in theory there could be some settings that affect pre-connect state Share this post Link to post
PeterBelow 238 Posted March 23, 2022 22 hours ago, dummzeuch said: Yes, I'm aware of that. Are you also aware of the legal repercussions that may have? It's of course OK if you only use the program on your own computers, but if you sell it to clients it opens you up to litigation. If the program is infected on the client's computer and then causes damage there the client could sue you, since the program does not follow accepted safety standards for software. Depends on your countries legislation, of course. Share this post Link to post