RemObjects verfügt über eine Delphi Prism-Bibliothek namens ShineOn, die eine ähnliche INI-Dateiklasse enthält. Sie benötigen jedoch Delphi Prism, um es aus dem Quellcode für .NET zu kompilieren, da noch keine kompilierte Assembly verfügbar ist. code.remobjects.com/p/shineon
Lex Li
1
Habe das gleiche Problem und habe meine eigene Bibliothek zum Parsen von INI-Dateien erstellt: github.com/rickyah/ini-parser Hoffe, es hilft
Ricardo Amores
5
Genau wie Ricky habe ich beschlossen, meine eigene Lösung dafür zu finden. Es ist verfügbar unter: github.com/MarioZ/MadMilkman.Ini
Mario Z
Antworten:
185
Die Ersteller des .NET Frameworks möchten, dass Sie XML-basierte Konfigurationsdateien anstelle von INI-Dateien verwenden. Also nein, es gibt keinen eingebauten Mechanismus zum Lesen.
Es sind jedoch Lösungen von Drittanbietern verfügbar.
Sie können Ihren eigenen INI-Handler schreiben. Dies ist die mühsame Art der alten Schule. Sie haben mehr Kontrolle über die Implementierung, die Sie für gut oder schlecht verwenden können. Siehe z. B. eine INI-Dateibehandlungsklasse mit C #, P / Invoke und Win32 .
Obwohl es stimmt, dass XML-Konfigurationsdateien der richtige Weg sind, ist dies immer noch keine Antwort auf die Frage oder VLQ nur für Links.
Danny Beckett
6
@aloneguid Ich würde argumentieren, dass die große Anzahl verfügbarer Funktionen tatsächlich dazu beigetragen hat, dass .NET-Konfigurationsdateien seltsame Giganten mit viel Magie sind. Sie sind zu "Code in der Konfigurationsdatei" geworden, was zu viel Komplexität und seltsamen Verhaltensweisen führt und das Konfigurationsmanagement erschwert. (Ich sehe Sie, Datenbank- "Anbieter" und Verbindungszeichenfolgen.) Daher sind INI-Dateien im Allgemeinen auch besser für die nicht manuelle Bearbeitung geeignet.
jpmc26
1
Ich mag alte Methode (P / Inovke) und Sie können Unicode mit alten Methode wie folgt verwenden: File.WriteAllBytes (Pfad, neues Byte [] {0xFF, 0xFE});
Segelfisch009
2
Gutes Paket, aber es könnte besser sein. Es kann keinen Wert analysieren, der '=' oder '\ n' vollständig enthält
Ahmad Behjati
211
Vorwort
Lesen Sie zunächst diesen MSDN-Blogbeitrag über die Einschränkungen von INI-Dateien . Wenn es Ihren Bedürfnissen entspricht, lesen Sie weiter.
Dies ist eine prägnante Implementierung, die ich unter Verwendung des ursprünglichen Windows P / Invoke geschrieben habe. Sie wird daher von allen Windows-Versionen mit installiertem .NET (dh Windows 98 - Windows 10) unterstützt. Ich gebe es hiermit öffentlich zugänglich - Sie können es ohne Namensnennung kommerziell nutzen.
Die winzige Klasse
Fügen Sie IniFile.csIhrem Projekt eine neue Klasse hinzu :
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;// Change this to match your program's normal namespace
namespace MyProg{classIniFile// revision 11{stringPath;string EXE =Assembly.GetExecutingAssembly().GetName().Name;[DllImport("kernel32",CharSet=CharSet.Unicode)]staticexternlongWritePrivateProfileString(stringSection,stringKey,stringValue,stringFilePath);[DllImport("kernel32",CharSet=CharSet.Unicode)]staticexternintGetPrivateProfileString(stringSection,stringKey,stringDefault,StringBuilderRetVal,intSize,stringFilePath);publicIniFile(stringIniPath=null){Path=newFileInfo(IniPath?? EXE +".ini").FullName;}publicstringRead(stringKey,stringSection=null){varRetVal=newStringBuilder(255);GetPrivateProfileString(Section?? EXE,Key,"",RetVal,255,Path);returnRetVal.ToString();}publicvoidWrite(stringKey,stringValue,stringSection=null){WritePrivateProfileString(Section?? EXE,Key,Value,Path);}publicvoidDeleteKey(stringKey,stringSection=null){Write(Key,null,Section?? EXE);}publicvoidDeleteSection(stringSection=null){Write(null,null,Section?? EXE);}publicboolKeyExists(stringKey,stringSection=null){returnRead(Key,Section).Length>0;}}}
Wie man es benutzt
Öffnen Sie die INI-Datei auf eine der folgenden drei Arten:
// Creates or loads an INI file in the same directory as your executable// named EXE.ini (where EXE is the name of your executable)varMyIni=newIniFile();// Or specify a specific name in the current dirvarMyIni=newIniFile("Settings.ini");// Or specify a specific name in a specific dirvarMyIni=newIniFile(@"C:\Settings.ini");
Ich bin etwas spät dran, aber es fehlt die GetSections()Methode.
Stil
2
Möglicherweise wäre eine traditionellere Standardeinstellung pro Anwendung (nicht pro Baugruppe) INI-Dateien wie Path.GetFullPath(IniPath ?? Path.ChangeExtension(Application.ExecutablePath, ".ini")).
Eugene
3
Echt super ! Auf Github legen?
Emrys Myrooin
2
@danny Beckett, schön gemacht. Dies entspricht fast genau dem, was ich in den letzten Jahren von .Net verwendet habe. Vor Jahren von altem Code aktualisiert.
Damian
10
Alt und so sehr ich Raymond Chen respektiere, waren viele der Einschränkungen in diesem Artikel Einschränkungen der spezifischen INI-Bibliothek in Windows und nicht des INI-Formats selbst. Andere, wie granulare Berechtigungen, können über mehrere Dateien leicht umgangen werden. Eine offizielle , modernisierte INI-Bibliothek wäre auch heute noch sehr willkommen.
Joel Coehoorn
68
Dieser Artikel über CodeProject " Eine INI- Dateibehandlungsklasse mit C # " sollte helfen.
Der Autor hat eine C # -Klasse "Ini" erstellt, die zwei Funktionen aus KERNEL32.dll verfügbar macht. Diese Funktionen sind: WritePrivateProfileStringund GetPrivateProfileString. Sie benötigen zwei Namespaces: System.Runtime.InteropServicesund System.Text.
Schritte zur Verwendung der Ini-Klasse
Fügen Sie in Ihrer Projekt-Namespace-Definition hinzu
using INI;
Erstellen Sie eine INIFile wie diese
INIFile ini =newINIFile("C:\\test.ini");
Verwenden Sie IniWriteValuediese Option , um einen neuen Wert in einen bestimmten Schlüssel in einem Abschnitt zu schreiben oder um IniReadValueeinen Wert aus einem Schlüssel in einem bestimmten Abschnitt zu lesen.
Ich habe diesen Ansatz für eine Weile verwendet, aber Sicherheitsverbesserungen ab Win7 haben dies für mich so gut wie zunichte gemacht. Sie können diesen Ansatz weiterhin verwenden, aber Sie müssen die INI in ProgramData speichern und Ihre App dort lesen / schreiben lassen.
Jess
Speichern Sie keine Anwendungskonfigurations-INI-Dateien in ProgramData. Sie gehören weder in die Registrierung noch in die Programmdaten. Konfigurationsdateien sollten sich in den LocalApplicationData-Ordnern befinden.
using System;
using System.IO;
using System.Collections;publicclassIniParser{privateHashtable keyPairs =newHashtable();privateString iniFilePath;privatestructSectionPair{publicStringSection;publicStringKey;}/// <summary>/// Opens the INI file at the given path and enumerates the values in the IniParser./// </summary>/// <param name="iniPath">Full path to INI file.</param>publicIniParser(String iniPath){TextReader iniFile =null;String strLine =null;String currentRoot =null;String[] keyPair =null;
iniFilePath = iniPath;if(File.Exists(iniPath)){try{
iniFile =newStreamReader(iniPath);
strLine = iniFile.ReadLine();while(strLine !=null){
strLine = strLine.Trim().ToUpper();if(strLine !=""){if(strLine.StartsWith("[")&& strLine.EndsWith("]")){
currentRoot = strLine.Substring(1, strLine.Length-2);}else{
keyPair = strLine.Split(newchar[]{'='},2);SectionPair sectionPair;Stringvalue=null;if(currentRoot ==null)
currentRoot ="ROOT";
sectionPair.Section= currentRoot;
sectionPair.Key= keyPair[0];if(keyPair.Length>1)value= keyPair[1];
keyPairs.Add(sectionPair,value);}}
strLine = iniFile.ReadLine();}}catch(Exception ex){throw ex;}finally{if(iniFile !=null)
iniFile.Close();}}elsethrownewFileNotFoundException("Unable to locate "+ iniPath);}/// <summary>/// Returns the value for the given section, key pair./// </summary>/// <param name="sectionName">Section name.</param>/// <param name="settingName">Key name.</param>publicStringGetSetting(String sectionName,String settingName){SectionPair sectionPair;
sectionPair.Section= sectionName.ToUpper();
sectionPair.Key= settingName.ToUpper();return(String)keyPairs[sectionPair];}/// <summary>/// Enumerates all lines for given section./// </summary>/// <param name="sectionName">Section to enum.</param>publicString[]EnumSection(String sectionName){ArrayList tmpArray =newArrayList();foreach(SectionPair pair in keyPairs.Keys){if(pair.Section== sectionName.ToUpper())
tmpArray.Add(pair.Key);}return(String[])tmpArray.ToArray(typeof(String));}/// <summary>/// Adds or replaces a setting to the table to be saved./// </summary>/// <param name="sectionName">Section to add under.</param>/// <param name="settingName">Key name to add.</param>/// <param name="settingValue">Value of key.</param>publicvoidAddSetting(String sectionName,String settingName,String settingValue){SectionPair sectionPair;
sectionPair.Section= sectionName.ToUpper();
sectionPair.Key= settingName.ToUpper();if(keyPairs.ContainsKey(sectionPair))
keyPairs.Remove(sectionPair);
keyPairs.Add(sectionPair, settingValue);}/// <summary>/// Adds or replaces a setting to the table to be saved with a null value./// </summary>/// <param name="sectionName">Section to add under.</param>/// <param name="settingName">Key name to add.</param>publicvoidAddSetting(String sectionName,String settingName){AddSetting(sectionName, settingName,null);}/// <summary>/// Remove a setting./// </summary>/// <param name="sectionName">Section to add under.</param>/// <param name="settingName">Key name to add.</param>publicvoidDeleteSetting(String sectionName,String settingName){SectionPair sectionPair;
sectionPair.Section= sectionName.ToUpper();
sectionPair.Key= settingName.ToUpper();if(keyPairs.ContainsKey(sectionPair))
keyPairs.Remove(sectionPair);}/// <summary>/// Save settings to new file./// </summary>/// <param name="newFilePath">New file path.</param>publicvoidSaveSettings(String newFilePath){ArrayList sections =newArrayList();String tmpValue ="";String strToSave ="";foreach(SectionPair sectionPair in keyPairs.Keys){if(!sections.Contains(sectionPair.Section))
sections.Add(sectionPair.Section);}foreach(String section in sections){
strToSave +=("["+ section +"]\r\n");foreach(SectionPair sectionPair in keyPairs.Keys){if(sectionPair.Section== section){
tmpValue =(String)keyPairs[sectionPair];if(tmpValue !=null)
tmpValue ="="+ tmpValue;
strToSave +=(sectionPair.Key+ tmpValue +"\r\n");}}
strToSave +="\r\n";}try{TextWriter tw =newStreamWriter(newFilePath);
tw.Write(strToSave);
tw.Close();}catch(Exception ex){throw ex;}}/// <summary>/// Save settings back to ini file./// </summary>publicvoidSaveSettings(){SaveSettings(iniFilePath);}}
+1, um über dem Downvote auszugleichen. Worüber beschweren Sie sich wirklich? Er sagte, er habe es gefunden. Stimmen Sie ihn ab, weil er keinen mit generischen Accessoren und Stringbuilder-Verwendung gefunden hat?
Tormod
1
@Tormod: Ich wünschte, ich könnte den Kommentar ablehnen. Es ist ein technisches Forum, wenn wir über Lösungen abstimmen, nicht über die (offensichtlich positive) Absicht. Wenn eine von Knuth selbst veröffentlichte Lösung Mängel hätte, würde - und sollte - darauf hingewiesen werden. Es spielt keine Rolle, ob die Lösung vom Poster gefunden oder geschrieben wurde.
ya23
7
Ich denke, Sie strecken die Definition von "Fehler". Wenn die Lösung Ihre Empfindlichkeiten nicht betont, stimmen Sie einfach nicht ab. Ich habe gerade eine Nachricht hinterlassen, dass ich seine Ablehnung bereits negiert habe, damit die anderen 7 Leute, die meinen Kommentar positiv bewertet haben, dies nicht selbst tun.
Tormod
21
Der Code in Joerages Antwort ist inspirierend.
Leider ändert es die Groß- und Kleinschreibung der Tasten und behandelt keine Kommentare. Also habe ich etwas geschrieben, das robust genug sein sollte, um (nur) sehr schmutzige INI-Dateien zu lesen und Schlüssel so abzurufen, wie sie sind.
Es verwendet etwas LINQ, ein verschachteltes String-Wörterbuch ohne Berücksichtigung der Groß- und Kleinschreibung, um Abschnitte, Schlüssel und Werte zu speichern und die Datei auf einmal zu lesen.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;classIniReader{Dictionary<string,Dictionary<string,string>> ini =newDictionary<string,Dictionary<string,string>>(StringComparer.InvariantCultureIgnoreCase);publicIniReader(string file){var txt =File.ReadAllText(file);Dictionary<string,string> currentSection =newDictionary<string,string>(StringComparer.InvariantCultureIgnoreCase);
ini[""]= currentSection;foreach(var line in txt.Split(new[]{"\n"},StringSplitOptions.RemoveEmptyEntries).Where(t =>!string.IsNullOrWhiteSpace(t)).Select(t => t.Trim())){if(line.StartsWith(";"))continue;if(line.StartsWith("[")&& line.EndsWith("]")){
currentSection =newDictionary<string,string>(StringComparer.InvariantCultureIgnoreCase);
ini[line.Substring(1, line.LastIndexOf("]")-1)]= currentSection;continue;}var idx = line.IndexOf("=");if(idx ==-1)
currentSection[line]="";else
currentSection[line.Substring(0, idx)]= line.Substring(idx +1);}}publicstringGetValue(string key){returnGetValue(key,"","");}publicstringGetValue(string key,string section){returnGetValue(key, section,"");}publicstringGetValue(string key,string section,string@default){if(!ini.ContainsKey(section))return@default;if(!ini[section].ContainsKey(key))return@default;return ini[section][key];}publicstring[]GetKeys(string section){if(!ini.ContainsKey(section))returnnewstring[0];return ini[section].Keys.ToArray();}publicstring[]GetSections(){return ini.Keys.Where(t => t !="").ToArray();}}
und danke für nicht setzen , dass catch (Exception ex) { throw ex; }dort
Mark Schultheiss
1
Gut! Zumindest einige Änderungen sind erforderlich, um besser zu funktionieren. Zeile 16: ini [""] = currentSection; To: // ini [""] = currentSection; Dies muss entfernt werden, da das erste Element [0] aufgrund dieser Initialisierung jedes Mal ein leeres Segment ist. Zeile 36: currentSection [line.Substring (0, idx)] = line.Substring (idx + 1); An: currentSection [line.Substring (0, idx) .Trim ()] = line.Substring (idx + 1) .Trim (); Schlüssel und Werte sollten unabhängig voneinander zugeschnitten werden, nicht nur in der Zeile Trimmen. In INI-ähnlichen Konfigurationsdateien neigen normalerweise diejenigen, die K-> V-Paare hinzufügen, dazu, diese Gleichheit innerhalb von Abschnitten auszurichten. Danke dir!
LXSoft
Es war lange her. Vielen Dank für Ihre Vorschläge. Sie alle machen Sinn und verdienen diesen Code für eine gute Aktualisierung.
Larry
13
Ich möchte eine IniParser-Bibliothek einführen, die ich vollständig in c # erstellt habe, damit sie in keinem Betriebssystem Abhängigkeiten enthält, wodurch sie Mono-kompatibel ist. Open Source mit MIT-Lizenz - kann also in jedem Code verwendet werden.
Wenn Sie nur Lese- und keinen Schreibzugriff benötigen und das verwenden Microsoft.Extensions.Confiuration(wird standardmäßig mit ASP.NET Core geliefert, funktioniert aber auch mit regulären Programmen), können Sie mit dem NuGet-Paket Microsoft.Extensions.Configuration.IniINI-Dateien in Ihre Konfigurationseinstellungen importieren.
Nur um hinzuzufügen, dass Sie dann Schlüssel mitConfiguration["keyname"]
Kofifus
@scott Das Problem ist, dass IIS es aus irgendeinem Grund nicht erkennt, wenn die App ausgeführt wird. Es wird dort bereitgestellt, aber nicht verbraucht. HTTP 500.30 wird zurückgegeben und im IIS-App-Protokoll wird angezeigt, dass die Konfigurationsdatei nicht gefunden wurde und nicht optional ist.
one.beat.consumer
3
Wenn Sie Anwendungen mit C # und dem .NET Framework erstellen, werden normalerweise keine INI-Dateien verwendet. Es ist üblicher, Einstellungen in einer XML-basierten Konfigurationsdatei oder in der Registrierung zu speichern. Wenn Ihre Software jedoch Einstellungen mit einer Legacy-Anwendung teilt, ist es möglicherweise einfacher, die Konfigurationsdatei zu verwenden, als die Informationen an anderer Stelle zu duplizieren.
Das .NET Framework unterstützt die direkte Verwendung von INI-Dateien nicht. Sie können jedoch Windows-API-Funktionen mit Platform Invocation Services (P / Invoke) verwenden, um in die Dateien zu schreiben und aus ihnen zu lesen. In diesem Link erstellen wir eine Klasse, die INI-Dateien darstellt und diese mithilfe von Windows-API-Funktionen bearbeitet. Bitte gehen Sie über den folgenden Link.
Bleib aus der Registrierung heraus! Anwendungskonfigurationsdaten sollten nicht in der Registrierung gespeichert werden.
Deegee
3
Wenn Sie nur einen einfachen Reader ohne Abschnitte und andere DLLs möchten, ist dies eine einfache Lösung:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Tool{publicclassConfig{Dictionary<string,string> values;publicConfig(string path){
values =File.ReadLines(path).Where(line =>(!String.IsNullOrWhiteSpace(line)&&!line.StartsWith("#"))).Select(line => line.Split(newchar[]{'='},2,0)).ToDictionary(parts => parts[0].Trim(), parts => parts.Length>1?parts[1].Trim():null);}publicstringValue(string name,stringvalue=null){if(values!=null&& values.ContainsKey(name)){return values[name];}returnvalue;}}}
Anwendungsbeispiel:
file =newTool.Config(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)+"\\config.ini");
command = file.Value("command");
action = file.Value("action");stringvalue;//second parameter is default value if no key found with this namevalue= file.Value("debug","true");this.debug =(value.ToLower()=="true"||value=="1");value= file.Value("plain","false");this.plain =(value.ToLower()=="true"||value=="1");
Konfigurieren Sie den Inhalt der Datei währenddessen (wie Sie sehen, unterstützt das Symbol # für den Zeilenkommentar):
#command to run
command = php
#default script
action = index.php
#debug mode#debug = true#plain text mode#plain = false#icon = favico.ico
PeanutButter.INI ist eine Nuget-Paketklasse für die Manipulation von INI-Dateien. Es unterstützt Lesen / Schreiben, einschließlich Kommentare - Ihre Kommentare bleiben beim Schreiben erhalten. Es scheint ziemlich beliebt zu sein, ist getestet und einfach zu bedienen. Es ist auch völlig kostenlos und Open Source.
Haftungsausschluss: Ich bin der Autor von PeanutButter.INI.
Ich bin spät dran, um an der Party teilzunehmen, aber ich hatte heute das gleiche Problem und habe die folgende Implementierung geschrieben:
using System.Text.RegularExpressions;staticbool match(thisstring str,string pat,outMatch m)=>(m =Regex.Match(str, pat,RegexOptions.IgnoreCase)).Success;staticvoidMain(){Dictionary<string,Dictionary<string,string>> ini =newDictionary<string,Dictionary<string,string>>();string section ="";foreach(string line inFile.ReadAllLines(.........))// read from file{string ln =(line.Contains('#')? line.Remove(line.IndexOf('#')): line).Trim();if(ln.match(@"^[ \t]*\[(?<sec>[\w\-]+)\]",outMatch m))
section = m.Groups["sec"].ToString();elseif(ln.match(@"^[ \t]*(?<prop>[\w\-]+)\=(?<val>.*)",out m)){if(!ini.ContainsKey(section))
ini[section]=newDictionary<string,string>();
ini[section][m.Groups["prop"].ToString()]= m.Groups["val"].ToString();}}// access the ini file as follows:string content = ini["section"]["property"];}
Es ist zu beachten, dass diese Implementierung keine Abschnitte oder Eigenschaften verarbeitet, die nicht gefunden wurden. Um dies zu erreichen, sollten Sie die Dictionary<,>Klasse erweitern, um nicht gefundene Schlüssel zu verarbeiten.
Um eine Instanz von Dictionary<string, Dictionary<string, string>>in eine .ini-file zu serialisieren , verwende ich den folgenden Code:
string targetpath =.........;Dictionary<string,Dictionary<string,string>> ini =........;StringBuilder sb =newStringBuilder();foreach(string section in ini.Keys){
sb.AppendLine($"[{section}]");foreach(string property in ini[section].Keys)
sb.AppendLine($"{property}={ini[section][property]");}File.WriteAllText(targetpath, sb.ToString());
Für den Fall, dass es nicht offensichtlich ist, die oberste Ebene der Bibliothek zu betrachten (es war mir nicht klar!), Sind die IniDcoument-Klasse und andere in ComLib.IO.
Tim Keating
2
Für alle, die sich diese Route ansehen, scheint CommonLibrary.NET nicht den INI-Konventionen zu folgen. Es wird ein Doppelpunkt ":" als Trennzeichen anstelle des Gleichheitszeichens verwendet und es werden keine Kommentare verarbeitet (das Beginnen einer Zeile mit einem Semikolon oder einem Nummernzeichen führt dazu, dass die Analyse fehlschlägt).
jmmr
2
Hier ist meine eigene Version mit regulären Ausdrücken. In diesem Code wird davon ausgegangen, dass jeder Abschnittsname eindeutig ist. Wenn dies jedoch nicht der Fall ist, ist es sinnvoll, Dictionary durch List zu ersetzen. Diese Funktion unterstützt das Kommentieren von INI-Dateien ab ';' Charakter. Abschnitt beginnt normal [Abschnitt], und Schlüsselwertpaare kommen normalerweise auch "Schlüssel = Wert". Gleiche Annahme wie für Abschnitte - Schlüsselname ist eindeutig.
/// <summary>/// Loads .ini file into dictionary./// </summary>publicstaticDictionary<String,Dictionary<String,String>> loadIni(String file){Dictionary<String,Dictionary<String,String>> d =newDictionary<string,Dictionary<string,string>>();String ini =File.ReadAllText(file);// Remove comments, preserve linefeeds, if end-user needs to count line number.
ini =Regex.Replace(ini,@"^\s*;.*$","",RegexOptions.Multiline);// Pick up all lines from first section to another sectionforeach(Match m inRegex.Matches(ini,"(^|[\r\n])\\[([^\r\n]*)\\][\r\n]+(.*?)(\\[([^\r\n]*)\\][\r\n]+|$)",RegexOptions.Singleline)){String sectionName = m.Groups[2].Value;Dictionary<String,String> lines =newDictionary<String,String>();// Pick up "key = value" kind of syntax.foreach(Match l inRegex.Matches(ini,@"^\s*(.*?)\s*=\s*(.*?)\s*$",RegexOptions.Multiline)){String key = l.Groups[1].Value;Stringvalue= l.Groups[2].Value;// Open up quotation if any.value=Regex.Replace(value,"^\"(.*)\"$","$1");if(!lines.ContainsKey(key))
lines[key]=value;}if(!d.ContainsKey(sectionName))
d[sectionName]= lines;}return d;}
Diese Funktion funktioniert für mich nicht: Sie vergisst jeden zweiten Abschnitt. Ich habe es mit und ohne Leerzeilen vor [Abschnitt] versucht.
Iksess
Können Sie ein Beispiel Ihrer .ini kopieren, das nicht funktioniert?
TarmoPikaro
-3
Hier ist meine Klasse, funktioniert wie ein Zauber:
publicstaticclassIniFileManager{[DllImport("kernel32")]privatestaticexternlongWritePrivateProfileString(string section,string key,string val,string filePath);[DllImport("kernel32")]privatestaticexternintGetPrivateProfileString(string section,string key,string def,StringBuilder retVal,int size,string filePath);[DllImport("kernel32.dll")]privatestaticexternintGetPrivateProfileSection(string lpAppName,byte[] lpszReturnBuffer,int nSize,string lpFileName);/// <summary>/// Write Data to the INI File/// </summary>/// <PARAM name="Section"></PARAM>/// Section name/// <PARAM name="Key"></PARAM>/// Key Name/// <PARAM name="Value"></PARAM>/// Value NamepublicstaticvoidIniWriteValue(string sPath,stringSection,stringKey,stringValue){WritePrivateProfileString(Section,Key,Value, sPath);}/// <summary>/// Read Data Value From the Ini File/// </summary>/// <PARAM name="Section"></PARAM>/// <PARAM name="Key"></PARAM>/// <PARAM name="Path"></PARAM>/// <returns></returns>publicstaticstringIniReadValue(string sPath,stringSection,stringKey){StringBuilder temp =newStringBuilder(255);int i =GetPrivateProfileString(Section,Key,"", temp,255, sPath);return temp.ToString();}
}}
Die Verwendung ist offensichtlich, da es sich um eine statische Klasse handelt. Rufen Sie einfach IniFileManager.IniWriteValue zum Lesen eines Abschnitts oder IniFileManager.IniReadValue zum Lesen eines Abschnitts auf.
Dieser Ansatz wurde bereits in einer anderen Antwort gezeigt und erklärt . Was fügt Ihre Antwort hinzu, die von dieser nicht abgedeckt wird?
Palec
Beachten Sie, dass dies nur funktioniert, wenn die INI-Datei in UNICODE (16-Bit-LE) gespeichert ist. Verwenden Sie Notepad ++, um den Text in Unicode zu konvertieren, denn wenn Sie ihn in UTF-8 speichern, funktioniert er nicht. Auch ANSI ist akzeptabel, aber Sie können keine Buchstaben mit Akzent lesen
user2991288
-6
Sie sollten Daten aus XML-Dateien lesen und schreiben, da Sie ein ganzes Objekt in XML speichern und ein Objekt aus einer gespeicherten XML-Datei füllen können. Es ist besser, Objekte einfach zu manipulieren.
Links zu externen Ressourcen werden empfohlen. Fügen Sie jedoch einen Kontext um den Link hinzu, damit Ihre Mitbenutzer eine Vorstellung davon haben, was es ist und warum es dort ist. Zitieren Sie immer den relevantesten Teil eines wichtigen Links, falls die Zielwebsite nicht erreichbar ist oder dauerhaft offline geht.
Davejal
Ich glaube, dass die Links Titel sehr klar über seine Referenzen / Kontext sind. Wenn Sie der Meinung sind, dass dies nicht ausreicht, können Sie es jederzeit bearbeiten.
Antworten:
Die Ersteller des .NET Frameworks möchten, dass Sie XML-basierte Konfigurationsdateien anstelle von INI-Dateien verwenden. Also nein, es gibt keinen eingebauten Mechanismus zum Lesen.
Es sind jedoch Lösungen von Drittanbietern verfügbar.
quelle
Vorwort
Lesen Sie zunächst diesen MSDN-Blogbeitrag über die Einschränkungen von INI-Dateien . Wenn es Ihren Bedürfnissen entspricht, lesen Sie weiter.
Dies ist eine prägnante Implementierung, die ich unter Verwendung des ursprünglichen Windows P / Invoke geschrieben habe. Sie wird daher von allen Windows-Versionen mit installiertem .NET (dh Windows 98 - Windows 10) unterstützt. Ich gebe es hiermit öffentlich zugänglich - Sie können es ohne Namensnennung kommerziell nutzen.
Die winzige Klasse
Fügen Sie
IniFile.cs
Ihrem Projekt eine neue Klasse hinzu :Wie man es benutzt
Öffnen Sie die INI-Datei auf eine der folgenden drei Arten:
Sie können einige Werte wie folgt schreiben:
So erstellen Sie eine Datei wie folgt:
So lesen Sie die Werte aus der INI-Datei aus:
Optional können Sie Folgendes einstellen
[Section]
:So erstellen Sie eine Datei wie folgt:
Sie können auch prüfen, ob ein Schlüssel wie folgt vorhanden ist:
Sie können einen Schlüssel wie folgt löschen:
Sie können auch einen ganzen Abschnitt (einschließlich aller Schlüssel) wie folgt löschen:
Bitte zögern Sie nicht, mit Verbesserungen zu kommentieren!
quelle
GetSections()
Methode.Path.GetFullPath(IniPath ?? Path.ChangeExtension(Application.ExecutablePath, ".ini"))
.Dieser Artikel über CodeProject " Eine INI- Dateibehandlungsklasse mit C # " sollte helfen.
Der Autor hat eine C # -Klasse "Ini" erstellt, die zwei Funktionen aus KERNEL32.dll verfügbar macht. Diese Funktionen sind:
WritePrivateProfileString
undGetPrivateProfileString
. Sie benötigen zwei Namespaces:System.Runtime.InteropServices
undSystem.Text
.Schritte zur Verwendung der Ini-Klasse
Fügen Sie in Ihrer Projekt-Namespace-Definition hinzu
Erstellen Sie eine INIFile wie diese
Verwenden Sie
IniWriteValue
diese Option , um einen neuen Wert in einen bestimmten Schlüssel in einem Abschnitt zu schreiben oder umIniReadValue
einen Wert aus einem Schlüssel in einem bestimmten Abschnitt zu lesen.Hinweis: Wenn Sie bei Null anfangen, können Sie diesen MSDN-Artikel lesen : Gewusst wie: Hinzufügen von Anwendungskonfigurationsdateien zu C # -Projekten . Dies ist eine bessere Möglichkeit, Ihre Anwendung zu konfigurieren.
quelle
Ich fand diese einfache Implementierung:
http://bytes.com/topic/net/insights/797169-reading-parsing-ini-file-c
Funktioniert gut für das, was ich brauche.
So verwenden Sie es:
Hier ist der Code:
quelle
Der Code in Joerages Antwort ist inspirierend.
Leider ändert es die Groß- und Kleinschreibung der Tasten und behandelt keine Kommentare. Also habe ich etwas geschrieben, das robust genug sein sollte, um (nur) sehr schmutzige INI-Dateien zu lesen und Schlüssel so abzurufen, wie sie sind.
Es verwendet etwas LINQ, ein verschachteltes String-Wörterbuch ohne Berücksichtigung der Groß- und Kleinschreibung, um Abschnitte, Schlüssel und Werte zu speichern und die Datei auf einmal zu lesen.
quelle
catch (Exception ex) { throw ex; }
dortIch möchte eine IniParser-Bibliothek einführen, die ich vollständig in c # erstellt habe, damit sie in keinem Betriebssystem Abhängigkeiten enthält, wodurch sie Mono-kompatibel ist. Open Source mit MIT-Lizenz - kann also in jedem Code verwendet werden.
Sie können die Quelle in GitHub überprüfen und sie ist auch als NuGet-Paket verfügbar
Es ist stark konfigurierbar und sehr einfach zu bedienen .
Entschuldigen Sie den schamlosen Stecker, aber ich hoffe, er kann jedem helfen, der diese Antwort noch einmal überprüft.
quelle
Wenn Sie nur Lese- und keinen Schreibzugriff benötigen und das verwenden
Microsoft.Extensions.Confiuration
(wird standardmäßig mit ASP.NET Core geliefert, funktioniert aber auch mit regulären Programmen), können Sie mit dem NuGet-PaketMicrosoft.Extensions.Configuration.Ini
INI-Dateien in Ihre Konfigurationseinstellungen importieren.quelle
Configuration["keyname"]
Wenn Sie Anwendungen mit C # und dem .NET Framework erstellen, werden normalerweise keine INI-Dateien verwendet. Es ist üblicher, Einstellungen in einer XML-basierten Konfigurationsdatei oder in der Registrierung zu speichern. Wenn Ihre Software jedoch Einstellungen mit einer Legacy-Anwendung teilt, ist es möglicherweise einfacher, die Konfigurationsdatei zu verwenden, als die Informationen an anderer Stelle zu duplizieren.
Das .NET Framework unterstützt die direkte Verwendung von INI-Dateien nicht. Sie können jedoch Windows-API-Funktionen mit Platform Invocation Services (P / Invoke) verwenden, um in die Dateien zu schreiben und aus ihnen zu lesen. In diesem Link erstellen wir eine Klasse, die INI-Dateien darstellt und diese mithilfe von Windows-API-Funktionen bearbeitet. Bitte gehen Sie über den folgenden Link.
Lesen und Schreiben von INI-Dateien
quelle
Wenn Sie nur einen einfachen Reader ohne Abschnitte und andere DLLs möchten, ist dies eine einfache Lösung:
Anwendungsbeispiel:
Konfigurieren Sie den Inhalt der Datei währenddessen (wie Sie sehen, unterstützt das Symbol # für den Zeilenkommentar):
quelle
Versuchen Sie diese Methode:
Es wird das Wörterbuch erstellt, in dem der Schlüssel "-" lautet. Sie können es folgendermaßen laden:
quelle
PeanutButter.INI ist eine Nuget-Paketklasse für die Manipulation von INI-Dateien. Es unterstützt Lesen / Schreiben, einschließlich Kommentare - Ihre Kommentare bleiben beim Schreiben erhalten. Es scheint ziemlich beliebt zu sein, ist getestet und einfach zu bedienen. Es ist auch völlig kostenlos und Open Source.
Haftungsausschluss: Ich bin der Autor von PeanutButter.INI.
quelle
Ich bin spät dran, um an der Party teilzunehmen, aber ich hatte heute das gleiche Problem und habe die folgende Implementierung geschrieben:
Es ist zu beachten, dass diese Implementierung keine Abschnitte oder Eigenschaften verarbeitet, die nicht gefunden wurden. Um dies zu erreichen, sollten Sie die
Dictionary<,>
Klasse erweitern, um nicht gefundene Schlüssel zu verarbeiten.Um eine Instanz von
Dictionary<string, Dictionary<string, string>>
in eine.ini
-file zu serialisieren , verwende ich den folgenden Code:quelle
In CommonLibrary.NET ist ein Ini-Parser verfügbar
Dies hat verschiedene sehr bequeme Überlastungen zum Abrufen von Abschnitten / Werten und ist sehr leicht.
quelle
Hier ist meine eigene Version mit regulären Ausdrücken. In diesem Code wird davon ausgegangen, dass jeder Abschnittsname eindeutig ist. Wenn dies jedoch nicht der Fall ist, ist es sinnvoll, Dictionary durch List zu ersetzen. Diese Funktion unterstützt das Kommentieren von INI-Dateien ab ';' Charakter. Abschnitt beginnt normal [Abschnitt], und Schlüsselwertpaare kommen normalerweise auch "Schlüssel = Wert". Gleiche Annahme wie für Abschnitte - Schlüsselname ist eindeutig.
quelle
Hier ist meine Klasse, funktioniert wie ein Zauber:
}}
Die Verwendung ist offensichtlich, da es sich um eine statische Klasse handelt. Rufen Sie einfach IniFileManager.IniWriteValue zum Lesen eines Abschnitts oder IniFileManager.IniReadValue zum Lesen eines Abschnitts auf.
quelle
Sie sollten Daten aus XML-Dateien lesen und schreiben, da Sie ein ganzes Objekt in XML speichern und ein Objekt aus einer gespeicherten XML-Datei füllen können. Es ist besser, Objekte einfach zu manipulieren.
So geht's: Objektdaten in eine XML-Datei schreiben: https://msdn.microsoft.com/en-us/library/ms172873.aspx Objektdaten aus einer XML-Datei lesen: https://msdn.microsoft. com / de-de / library / ms172872.aspx
quelle