Results 1 to 3 of 3

Thread: Windows INI Reader and Writer v1.3

  1. #1

    Thread Starter
    Fanatic Member BenJones's Avatar
    Join Date
    Mar 2010
    Location
    Wales UK
    Posts
    667

    Post Windows INI Reader and Writer v1.3

    Hi here is an update of my ini reader and writer I made a few years back, anyway I been working on a new project and needed a few other things from my ini so I added them in hope you like it Comments welcome.

    INI Class

    Code:
    /* Simple INI file reading and writing class.
     * Version 1.0
     * By Ben a.k.a DreamVB
     * Please use this class as you want.
     * 
     * Update v1.2 18/4/2024
     * Added support to read and write Multiline Strings
     * Added support to read and write integer
     * Added support to read and write bool
     * Added support to read and write double
     * Added SelectionExists
     * Added KeyExists
     * 
     * Update v1.3 22/4/2024
     * Some changes with error checking thanks for the info PlausiblyDamp
     * Added check if value exists.
     */
    
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.InteropServices;
    using System.IO;
    
    namespace inidemo
    {
        class inifile
        {
            private readonly FileInfo fi;
    
            [DllImport("kernel32")]
            static extern long WritePrivateProfileString(string Section, string Key, string Value, string FilePath);
    
            [DllImport("kernel32")]
            static extern int GetPrivateProfileString(string Section, string Key, string Default, StringBuilder RetVal, int Size, string FilePath);
    
            public void WriteString(string selection, string Key, string Value)
            {
                WritePrivateProfileString(selection, Key, Value, fi.FullName);
            }
    
            public string ReadString(string selection, string Key, string vDefault = "")
            {
                StringBuilder sb = new StringBuilder(2048);
                //Get INI file.
                GetPrivateProfileString(selection, Key, vDefault, sb, 2048, fi.FullName);
                //Return value.
                return sb.ToString();
            }
    
            public void WriteMultilineString(string selection,string Key, string Value)
            {
                string S = Value.Replace(Environment.NewLine, "\\n");
                WriteString(selection, Key, S); 
            }
    
            public void WriteInteger(string selection,string Key, int Value)
            {
                WriteString(selection, Key, Value.ToString());
            }
    
            public void WriteBool(string selection, string Key, bool Value)
            {
                WriteString(selection, Key, Value.ToString());
            }
    
            public void WriteDouble(string selection, string Key, double Value)
            {
                WriteString(selection, Key, Value.ToString());
            }
    
            public int ReadInteger(string selection, string Key, int vDefault)
            {
                if (int.TryParse(ReadString(selection, Key, vDefault.ToString()), out int v))
                {
                    return v;
                }
                else
                {
                    return vDefault;
                }
            }
    
            public string ReadMultilineString(string selection, string Key, string vDefault)
            {
                string v;
    
                try
                {
                    v = ReadString(selection, Key, vDefault.ToString()).Replace("\\n", Environment.NewLine);
                }catch (Exception e)
                {
                    throw new ApplicationException("ApplicationException", e);
                }
                return v;
            }
    
            public bool ReadBool(string selection, string Key, bool vDefault)
            {
                if (bool.TryParse(ReadString(selection, Key, vDefault.ToString()), out bool v))
                {
                    return v;
                }
                else
                {
                    return vDefault;
                }
            }
            public double ReadDouble(string selection, string Key, double vDefault)
            {
                if (double.TryParse(ReadString(selection, Key, vDefault.ToString()), out double v))
                {
                    return v;
                }
                else
                {
                    return vDefault;
                }
            }
    
            public void DeleteSelection(string selection)
            {
                WritePrivateProfileString(selection, null, null, fi.FullName);
            }
    
            public void DeleteKey(string selection, string key)
            {
                WritePrivateProfileString(selection, key, null, fi.FullName);
            }
    
            public List<string> ReadSelections()
            {
                List<string> temp = new List<string>();
                string sLine;
                
                if (!fi.Exists)
                {
                    return temp;
                }
    
                using (StreamReader sr = new StreamReader(fi.FullName))
                {
                    while (!sr.EndOfStream)
                    {
                        //Get and trim line
                        sLine = sr.ReadLine();
                        //Check for opening and closing tags
                        if (sLine.StartsWith("[") && (sLine.EndsWith("]")))
                        {
                            //Add to collection.
                            temp.Add(sLine.Substring(1, sLine.Length - 2));
                        }
                    }
                    //close file
                    sr.Close();
                }
                return temp;
            }
    
            public bool SelectionExists(string selection)
            {
                List<string> Temp;
                bool Found = false;
                try
                {
                    Temp = ReadSelections();
                    foreach(string s in Temp)
                    {
                        if (s.ToLower() == selection.ToLower())
                        {
                            Found = true;
                            break;
                        }
                    }
                }catch (Exception e)
                {
                    throw new Exception(e.Message); 
                }
                Temp.Clear();
                return Found;
            }
    
            public bool KeyExists(string selection, string Key)
            {
                List<string> Temp;
                bool Found = false;
                try
                {
                    Temp = ReadSelectionKeys(selection);
                    foreach (string s in Temp)
                    {
                        if (s.ToLower() == Key.ToLower())
                        {
                            Found = true;
                            break;
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new ApplicationException("ApplicationException", e);
                }
                Temp.Clear();
                return Found;
            }
    
            public bool ValueExists(string selection, string key, string value)
            {
                return ReadString(selection, key, string.Empty) == value;
            }
    
            public List<string> ReadSelectionKeys(string selection)
            {
                List<string> temp = new List<string>();
                string sLine;
                string SelName = string.Empty;
    
                if (!fi.Exists)
                {
                    return temp;
                }
    
                using (StreamReader sr = new StreamReader(fi.FullName))
                {
                    while (!sr.EndOfStream)
                    {
                        //Get and trim line
                        sLine = sr.ReadLine();
                        //Check for opening and closing tags
                        if (sLine.StartsWith("[") && (sLine.EndsWith("]")))
                        {
                            //Add to collection.
                            SelName = sLine.Substring(1, sLine.Length - 2);
    
                            if (!sr.EndOfStream)
                            {
                                //Get next line
                                sLine = sr.ReadLine();
                            }
                        }
    
                        //Compare selection names.
                        if (SelName.ToUpper() == selection.ToUpper())
                        {
                            if (sLine.Length > 0)
                            {
                                int pos = sLine.IndexOf("=");
                                //Check for equals sign
                                if (pos > 0)
                                {
                                    //Extract key
                                    temp.Add(sLine.Remove(pos, sLine.Length - pos));
                                }
                            }
                        }
                    }
                    //Close file.
                    sr.Close();
                }
                return temp;
            }
    
            public inifile(string Filename)
            {
                fi = new FileInfo(Filename);
            }
    
        }
    }
    Last edited by BenJones; Apr 22nd, 2024 at 03:08 PM. Reason: Updated code

  2. #2
    PowerPoster PlausiblyDamp's Avatar
    Join Date
    Dec 2016
    Location
    Pontypool, Wales
    Posts
    2,547

    Re: Windows INI Reader and Writer

    Just a couple of points...

    Firstly I wouldn't do this
    Code:
    private static FileInfo fi;
    as the static keyword means only one instance of the fi variable exists and it is shared between all instances of the inifile class in your application. That means if you try to use the class to manipulate two (or more) different inifiles then whichever one you use last will be the only one you modify. e.g. try the following snippet

    Code:
    var i1 = new inifile("test1.ini");
    var i2 = new inifile("test2.ini");
    
    i1.WriteBool("section1", "key1", true);
    i2.WriteBool("section1", "key1", false);
    i1.WriteString("section1", "key2", "Hello World");
    In that case nothing would be written to test1.ini, only test2.ini - removing the keyword static would solve this problem.

    It might be beneficial to mark fi as readonly however.

    Secondly, if you are going to just catch and rethrow an Exception like
    Code:
    //....
    catch (Exception e)
    {
        throw new Exception(e.Message);
    }
    return v;
    then you may as well just not catch the exception, all you are doing is throwing away things like the stack trace which might be useful to higher level code. Either just let the Exception propagate up and the callers can deal with it, or wrap it in another exception e.g.
    Code:
    //....
    catch (Exception e)
    {
        throw new ApplicationException("Your error message", e);
    }
    return v;
    I would personally just let the Exception propagate up the call stack.

    In fact on the ReadXXXX methods it might be better to use the various TryParse methods e.g.
    Code:
    public int ReadInteger(string selection, string Key, int vDefault)
    {
    if (int.TryParse(ReadString(selection, Key, vDefault.ToString()), out int v))
        {
         return v;
         }
    else
        {
         return vDefault; // or throw an exception
         }
    }
    Finally, although this is possibly personal preference, it might be worth considering overloading the various Write methods so you have a single Write e.g.
    Code:
    public void Write(string selection, string key, int value)
    {
    WriteString(selection, key, value.ToString());
    }
    
    public void Write(string selection, string key, bool value)
    {
    WriteString(selection, key, value.ToString());
    }

  3. #3

    Thread Starter
    Fanatic Member BenJones's Avatar
    Join Date
    Mar 2010
    Location
    Wales UK
    Posts
    667

    Re: Windows INI Reader and Writer

    Thanks for the suggestions PlausiblyDamp I look into updating the class again.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width