357 lines
No EOL
13 KiB
C#
357 lines
No EOL
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using Nocksoft.IO.ConfigFiles;
|
|
|
|
|
|
|
|
|
|
public static class ConfigUtils
|
|
{
|
|
private static INIFile config;
|
|
|
|
public static void InitConfig(string path = "config.ini")
|
|
{
|
|
config = new INIFile(path, true);
|
|
}
|
|
public static void SetValue<T>(this Enum _type, T _value)
|
|
{
|
|
if (!checkIfInitialized())
|
|
return;
|
|
config.SetValue(getStrType(_type), getStrName(_type), _value.ToString());
|
|
}
|
|
public static T GetValue<T>(this Enum _type)
|
|
{
|
|
if (!checkIfInitialized())
|
|
return default(T);
|
|
try
|
|
{
|
|
var value = config.GetValue(getStrType(_type), getStrName(_type));
|
|
return (T)Convert.ChangeType(value, typeof(T));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine("ConfigManager Exception on " + getStrType(_type) + "." + getStrName(_type) + ": " + ex.Message);
|
|
return default(T);
|
|
}
|
|
}
|
|
private static string getStrType(Enum _enum)
|
|
{
|
|
return _enum.GetType().Name;
|
|
}
|
|
|
|
private static string getStrName(Enum _enum)
|
|
{
|
|
return Enum.GetName(_enum.GetType(), _enum);
|
|
}
|
|
|
|
|
|
private static bool checkIfInitialized()
|
|
{
|
|
if (config == null)
|
|
{
|
|
Console.WriteLine("Config not initialized");
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Copyright by Nocksoft
|
|
* https://www.nocksoft.de
|
|
* https://nocksoft.de/tutorials/visual-c-sharp-arbeiten-mit-ini-dateien/
|
|
* https://github.com/Nocksoft/INIFile.cs
|
|
* -----------------------------------
|
|
* Author: Rafael Nockmann @ Nocksoft
|
|
* Updated: 2022-01-09
|
|
* Version: 1.0.3
|
|
*
|
|
* Language: Visual C#
|
|
*
|
|
* License: MIT license
|
|
* License URL: https://github.com/Nocksoft/INIFile.cs/blob/master/LICENSE
|
|
*
|
|
* Description:
|
|
* Provides basic functions for working with INI files.
|
|
*
|
|
* ##############################################################################################
|
|
*/
|
|
|
|
|
|
namespace Nocksoft.IO.ConfigFiles
|
|
{
|
|
public class INIFile
|
|
{
|
|
private string _File;
|
|
|
|
/// <summary>
|
|
/// Call the constructor creates a new object of the INIFile class to work with INI files.
|
|
/// </summary>
|
|
/// <param name="file">Name of INI file, which you want to access.</param>
|
|
/// <param name="createFile">Specifies whether the INI file should be created if it does not exist.</param>
|
|
public INIFile(string file, bool createFile = false)
|
|
{
|
|
if (createFile == true && File.Exists(file) == false)
|
|
{
|
|
FileInfo fileInfo = new FileInfo(file);
|
|
FileStream fileStream = fileInfo.Create();
|
|
fileStream.Close();
|
|
}
|
|
_File = file;
|
|
}
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Removes all comments and empty lines from a complete section and returns the sections.
|
|
/// This method is not case-sensitive.
|
|
/// The return value does not contain any spaces at the beginning or at the end of a line.
|
|
/// </summary>
|
|
/// <param name="section">Name of the requested section.</param>
|
|
/// <param name="includeComments">Specifies whether comments should also be returned.</param>
|
|
/// <returns>Returns the whole section.</returns>
|
|
public List<string> GetSection(string section, bool includeComments = false)
|
|
{
|
|
section = CheckSection(section);
|
|
|
|
List<string> completeSection = new List<string>();
|
|
bool sectionStart = false;
|
|
|
|
string[] fileArray = File.ReadAllLines(_File);
|
|
|
|
foreach (var item in fileArray)
|
|
{
|
|
if (item.Length <= 0) continue;
|
|
|
|
// Beginning of section.
|
|
if (item.Replace(" ", "").ToLower() == section)
|
|
{
|
|
sectionStart = true;
|
|
}
|
|
// Beginning of next section.
|
|
if (sectionStart == true && item.Replace(" ", "").ToLower() != section && item.Replace(" ", "").Substring(0, 1) == "[" && item.Replace(" ", "").Substring(item.Length - 1, 1) == "]")
|
|
{
|
|
break;
|
|
}
|
|
if (sectionStart == true)
|
|
{
|
|
// Add the entry to the List<string> completeSection, if it is not a comment or an empty entry.
|
|
if (includeComments == false
|
|
&& item.Replace(" ", "").Substring(0, 1) != ";" && !string.IsNullOrWhiteSpace(item))
|
|
{
|
|
completeSection.Add(ReplaceSpacesAtStartAndEnd(item));
|
|
}
|
|
if (includeComments == true && !string.IsNullOrWhiteSpace(item))
|
|
{
|
|
completeSection.Add(ReplaceSpacesAtStartAndEnd(item));
|
|
}
|
|
}
|
|
}
|
|
return completeSection;
|
|
}
|
|
|
|
/// <summary>
|
|
/// The method returns a value for the associated key.
|
|
/// This method is not case-sensitive.
|
|
/// </summary>
|
|
/// <param name="section">Name of the requested section.</param>
|
|
/// <param name="key">Name of the requested key.</param>
|
|
/// <param name="convertValueToLower">If "true" is passed, the value will be returned in lowercase letters.</param>
|
|
/// <returns>Returns the value for the specified key in the specified section, if available, otherwise null.</returns>
|
|
public string GetValue(string section, string key, bool convertValueToLower = false)
|
|
{
|
|
section = CheckSection(section);
|
|
key = key.ToLower();
|
|
|
|
List<string> completeSection = GetSection(section);
|
|
|
|
foreach (var item in completeSection)
|
|
{
|
|
// Continue if entry is no key.
|
|
if (!item.Contains("=") && item.Contains("[") && item.Contains("]")) continue;
|
|
|
|
string[] keyAndValue = item.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries);
|
|
if (keyAndValue[0].ToLower() == key && keyAndValue.Count() > 1)
|
|
{
|
|
if (convertValueToLower == true)
|
|
{
|
|
keyAndValue[1] = keyAndValue[1].ToLower();
|
|
}
|
|
return keyAndValue[1];
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set or add a value of the associated key in the specified section.
|
|
/// This method is not case-sensitive.
|
|
/// </summary>
|
|
/// <param name="section">Name of the section.</param>
|
|
/// <param name="key">Name of the key.</param>
|
|
/// <param name="value">Value to save.</param>
|
|
/// <param name="convertValueToLower">If "true" is passed, the value will be saved in lowercase letters.</param>
|
|
public void SetValue(string section, string key, string value, bool convertValueToLower = false)
|
|
{
|
|
section = CheckSection(section, false);
|
|
string sectionToLower = section.ToLower();
|
|
|
|
bool sectionFound = false;
|
|
|
|
List<string> iniFileContent = new List<string>();
|
|
|
|
string[] fileLines = File.ReadAllLines(_File);
|
|
|
|
// Creates a new INI file if none exists.
|
|
if (fileLines.Length <= 0)
|
|
{
|
|
iniFileContent = AddSection(iniFileContent, section, key, value, convertValueToLower);
|
|
WriteFile(iniFileContent);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < fileLines.Length; i++)
|
|
{
|
|
// Possibility 1: The desired section has not (yet) been found.
|
|
if (fileLines[i].Replace(" ", "").ToLower() != sectionToLower)
|
|
{
|
|
iniFileContent.Add(fileLines[i]);
|
|
// If a section does not exist, the section will be created.
|
|
if (i == fileLines.Length - 1 && fileLines[i].Replace(" ", "").ToLower() != sectionToLower && sectionFound == false)
|
|
{
|
|
iniFileContent.Add(null);
|
|
iniFileContent = AddSection(iniFileContent, section, key, value, convertValueToLower);
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
|
|
// Possibility 2 -> Desired section was found.
|
|
sectionFound = true;
|
|
|
|
// Get the complete section in which the target key may be.
|
|
List<string> targetSection = GetSection(sectionToLower, true);
|
|
|
|
for (int x = 0; x < targetSection.Count; x++)
|
|
{
|
|
string[] targetKey = targetSection[x].Split(new string[] { "=" }, StringSplitOptions.None);
|
|
// When the target key is found.
|
|
if (targetKey[0].ToLower() == key.ToLower())
|
|
{
|
|
if (convertValueToLower == true)
|
|
{
|
|
iniFileContent.Add(key + "=" + value.ToLower());
|
|
}
|
|
else
|
|
{
|
|
iniFileContent.Add(key + "=" + value);
|
|
}
|
|
i = i + x;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
iniFileContent.Add(targetSection[x]);
|
|
// If the target key is not found, it will be created.
|
|
if (x == targetSection.Count - 1 && targetKey[0].ToLower() != key.ToLower())
|
|
{
|
|
if (convertValueToLower == true)
|
|
{
|
|
iniFileContent.Add(key + "=" + value.ToLower());
|
|
}
|
|
else
|
|
{
|
|
iniFileContent.Add(key + "=" + value);
|
|
}
|
|
i = i + x;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
WriteFile(iniFileContent);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private Methods
|
|
|
|
/// <summary>
|
|
/// Ensures that a section is always in the following format: [section].
|
|
/// </summary>
|
|
/// <param name="section">Section to be checked for correct format.</param>
|
|
/// <param name="convertToLower">Specifies whether the section should be vonverted in lower case letters.</param>
|
|
/// <returns>Returns section in this form: [section].</returns>
|
|
private string CheckSection(string section, bool convertToLower = true)
|
|
{
|
|
if (convertToLower == true)
|
|
{
|
|
section = section.ToLower();
|
|
}
|
|
if (!section.StartsWith("[") && !section.EndsWith("]"))
|
|
{
|
|
section = "[" + section + "]";
|
|
}
|
|
return section;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes leading and trailing spaces from sections, keys and values.
|
|
/// </summary>
|
|
/// <param name="item">String to be trimmed.</param>
|
|
/// <returns>Returns the trimmed string.</returns>
|
|
private string ReplaceSpacesAtStartAndEnd(string item)
|
|
{
|
|
// If the string has a key and a value.
|
|
if (item.Contains("=") && !item.Contains("[") && !item.Contains("]"))
|
|
{
|
|
string[] keyAndValue = item.Split(new string[] { "=" }, StringSplitOptions.None);
|
|
return keyAndValue[0].Trim() + "=" + keyAndValue[1].Trim();
|
|
}
|
|
|
|
return item.Trim();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a new section with key value pair.
|
|
/// </summary>
|
|
/// <param name="iniFileContent">List iniFileContent from SetValue.</param>
|
|
/// <param name="section">Section to be created.</param>
|
|
/// <param name="key">Key to be added.</param>
|
|
/// <param name="value">Value to be added.</param>
|
|
/// <param name="convertValueToLower">Specifies whether the key and value should be saved in lower case letters.</param>
|
|
/// <returns>Returns the new created section with key value pair.</returns>
|
|
private List<string> AddSection(List<string> iniFileContent, string section, string key, string value, bool convertValueToLower)
|
|
{
|
|
if (convertValueToLower == true)
|
|
{
|
|
value = value.ToLower();
|
|
}
|
|
|
|
iniFileContent.Add(section);
|
|
iniFileContent.Add($"{key}={value}");
|
|
return iniFileContent;
|
|
}
|
|
|
|
private void WriteFile(List<string> content)
|
|
{
|
|
StreamWriter writer = new StreamWriter(_File);
|
|
foreach (var item in content)
|
|
{
|
|
writer.WriteLine(item);
|
|
}
|
|
writer.Close();
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |