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(this Enum _type, T _value) { if (!checkIfInitialized()) return; config.SetValue(getStrType(_type), getStrName(_type), _value.ToString()); } public static T GetValue(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; /// /// Call the constructor creates a new object of the INIFile class to work with INI files. /// /// Name of INI file, which you want to access. /// Specifies whether the INI file should be created if it does not exist. 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 /// /// 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. /// /// Name of the requested section. /// Specifies whether comments should also be returned. /// Returns the whole section. public List GetSection(string section, bool includeComments = false) { section = CheckSection(section); List completeSection = new List(); 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 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; } /// /// The method returns a value for the associated key. /// This method is not case-sensitive. /// /// Name of the requested section. /// Name of the requested key. /// If "true" is passed, the value will be returned in lowercase letters. /// Returns the value for the specified key in the specified section, if available, otherwise null. public string GetValue(string section, string key, bool convertValueToLower = false) { section = CheckSection(section); key = key.ToLower(); List 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; } /// /// Set or add a value of the associated key in the specified section. /// This method is not case-sensitive. /// /// Name of the section. /// Name of the key. /// Value to save. /// If "true" is passed, the value will be saved in lowercase letters. public void SetValue(string section, string key, string value, bool convertValueToLower = false) { section = CheckSection(section, false); string sectionToLower = section.ToLower(); bool sectionFound = false; List iniFileContent = new List(); 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 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 /// /// Ensures that a section is always in the following format: [section]. /// /// Section to be checked for correct format. /// Specifies whether the section should be vonverted in lower case letters. /// Returns section in this form: [section]. private string CheckSection(string section, bool convertToLower = true) { if (convertToLower == true) { section = section.ToLower(); } if (!section.StartsWith("[") && !section.EndsWith("]")) { section = "[" + section + "]"; } return section; } /// /// Removes leading and trailing spaces from sections, keys and values. /// /// String to be trimmed. /// Returns the trimmed string. 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(); } /// /// Adds a new section with key value pair. /// /// List iniFileContent from SetValue. /// Section to be created. /// Key to be added. /// Value to be added. /// Specifies whether the key and value should be saved in lower case letters. /// Returns the new created section with key value pair. private List AddSection(List 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 content) { StreamWriter writer = new StreamWriter(_File); foreach (var item in content) { writer.WriteLine(item); } writer.Close(); } #endregion } }