|
|
Comments and Discussions
|
|
 |
|

|
my long time issue of saving config solved
|
|
|
|

|
for me it dont work on Windows 8 the Program don't create the ini file
|
|
|
|

|
i am using windows 7. please check the file path . use absolute path like @c:\temp.ini. if you put only file name then it's not creating ini file.
|
|
|
|

|
The Closing event is obsolete in the .NET Framework version 2.0; use the FormClosing event in example instead.
|
|
|
|

|
this is awesome..very comprehensive...thanks...
and easy to use..Cheers!
|
|
|
|

|
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.IO;
public class IniFile
{
[DllImport("KERNEL32.DLL", EntryPoint = "GetPrivateProfileStringW",
SetLastError = true,
CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
private static extern int GetPrivateProfileString(
string lpSection,
string lpKey,
string lpDefault,
StringBuilder lpReturnString,
int nSize,
string lpFileName);
[DllImport("KERNEL32.DLL", EntryPoint = "WritePrivateProfileStringW",
SetLastError = true,
CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
private static extern int WritePrivateProfileString(
string lpSection,
string lpKey,
string lpValue,
string lpFileName);
private string _path = "";
public string Path {
get
{
return _path;
}
set
{
if (!File.Exists(value))
File.WriteAllText(value, "", Encoding.Unicode);
_path = value;
}
}
public IniFile(string INIPath)
{
this.Path = INIPath;
}
public void IniWriteValue(string Section, string Key, string Value)
{
WritePrivateProfileString(Section, Key, Value, this.Path);
}
public string IniReadValue(string Section, string Key)
{
const int MAX_CHARS = 1023;
StringBuilder result = new StringBuilder(MAX_CHARS);
GetPrivateProfileString(Section, Key, "", result, MAX_CHARS, this.Path);
return result.ToString();
}
}
|
|
|
|

|
Clear structured an easy to use!
|
|
|
|

|
Thankx Dear...!!! It helps me lot...!!!
But i hav one query....if i want to use <> this for defining Section i.e.
how to read this test.ini file?
=
|
|
|
|
|

|
My piece of code in VB.Net
<Runtime.InteropServices.DllImport("kernel32.dll", CharSet:=Runtime.InteropServices.CharSet.Ansi, SetLastError:=True)> _
Private Function WritePrivateProfileString(Section As String, Key As String, Value As String, FilePath As String) As Long
End Function
<Runtime.InteropServices.DllImport("kernel32.dll", CharSet:=Runtime.InteropServices.CharSet.Ansi, SetLastError:=True)> _
Private Function GetPrivateProfileString(Section As String, Key As String, DefaultValue As String, Result As System.Text.StringBuilder, Size As Integer, FilePath As String) As Long
End Function
|
|
|
|
|

|
It solved my problem and useful article..
|
|
|
|

|
It solved my problem and useful article..
|
|
|
|
|
|
|

|
///
/// see IniWriteValue, but write an integer
///
public void IniWriteInt(string section, string key, int value)
{
String s = Convert.ToString(value);
IniWriteValue(section, key, s);
}
///
/// see IniReadValue, but read as an integer.
///
public int IniReadInt(string section, string key)
{
String s= IniReadValue(section,key);
String exceptionMsg = "string could not be converted to an int";
int value;
try
{
value = Convert.ToInt32(s);
}
catch (FormatException ex)
{
throw new IniFileException(exceptionMsg, ex);
}
catch (OverflowException ex)
{
throw new IniFileException(exceptionMsg, ex);
}
return value;
}
public class IniFileException : Exception
{
//TODO put this class in it's own file.
public IniFileException(String message)
: base(message)
{
}
public IniFileException(string message, Exception ex)
: base(message, ex)
{
}
}
|
|
|
|

|
This is way overcomplicated. Try this instead:
public class IniFile
{
public string path;
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
public IniFile(string INIPath)
{
path = INIPath;
}
public void IniWriteValue(string Section, string Key, string Value)
{
WritePrivateProfileString(Section, Key, Value, this.path);
}
public string IniReadValue(string Section,string Key, string Def)
{
StringBuilder temp = new StringBuilder(255);
int i = GetPrivateProfileString(Section, Key, (def != null ? def : string.Empty), temp, 255, this.path);
return temp.ToString();
}
public void IniWriteValue(string Section, string Key, int Value)
{
IniWriteValue(Section, Key, Value.ToString());
}
public int IniReadValue(string section, string key, int? def)
{
string s = ReadValue(section, key, (def != null ? def.ToString() : null));
int i = 0;
if (int.TryParse(s, out i))
return i;
else
throw new IniFileException("Tried to retrieve invalid value type from ini.");
}
}
public class IniFileException : Exception
{
public IniFileException(string Message)
: base(Message)
{
}
}
Your stack trace will now have everything you need, and you can get rid of the messy try...catch...throw. There's no need to include an InnerException as part of the newly thrown IniFileException, as no other Exception has been generated yet.
You have room for a default value now, and you're using overloads instead of multiple alternately named, similar functions. This is a more standardized method for this sort of endeavor.
An int.TryParse is just a hair slower than a Convert.ToInt32 but the overhead this method will save you on failure is well worth it. Additionally, it's the preferred method for conversion.
|
|
|
|

|
Hi md5sum, thx for your insight here!
Allthough the methodes I posted
do what they supposed to, I agree
with overloading, the methods you posted.
I made changes accordingly. However I am not sure
about using tryparse. if reading from ini would fail because
the number is too high to be parsed or there is an invalid
format, then you can't distinqush between those cases from
iniexception anymore.
|
|
|
|

|
I suppose if you need that much granularity in your error reporting, then it would be necessary to report it that way. However, I would probably instead change:
throw new IniFileException("Tried to retrieve invalid value type from ini.");
to:
throw new IniFileException(string.Format("Tried to retrieve invalid value type from ini. Tried to convert \"{0}\" to int.", s));
in order to introduce the same level of reporting the cause of the error without the granularity of exception types generated through the alternate, multiple catch method. I can't imagine an instance where I would need (for myself or my users) to have more than a single exception generated from this block of code. In general though, if you absolutely want to keep the InnerException and specifically NOT use a TryParse, I would limit it to simply:
try
{
i = Convert.ToInt32(s);
}
catch (Exception ex)
{
throw new IniFileException("Tried to retrieve invalid value type from ini.", ex);
}
and add the following constructor back to the IniFileException class:
public IniFileException(string Message, Exception ex)
: base(Message, ex)
{
}
This will keep your granularity in exception types, rethrowing the wrapped exception with an appropriate InnerException. I just can't imagine why you would want that in this particular case.
modified on Friday, January 7, 2011 2:38 PM
|
|
|
|

|
good class
but where is the ReadValue() method??
EDIT:
is IniReadValue()
Thanks for the code!!
|
|
|
|

|
The code will only be able to retrieve strings that are 254 characters or less (to fit in a null-terminated buffer of 255 characters), otherwise they will be truncated.
int i = GetPrivateProfileString(Section,Key,"",temp, 255, this.path);
|
|
|
|

|
Found the same problem. May be the author should easy fix this bug?
|
|
|
|

|
don't explain exactly where tu put the items. nice help, but to those who has some knoledge in C# already
|
|
|
|

|
The solution work fine with one time input.
But problem come when read/write multiple line to the ini.
Every new record only replace the previous record.
Any solution to solve it?
|
|
|
|

|
CAN BE DONE THROUGH
FILE.Writeallline()
and can be read through file.readallline
file is beeter than stream read and stream write because stream write is used once if we used more than once it overwrite thats file is beeter option because it does not overwrite and there is no use of close0, flush in file .
|
|
|
|

|
Can you elaborate on this?
How would we implement File.WriteAllLines with the class?
|
|
|
|

|
Hey, nice job. I just posted an implementation I wrote a while ago on my site. It doesn't provide an interface to write to the Ini though just read from it. Take a look at it and let me know what you think.
http://www.crowsprogramming.com/archives/95
|
|
|
|

|
I added a IniGetCategories() and IniGetKeys() functions to the class based on a post I read at How to access INI Files in C# .NET - By Gerhard Stephan[^]
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Collections.Generic;
namespace Ini
{
public class IniFile
{
public string path;
[DllImport("KERNEL32.DLL", EntryPoint = "GetPrivateProfileStringW",
SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)]
private static extern int GetPrivateProfileString(
string lpAppName,
string lpKeyName,
string lpDefault,
string lpReturnString,
int nSize,
string lpFilename);
[DllImport("KERNEL32.DLL", EntryPoint="WritePrivateProfileStringW",
SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)]
private static extern int WritePrivateProfileString(
string lpAppName,
string lpKeyName,
string lpString,
string lpFilename);
public IniFile(string INIPath)
{
path = INIPath;
}
public void IniWriteValue(string Section,string Key,string Value)
{
WritePrivateProfileString(Section,Key,Value,this.path);
}
public string IniReadValue(string Section,string Key)
{
string result = new string(' ', 255);
GetPrivateProfileString(Section, Key, "", result, 255, this.path);
return result;
}
public List<string> IniGetCategories()
{
string returnString = new string(' ', 65536);
GetPrivateProfileString(null,null,null,returnString,65536,this.path);
List<string> result = new List<string>(returnString.Split('\0'));
result.RemoveRange(result.Count - 2, 2);
return result;
}
public List<string> IniGetKeys(string category)
{
string returnString = new string(' ', 32768);
GetPrivateProfileString(category, null, null, returnString, 32768, this.path);
List<string> result = new List<string>(returnString.Split('\0'));
result.RemoveRange(result.Count-2,2);
return result;
}
}
}
Hope someone finds this useful!
Ben Ethington
|
|
|
|

|
I thought i would write a quick conversion from INI to Xml based on your additions to this class.
Here is what i came up with
public static void ConvertIni2Xml(string IniFileName, string XmlOutputFileName)
{
if (string.IsNullOrEmpty(XmlOutputFileName))
{
XmlOutputFileName = Path.Combine(Path.GetDirectoryName(IniFileName), String.Format("{0}.xml", Path.GetFileNameWithoutExtension(IniFileName)));
}
IniFile iniFile = new IniFile(IniFileName);
XmlTextWriter xw = null;
try
{
xw = new XmlTextWriter(XmlOutputFileName, Encoding.UTF8);
xw.WriteStartDocument();
xw.WriteStartElement("configuration");
foreach (string categoryName in iniFile.IniGetCategories())
{
xw.WriteStartElement("category");
xw.WriteAttributeString("name", categoryName);
foreach (string keyName in iniFile.IniGetKeys(categoryName))
{
xw.WriteStartElement("setting");
xw.WriteAttributeString("name", keyName);
xw.WriteAttributeString("value", iniFile.IniReadValue(categoryName, keyName));
xw.WriteEndElement();
}
xw.WriteEndElement();
}
xw.WriteEndElement(); xw.WriteEndDocument();
}
catch (Exception)
{
throw;
}
finally
{
if (xw != null)
{
xw.Close();
}
}
}
modified on Tuesday, August 4, 2009 2:35 PM
|
|
|
|

|
Adding to Ben's changes.. here's a method for fetching all the keys and their values together. (e.g. SourceFolder=C:\Windows\Temp, DestinationFolder=E:\Audit\Archives)
public List<string> GetKeysAndValues(string section)
{
List<string> result = new List<string>();
foreach (string key in GetKeys(section))
{
result.Add(key + "=" + ReadValue(section, key));
}
return result;
}
|
|
|
|

|
This is a nice class.
I'm a C# newbie and tried to add some additional methods useful for a project of mine.
public int IniReadValue(string Section, string Key, int DefaultValue)
{
string sTemp = IniReadValue(Section, Key, "");
if (sTemp.Length == 0)
{
return DefaultValue;
}
return Int32.Parse(sTemp);
}
public ulong IniReadValue(string Section, string Key, ulong DefaultValue)
{
string sTemp = IniReadValue(Section, Key, "");
if (sTemp.Length == 0)
{
return DefaultValue;
}
return ulong.Parse(sTemp);
}
public double IniReadValue(string Section, string Key, double DefaultValue)
{
string sTemp = IniReadValue(Section, Key, "");
if (sTemp.Length == 0)
{
return DefaultValue;
}
return double.Parse(sTemp, CultureInfo.GetCultureInfo("en-US").NumberFormat);
}
public bool IniReadValue(string Section, string Key, bool DefaultValue)
{
bool RetVal = DefaultValue;
string sTemp = IniReadValue(Section, Key, "");
if (sTemp.Length == 0)
{
return DefaultValue;
}
if (!bool.TryParse(sTemp, out RetVal))
{
return (Int32.Parse(sTemp) == 0) ? false : true;
}
return RetVal;
}
|
|
|
|

|
But you defined no method to accept third parameter as string: IniReadValue(Section, Key, "")
|
|
|
|

|
It could be accomplished by modifying the original IniReadValue() method and adding a third parameter to provide a default string to be used when the searched key cannot be found.
|
|
|
|

|
I have been using this .ini class for a while in my test apps that I am developing in C#. Recently I have been building web applications using Visual Studio 2008. I have this .ini class imported into my project and it all seems to work just fine when I test the app on my computer(The one that I developed the app on) but when i publish it to the remote web server, the class does not seem to work, it does not even give me an error. are there any changes i need to make to get it to read and write an .ini file on the server that is hosting the applicaiton?
|
|
|
|

|
Excellent code, exactly what I needed ... thanks.
regards
Mark Hibbert
|
|
|
|

|
It really made my job easy.. Really appriciated!!
Clean n Neat code..!! Thanks!!
Niks
|
|
|
|

|
What are the licensing terms for this? Can I free redistribute this code as part of my products?
|
|
|
|

|
why is the path public not private?
|
|
|
|

|
Without full path, this don't create any file:
INIFile ini = new INIFile("test.ini");
This is the solution:
INIFile ini = new INIFile(".\\test.ini");
|
|
|
|

|
That's not completly correct.
The default path for the file is %WINDIR% (in my case C:\WINDOWS).
|
|
|
|

|
How to put it in the application folder?
INIFile ini = new INIFile(".\\test.ini");
doesn't work
|
|
|
|

|
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.IO;
using System.Collections.Specialized;
namespace Utils
{
public class INIFileHandler
{
private Sections m_sections = new Sections();
private char[] vbCrLf = new char[] { '\n', '\r' };
public INIFileHandler() { }
public INIFileHandler(string strINIFile)
{
ReadFile(strINIFile);
}
public void Dispose()
{
if (m_sections != null)
m_sections = null;
}
public Sections Sections()
{
return m_sections;
}
public Section Sections(string name)
{
Section secReturn = new Section("");
try
{
secReturn = m_sections.Section(name);
}
catch (Exception ex)
{ }
if (secReturn != null)
return secReturn;
else
return new Section("");
}
public Section Sections(int index)
{
Section secReturn = new Section("");
try
{
secReturn = m_sections.Section(index);
}
catch (Exception ex)
{
}
if (secReturn != null)
return secReturn;
else
return new Section("");
}
public bool ReadFile(string strINIFile)
{
bool blnOK = false;
try
{
StreamReader srFile = File.OpenText(strINIFile);
string strFile = srFile.ReadToEnd();
string strSectionName = "";
string[] strSetting = null;
string strKey = "";
string strValue = "";
string[] strLine = strFile.Split(vbCrLf);
//~~~~~~~~~~~~~~~~~~~~~~~~
//~ Zap files
//~~~~~~~~~~~~~~~~~~~~
strFile = null;
srFile.Close();
srFile = null;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~ Loop for each line in file
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for (int nI = 0; nI < strLine.Length; nI++)
{
if ((strLine[nI].Trim().Length > 0) && (!strLine[nI].StartsWith(";")))
{
if (strLine[nI].ToUpper().StartsWith("["))
{
strSectionName = strLine[nI].Substring(1, strLine[nI].Length - 2);
m_sections.AddSection(strSectionName);
}
else if (strSectionName.Length > 0)
{
strSetting = strLine[nI].Split('=');
strKey = strSetting[0].ToString().Trim();
strValue = strSetting[1].ToString().Trim();
m_sections.AddSetting(strKey, strValue);
}
}
}
blnOK = true;
}
catch (Exception ex)
{
blnOK = false;
}
return blnOK;
}
public bool WriteINIFile(string strFileName)
{
bool blnOK = false;
try
{
string strINIDoc = this.ToString();
if (strINIDoc != null && strINIDoc.Length > 0)
{
FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write);
StreamWriter writer = new StreamWriter(fs);
writer.Write(strINIDoc);
writer.Flush();
fs.Flush();
fs.Close();
fs = null;
blnOK = true;
}
else
{
blnOK = false;
}
}
catch (Exception ex)
{
blnOK = false;
}
return blnOK;
}
public override string ToString()
{
string strReturn = "";
try
{
string strINIDoc = "";
for (int nSec = 0; nSec < m_sections.Count; nSec++)
{
strINIDoc += "[" + m_sections.Section(nSec).Name + "]" + vbCrLf;
for (int nSetting = 0; nSetting < m_sections.Section(nSec).Settings.Count; nSetting++)
{
string strSetting = m_sections.Section(nSec).Settings[nSetting];
string strKey = m_sections.Section(nSec).Keys(nSetting);
strINIDoc += strKey + "=" + strSetting + vbCrLf;
}
strINIDoc += "" + vbCrLf;
}
strReturn = strINIDoc.Trim();
}
catch (Exception ex)
{
strReturn = "";
}
return strReturn;
}
}
public class Sections : System.Collections.Specialized.NameObjectCollectionBase
{
private Section m_section;
public Sections()
{
}
public void AddSection(string name)
{
m_section = new Section(name);
base.BaseAdd(name, m_section);
}
public void AddSetting(string name, string value)
{
m_section.AddSetting(name, value);
}
public Section Section(string name)
{
return (Section)base.BaseGet(name);
}
public Section Section(int index)
{
return (Section)base.BaseGet(index);
}
}
public class Section
{
private NameValueCollection m_colSettings = new NameValueCollection();
private string m_strSectionName = "";
public Section(string name)
{
m_strSectionName = name;
}
public void Dispose()
{
if (m_colSettings != null)
{
m_colSettings = null;
}
}
public String Name
{
get
{
return m_strSectionName;
}
}
public void AddSetting(string name, string value)
{
m_colSettings.Add(name, value);
}
public System.Collections.Specialized.NameValueCollection Settings
{
get
{
return m_colSettings;
}
}
public string Setting(string name)
{
string strReturn = "";
try
{
strReturn = m_colSettings[name];
}
catch (Exception ex)
{
strReturn = "";
}
if (strReturn != null)
{
return strReturn;
}
else
{
return "";
}
}
public string Setting(int index)
{
string strReturn = "";
try
{
strReturn = m_colSettings[index];
}
catch (Exception ex)
{
strReturn = "";
}
return strReturn;
}
public string Keys(int index)
{
string strReturn = "";
try
{
strReturn = m_colSettings.GetKey(index);
}
catch (Exception ex)
{
strReturn = "";
}
if (strReturn != null)
{
return strReturn;
}
else
return "";
}
}
}
|
|
|
|

|
Could anyone tell me which are the exception i need to check in order to avoid any crash of the application when i use dll of the kernel ??
Thanks a lot
|
|
|
|

|
I've been using your code for a while in several different projects and I just realized I never thanked you for it. So... thanks!
|
|
|
|

|
at http://www.snapconfig.com
if you are working with ini files its guaranteed to make your life easier.
None
|
|
|
|

|
I had no problem getting this to work.
Very well done!
One thing I did find I needed was a way to pass a default string if the INI is empty or missing
the keyword.
This was a cinch...
public string IniReadValue(string sSection, string sKey, string sDef)
{
StringBuilder temp = new StringBuilder(255);
int i = GetPrivateProfileString ( sSection, sKey, "", temp, 255, this.path );
string sTemp = temp.ToString();
//
// If empty, put in the supplied default
if (sTemp == string.Empty)
sTemp = sDef;
//
// Return the string
return sTemp;
}
|
|
|
|

|
The third argument to GetPrivateProfileString is the default. Just pass sDef in place of "".
public string IniReadValue(string sSection, string sKey, string sDef)
{
StringBuilder temp = new StringBuilder(255);
int i = GetPrivateProfileString ( sSection, sKey, sDef, temp, 255, this.path );
return temp.ToString();
}
|
|
|
|

|
Where is the file created??????!??!??
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
A C# class that exposes the INI file handling functions from Kernal32.dll
| Type | Article |
| Licence | |
| First Posted | 14 Mar 2002 |
| Views | 425,858 |
| Bookmarked | 125 times |
|
|