using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using Yaulw.Tools; using Yaulw.Win32; using System.Diagnostics; namespace Yaulw.File { /// /// Responsible for Reading and Writing an INI File. /// Simply construct an INIFile Object passing in a File name and Path, /// as well as an enum that lists all the Categories and Keys. /// /// An example *You can mix and match Categories and Keys as needed *: /// public enum INICatsNKeys /// { /// App_Settings__Load_XML_At_StartUp, /// App_Settings__Allow_Command_Line_to_override_INI, /// App_Settings__Default_User, /// App_Settings__Default_Server, /// Runtime_Debug__Error_Debug_Level, /// Data_Access__Read_Only, /// Settings__Program_Folder, /// Settings__User1_Default, /// Recent_File_List__File1, /// Recent_File_List__File2, /// Recent_File_List__File3, /// Recent_File_List__File4, /// } /// /// The '__' Character signifies a category to Key change /// the '_' will be replaced by ' ', when actually writing to the Ini File. /// public class INIFile { #region Private Members private string _IniPathNFileName = String.Empty; private Type _IniKeysNCategories = null; #endregion #region Construction /// /// Initialize an INIFile object with a valid path and FileName to write/read from. /// Also pass in an Enum Type that contains Category and Key Information. This Enum will be used /// to read and write to the INIFile (to determine which Section/Key to read/write from/to) /// /// Pass in the full file name and path to use * Creates Directory, if it does not exits * /// Pass in an Enum that specifies the Categories and Keys /// Thrown if an invalid Enum is passed in via IniKeysNCategories public INIFile(string IniPathNFileName, Type IniKeysNCategories) { // Check and ensure Enum Accuracy if (IniKeysNCategories.IsEnum && EnumTool.EnumType_HasCategoryNKey(IniKeysNCategories)) { _IniKeysNCategories = IniKeysNCategories; } else throw new ArgumentException("IniKeysNCategories is not an Enum or not all Enums contain Key and Category Information"); // Ensure Directory Existence if (!Directory.Exists(Path.GetDirectoryName(IniPathNFileName))) Directory.CreateDirectory(Path.GetDirectoryName(IniPathNFileName)); _IniPathNFileName = IniPathNFileName; } #endregion #region Public Properties /// /// Ini File Used by IniFile /// public string IniFile { get { return _IniPathNFileName; } } #endregion #region Public Ini Key Reader / Writer Functions /// /// Use this to directly set a key to any string value /// /// Specify Key and category set Directly /// value to set /// If cKey is not a valid Category/Key Pair Enum public void SetKeyValue(Enum cKey, T Value) { if (EnumTool.Enum_HasCategoryNKey(cKey)) { string Category; string Key; EnumTool.Enum_ToCategoryNKey(cKey, out Category, out Key); string ValueStr = ObjTool.ConvertObjToString(Value); SetKeyValueString(Category, Key, ValueStr); } else { throw new ArgumentException("cKey must have both Category and Key Information"); } } /// /// Use this to directly retrieve a key /// /// Specify Key and category set Directly /// default value to return, if not found /// value retrieved or default value /// If cKey is not a valid Category/Key Pair Enum public T GetKeyValue(Enum cKey, T defaultValue) { try { if (EnumTool.Enum_HasCategoryNKey(cKey)) { string Category; string Key; EnumTool.Enum_ToCategoryNKey(cKey, out Category, out Key); // Get Key and verify that something was found string defaultValueStr = ObjTool.ConvertObjToString(defaultValue); string KeyValue = GetKeyValueString(Category, Key, defaultValueStr); bool bHasAValue = (KeyValue.Trim().Length != 0); // always write the value back out to ini SetKeyValue(cKey, bHasAValue ? KeyValue : defaultValueStr); // Return value if (bHasAValue) { return ObjTool.ConvertStringToObj(KeyValue); } else { return defaultValue; } } else { throw new ArgumentException("cKey must have both Category and Key Information"); } } catch (Exception) { /* ignore */ } return defaultValue; } #endregion #region Private Generic Ini Key Reader / Writer Functions /// /// Set a value for the specified Key and for the specified category /// /// specify category /// specify key /// specify a value to set private void SetKeyValueString(string category, string key, string value) { bool bSuccess = Kernel32.WritePrivateProfileString(category, key, value, IniFile); Debug.Assert(bSuccess); } /// /// Retrieve the value for a specified Key and for a specified category /// /// specify category /// specify key /// specify default value, returned when no value found /// the value for the Key, or default value if no value found private string GetKeyValueString(string category, string key, string defaultValue) { StringBuilder returnString = new StringBuilder(1024); Kernel32.GetPrivateProfileString(category, key, defaultValue, returnString, 1024, IniFile); return returnString.ToString().Split('\0')[0]; } #endregion #region Private Generic Ini File Readers (Not Used) /// /// Use this to return all the categories in an INI File /// /// a list with Gategory Items, or 0 length list is none found private List GetAllCategories() { StringBuilder returnString = new StringBuilder(65536); uint returnValue = Kernel32.GetPrivateProfileString(null, null, null, returnString, 65536, IniFile); List result = new List(returnString.ToString().Split('\0')); result.RemoveRange(result.Count - 2, 2); return result; } /// /// Use this to return the Keys from a category from an INI File /// /// a list with Key Items, or 0 length list is none found private List GetAllKeysInCategory(string category) { StringBuilder returnString = new StringBuilder(32768); Kernel32.GetPrivateProfileString(category, null, null, returnString, 32768, IniFile); List result = new List(returnString.ToString().Split('\0')); result.RemoveRange(result.Count - 2, 2); return result; } #endregion } }