Introduction
I found several snippets of code on the internet that uses the function GetPrivateProfileString
from KERNEL32.DLL, but none of them offered the functionality I required. So, I created a C# class, INI, which exposes this function, utilizing the best elements from these snippets of code.
First, create a new C# Console Application. Then, add a new C# class. I called mine ReadINI.cs. Now, copy and paste the first section of code into this new class. Then, copy the second section of code into the C# Main Console Application class. Now, create a basic INI file on the root of C:\, called Test.ini.
[TestSectionHeader1]
TestKey11 = TestValue11
TestKey12 = TestValue12
TestKey13 = TestValue13
TestKey14 = TestValue14
TestKey15 = TestValue15
[TestSectionHeader2]
TestKey21 = TestValue21
TestKey22 = TestValue22
TestKey23 = TestValue23
TestKey24 = TestValue24
TestKey25 = TestValue25
[TestSectionHeader3]
TestKey31 = TestValue31
TestKey32 = TestValue32
TestKey33 = TestValue33
TestKey34 = TestValue34
TestKey35 = TestValue35
The Class
using System;
using System.Text;
using System.Runtime.InteropServices;
namespace INI
{
public class IniFileName
{
[DllImport ("kernel32")]
static extern int GetPrivateProfileString (string Section, string Key,
string Value, StringBuilder Result, int Size, string FileName);
[DllImport ("kernel32")]
static extern int GetPrivateProfileString (string Section, int Key,
string Value, [MarshalAs (UnmanagedType.LPArray)] byte[] Result,
int Size, string FileName);
[DllImport ("kernel32")]
static extern int GetPrivateProfileString (int Section, string Key,
string Value, [MarshalAs (UnmanagedType.LPArray)] byte[] Result,
int Size, string FileName);
public string path;
public IniFileName(string INIPath)
{
path = INIPath;
}
public string[] GetSectionNames()
{
for (int maxsize = 500; true; maxsize*=2)
{
byte[] bytes = new byte[maxsize];
int size = GetPrivateProfileString(0,"","",bytes,maxsize,path);
if (size < maxsize -2)
{
string Selected = Encoding.ASCII.GetString(bytes,0,
size - (size >0 ? 1:0));
return Selected.Split(new char[] {'\0'});
}
}
}
public string[] GetEntryNames(string section)
{
for (int maxsize = 500; true; maxsize*=2)
{
byte[] bytes = new byte[maxsize];
int size = GetPrivateProfileString(section,0,"",bytes,maxsize,path);
if (size < maxsize -2)
{
string entries = Encoding.ASCII.GetString(bytes,0,
size - (size >0 ? 1:0));
return entries.Split(new char[] {'\0'});
}
}
}
public object GetEntryValue(string section, string entry)
{
for (int maxsize = 250; true;maxsize *=2)
{
StringBuilder result = new StringBuilder(maxsize);
int size = GetPrivateProfileString(section,entry,"",
result, maxsize,path);
if (size < maxsize -1)
{
return result.ToString();
}
}
}
}
}
Now, for the Main C# Console Application class.
I have included two routines for gathering information. The first is a foreach
loop which is in the main body of the code. The second is commented out at the end of the code, and uses the IEnumerator
function. Both produce the same results.
using System;
using System.Collections;
using INI;
namespace MainApp
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
IniFileName INI = new INI.IniFileName("C:\\test.ini");
try
{
string [] SectionHeader = INI.GetSectionNames();
if (SectionHeader != null)
{
foreach (string SecHead in SectionHeader)
{
Console.WriteLine(SecHead);
string [] Entry = INI.GetEntryNames(SecHead);
if (Entry != null)
{
foreach (string EntName in Entry)
{
Console.WriteLine(" {0} = {1}", EntName,
INI.GetEntryValue(SecHead,EntName));
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("Error: "+ ex);
}
Console.ReadLine();
}
}
}
And, that's it. Run the application to display your results.
Points of interest
I have also included the code in zip format for you. I hope this is of help to someone. This is my first posting, so please be gentle.. Can I also take this opportunity to thank all those other C# Guru's for their code snippets that helped me complete mine?