使用GetPrivateProfileString读取所有ini文件值

我需要一种方法来读取StringBuilder变量中的ini文件的所有部分/键:

[DllImport("kernel32.dll")] private static extern int GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, int nSize, string lpFileName); ... private List GetKeys(string iniFile, string category) { StringBuilder returnString = new StringBuilder(255); GetPrivateProfileString(category, null, null, returnString, 32768, iniFile); ... } 

在returnString中只是第一个键值! 如何一次性获取所有内容并将其写入StringBuilder和List?

谢谢您的帮助!

招呼leon22

可能的方法:

 [DllImport("kernel32.dll")] private static extern int GetPrivateProfileSection(string lpAppName, byte[] lpszReturnBuffer, int nSize, string lpFileName); private List GetKeys(string iniFile, string category) { byte[] buffer = new byte[2048]; GetPrivateProfileSection(category, buffer, 2048, iniFile); String[] tmp = Encoding.ASCII.GetString(buffer).Trim('\0').Split('\0'); List result = new List(); foreach (String entry in tmp) { result.Add(entry.Substring(0, entry.IndexOf("="))); } return result; } 

我相信也有GetPrivateProfileSection()可以帮助,但我同意Zenwalker,有些库可以帮助解决这个问题。 INI文件并不难读:部分,键/值和注释几乎就是它。

为什么不使用IniReader库来读取INI文件? 它更简单,更快捷。

这些例程将读取整个INI部分,并将该部分作为原始字符串的集合返回,其中每个条目是INI文件中的单行(如果您使用INI结构但不一定具有=,则非常有用) ,另一个返回该部分中所有条目的keyvalue对的集合。

  [DllImport("kernel32.dll")] public static extern uint GetPrivateProfileSection(string lpAppName, IntPtr lpReturnedString, uint nSize, string lpFileName); // ReSharper disable once ReturnTypeCanBeEnumerable.Global public static string[] GetIniSectionRaw(string section, string file) { string[] iniLines; GetPrivateProfileSection(section, file, out iniLines); return iniLines; } ///  Return an entire INI section as a list of lines. Blank lines are ignored and all spaces around the = are also removed.  /// [Section] /// INI File ///  List of lines  public static IEnumerable> GetIniSection(string section, string file) { var result = new List>(); string[] iniLines; if (GetPrivateProfileSection(section, file, out iniLines)) { foreach (var line in iniLines) { var m = Regex.Match(line, @"^([^=]+)\s*=\s*(.*)"); result.Add(m.Success ? new KeyValuePair(m.Groups[1].Value, m.Groups[2].Value) : new KeyValuePair(line, "")); } } return result; } 
 Dim MyString As String = String.Empty Dim BufferSize As Integer = 1024 Dim PtrToString As IntPtr = IntPtr.Zero Dim RetVal As Integer RetVal = GetPrivateProfileSection(SectionName, PtrToString, BufferSize, FileNameAndPah) 

如果我们的函数调用成功,我们将得到PtrToString内存地址的结果,RetVal将包含PtrToString中字符串的长度。 否则,如果由于缺少足够的BufferSize而导致此函数失败,那么RetVal将包含BufferSize – 2.因此我们可以检查它并使用更大的BufferSize再次调用此函数。

‘现在,这是我们如何从内存地址获取字符串。

 MyString = Marshal.PtrToStringAuto(PtrToString, RetVal - 1) 

‘在这里我使用“RetVal – 1”来避免额外的空字符串。

‘现在,我们需要将字符串拆分为空字符。

 Dim MyStrArray() As String = MyString.Split(vbNullChar) 

因此,此数组包含该特定部分中的所有keyvalue对。 别忘了释放记忆

 Marshal.FreeHGlobal(PtrToString)