214 lines
8.5 KiB
C#
214 lines
8.5 KiB
C#
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
|
|
{
|
|
/// <remarks>
|
|
/// 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.
|
|
/// </remarks>
|
|
public class INIFile
|
|
{
|
|
#region Private Members
|
|
|
|
private string _IniPathNFileName = String.Empty;
|
|
private Type _IniKeysNCategories = null;
|
|
|
|
#endregion
|
|
|
|
#region Construction
|
|
|
|
/// <summary>
|
|
/// 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)
|
|
/// </summary>
|
|
/// <param name="IniPathNFileName">Pass in the full file name and path to use * Creates Directory, if it does not exits *</param>
|
|
/// <param name="IniKeysNCategories">Pass in an Enum that specifies the Categories and Keys</param>
|
|
/// <exception cref="ArgumentException">Thrown if an invalid Enum is passed in via IniKeysNCategories</exception>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Ini File Used by IniFile
|
|
/// </summary>
|
|
public string IniFile { get { return _IniPathNFileName; } }
|
|
|
|
#endregion
|
|
|
|
#region Public Ini Key Reader / Writer Functions
|
|
|
|
/// <summary>
|
|
/// Use this to directly set a key to any string value
|
|
/// </summary>
|
|
/// <param name="cKey">Specify Key and category set Directly</param>
|
|
/// <param name="Value">value to set</param>
|
|
/// <exception cref="ArgumentException">If cKey is not a valid Category/Key Pair Enum</exception>
|
|
public void SetKeyValue<T>(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<T>(Value);
|
|
SetKeyValueString(Category, Key, ValueStr);
|
|
}
|
|
else
|
|
{
|
|
throw new ArgumentException("cKey must have both Category and Key Information");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use this to directly retrieve a key
|
|
/// </summary>
|
|
/// <param name="cKey">Specify Key and category set Directly</param>
|
|
/// <param name="defaultValue">default value to return, if not found</param>
|
|
/// <returns>value retrieved or default value</returns>
|
|
/// <exception cref="ArgumentException">If cKey is not a valid Category/Key Pair Enum</exception>
|
|
public T GetKeyValue<T>(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<T>(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<T>(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
|
|
|
|
/// <summary>
|
|
/// Set a value for the specified Key and for the specified category
|
|
/// </summary>
|
|
/// <param name="category">specify category</param>
|
|
/// <param name="key">specify key</param>
|
|
/// <param name="value">specify a value to set</param>
|
|
private void SetKeyValueString(string category, string key, string value)
|
|
{
|
|
bool bSuccess = Kernel32.WritePrivateProfileString(category, key, value, IniFile);
|
|
Debug.Assert(bSuccess);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve the value for a specified Key and for a specified category
|
|
/// </summary>
|
|
/// <param name="category">specify category</param>
|
|
/// <param name="key">specify key</param>
|
|
/// <param name="defaultValue">specify default value, returned when no value found</param>
|
|
/// <returns>the value for the Key, or default value if no value found</returns>
|
|
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)
|
|
|
|
/// <summary>
|
|
/// Use this to return all the categories in an INI File
|
|
/// </summary>
|
|
/// <returns>a list with Gategory Items, or 0 length list is none found</returns>
|
|
private List<string> GetAllCategories()
|
|
{
|
|
StringBuilder returnString = new StringBuilder(65536);
|
|
uint returnValue = Kernel32.GetPrivateProfileString(null, null, null, returnString, 65536, IniFile);
|
|
List<string> result = new List<string>(returnString.ToString().Split('\0'));
|
|
result.RemoveRange(result.Count - 2, 2);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use this to return the Keys from a category from an INI File
|
|
/// </summary>
|
|
/// <returns>a list with Key Items, or 0 length list is none found</returns>
|
|
private List<string> GetAllKeysInCategory(string category)
|
|
{
|
|
StringBuilder returnString = new StringBuilder(32768);
|
|
Kernel32.GetPrivateProfileString(category, null, null, returnString, 32768, IniFile);
|
|
List<string> result = new List<string>(returnString.ToString().Split('\0'));
|
|
result.RemoveRange(result.Count - 2, 2);
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|