|
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");
modified 15-Dec-20 21:02pm.
|
|
|
|
|
That's not completly correct.
The default path for the file is %WINDIR% (in my case C:\WINDOWS).
|
|
|
|
|
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;
}
|
|
|
|
|