A lightweight .NET library for reading and writing Windows INI files via the native kernel32 API.
- π About
- β¨ Features
- π Getting Started
- π‘ Usage
- π API Reference
- π§ͺ Running Tests
- ποΈ Project Structure
- π€ Contributing
- π License
IniFile is a thin, zero-dependency wrapper around the Windows kernel32.dll Private Profile functions (WritePrivateProfileString, GetPrivateProfileString, GetPrivateProfileInt, etc.).
It lets you read and write classic INI configuration files with a simple, strongly-typed C# API β no parsing logic needed.
β οΈ Note: This library uses Windows-only P/Invoke calls and is not cross-platform.
| Method | Description |
|---|---|
Write |
βοΈ Write a string value to a key in a given section |
ReadString |
π Read a string value (with optional default) |
ReadInt |
π’ Read an integer value (with optional default) |
ReadBool |
β
Read a boolean β supports true/false, 1/0, yes/no |
GetAllSections |
π List all section names in the file |
GetAllDataSection |
π List all key=value pairs in a section |
DeleteKey |
ποΈ Remove a specific key from a section |
DeleteSection |
π§Ή Remove an entire section and its keys |
KeyExists |
π Check whether a key exists in a section |
- OS: Windows 10 / 11 or Windows Server 2016+
- SDK: .NET 10 SDK or later
- Language: C# 14
dotnet add package Laileb.IniFile
Or via the Package Manager Console in Visual Studio:
Install-Package Laileb.IniFile
Or add directly to your .csproj:
<PackageReference Include="Laileb.IniFile" Version="2.0.4" />π‘ Make sure to enable
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>in your.csproj(required byLibraryImportsource generation).
using Ini = IniFile.IniFile;
var ini = new Ini("config.ini");
// Write values
ini.Write("Host", "localhost", "Database");
ini.Write("Port", "5432", "Database");
ini.Write("Debug", "true", "Logging");
// Read values
string host = ini.ReadString("Host", "Database"); // "localhost"
int port = ini.ReadInt("Port", "Database"); // 5432
bool dbg = ini.ReadBool("Debug", "Logging"); // true
string miss = ini.ReadString("Missing", "Nope", defaultValue: "N/A"); // "N/A"
// Enumerate
string[] sections = ini.GetAllSections(); // ["Database", "Logging"]
string[] entries = ini.GetAllDataSection("Database"); // ["Host=localhost", "Port=5432"]
// Check & delete
bool exists = ini.KeyExists("Host", "Database"); // true
ini.DeleteKey("Host", "Database");
ini.DeleteSection("Logging");π See the full working demo in examples/IniFile.Example/Program.cs.
public IniFile(string filePath)Creates a new instance bound to the given file path. The path is resolved to an absolute path internally. Throws ArgumentException if the path is null, empty, or whitespace.
| Property | Type | Description |
|---|---|---|
FilePath |
string |
The fully-qualified path to the INI file. |
public bool Write(string key, string? value, string? section = null)Writes a string value. Returns true on success. Creates the file, section, and key if they don't exist. When section is omitted or null, the wrapper uses an empty section name, which Windows serializes as [].
public string ReadString(string? key, string? section = null, string defaultValue = "", int bufferSize = 1024)Returns the value for the key, or defaultValue if not found. When section is omitted or null, key reads use an empty section name, which Windows serializes as []. Passing null for key preserves the native enumeration behavior: key names for a section, or section names when both key and section are null.
public int ReadInt(string key, string? section = null, int defaultValue = -1)Returns the integer value for the key, or defaultValue if the key is not found. Malformed numeric values follow the native GetPrivateProfileInt parsing behavior and may return 0 instead of defaultValue. When section is omitted or null, the wrapper uses an empty section name, which Windows serializes as [].
public bool ReadBool(string key, string? section = null, bool defaultValue = false)Returns true for "true", "1", "yes"; false for "false", "0", "no" (case-insensitive). Returns defaultValue for anything else. When section is omitted or null, the wrapper uses an empty section name, which Windows serializes as [].
public string[] GetAllSections(int bufferSize = 32768)Returns an array of all section names. Returns an empty array if the file has no sections.
public string[] GetAllDataSection(string section, int bufferSize = 32768)Returns an array of "key=value" strings for every entry in the given section.
public bool DeleteKey(string key, string? section = null)Removes a key and its value. Returns true on success. When section is omitted or null, the wrapper uses an empty section name, which Windows serializes as [].
public bool DeleteSection(string? section = null)Removes an entire section. Returns true on success. When section is omitted or null, the wrapper deletes the empty [] section.
public bool KeyExists(string key, string? section = null)Returns true if the key exists in the section (including keys with empty values). When section is omitted or null, the wrapper uses an empty section name, which Windows serializes as [].
dotnet testTests are located in tests/IniFile.Tests/ and use xUnit. They create temporary INI files in the system temp directory and clean up after each run.
IniFile/
βββ π src/
β βββ π IniFile/ # Library source
β βββ π IniFile.cs
β βββ π IniFile.csproj
βββ π tests/
β βββ π IniFile.Tests/ # xUnit tests
β βββ π IniFileTests.cs
β βββ π IniFile.Tests.csproj
βββ π examples/
β βββ π IniFile.Example/ # Console demo app
β βββ π Program.cs
β βββ π IniFile.Example.csproj
βββ π Directory.Build.props # Shared build settings
βββ π Directory.Packages.props # Central package management
βββ π IniFile.slnx # Solution file
βββ π README.md
Contributions are welcome! To get started:
- π΄ Fork the repository
- πΏ Create a feature branch (
git checkout -b feature/my-feature) - βοΈ Make your changes and add tests
- β
Run
dotnet testto verify everything passes - π¬ Open a Pull Request
This project is licensed under the MIT License.