INI File Not Found
Delphi Programming Language
Severity: MinorWhat Does This Error Mean?
Delphi's TIniFile does not raise an exception if the INI file does not exist — it silently returns the default value you provide. However, problems arise when code does not provide defaults, uses wrong file paths, or tries to write to a location where the application has no permission. The fix is to always provide defaults when reading and to store INI files in a writable location.
Affected Models
- Delphi 10.4 Sydney
- Delphi 11 Alexandria
- Delphi 12 Athens
- Embarcadero RAD Studio
- Free Pascal / Lazarus
Common Causes
- Reading a key that does not exist and not providing a default value, causing unexpected empty string or zero results
- Storing the INI file in the application folder under Program Files, where Windows does not allow writes
- Using a relative path for the INI file, which resolves differently depending on how the application is launched
- The INI file was deleted or never created and the code assumes it always exists
- File permission errors when trying to write the INI file (read-only filesystem or UAC restrictions)
How to Fix It
-
Store the INI file in the user's AppData folder, not the application folder. Use: IniPath := IncludeTrailingPathDelimiter(GetEnvironmentVariable('APPDATA')) + 'YourAppName\settings.ini';
Writing to Program Files requires elevation on modern Windows. AppData is always writable by the current user.
-
Always use absolute paths. Get the path dynamically rather than hardcoding it: ExtractFilePath(Application.ExeName) + 'settings.ini' works for portable apps in user-writable locations.
Relative paths depend on the current working directory, which varies by how the application is launched.
-
Always pass default values to every Read call: Value := Ini.ReadString('Section', 'Key', 'DefaultValue'). TIniFile returns the default if the section or key is missing.
If no default is provided (empty string), missing keys silently return empty strings. This can cause logic errors if the code does not check for empty returns.
-
Check if the INI file exists at startup and create a default one if it does not: if not FileExists(IniPath) then WriteDefaultSettings(IniPath). This makes the first-run experience predictable.
Creating a default INI file on first run also serves as a template showing users what settings are available.
-
Use TMemIniFile instead of TIniFile for better behavior. TMemIniFile reads the whole file into memory at once, and is faster for multiple read operations. It also fails more explicitly if the file cannot be read.
TIniFile calls the Windows INI API for every read/write. TMemIniFile loads the file once and works with an in-memory copy, then writes back on UpdateFile.
When to Call a Professional
TIniFile behavior differs between reading (silent defaults) and writing (silent failures on permission errors). Always use the AppData folder for INI files: ExpandConstant('%APPDATA%') or SysUtils.GetEnvironmentVariable('APPDATA'). Always provide meaningful defaults for every ReadString/ReadInteger/ReadBool call.
Frequently Asked Questions
Does TIniFile raise an exception if the file does not exist?
No. TIniFile silently creates the file on first write and silently returns defaults on reads if the file does not exist. This silent behavior is convenient but can hide bugs where the file path is wrong. Use FileExists to explicitly verify the path when you need to detect a missing file.
Why does my INI file save correctly during development but not on the user's machine?
Development machines often run with administrator rights, allowing writes anywhere. User machines run as standard users who cannot write to Program Files. Always test your application running as a standard user to catch permission issues before deployment.
Is TIniFile the best way to store application settings in Delphi?
TIniFile is fine for simple settings in portable or small applications. For Windows applications, TRegistry (using HKEY_CURRENT_USER) integrates better with Windows settings management. For complex settings or multiple users, a small database or JSON/XML file with a dedicated parser may be more appropriate.