使用GetPrivateProfileString读取所有ini文件值

时间:2011-08-17 08:48:40

标签: c# stringbuilder 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<string> GetKeys(string iniFile, string category)
{
    StringBuilder returnString = new StringBuilder(255);            

    GetPrivateProfileString(category, null, null, returnString, 32768, iniFile);

    ...
}

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

感谢您的帮助!

迎接leon22

5 个答案:

答案 0 :(得分:19)

可能的解决方案:

[DllImport("kernel32.dll")]
private static extern int GetPrivateProfileSection(string lpAppName, byte[] lpszReturnBuffer, int nSize, string lpFileName);

private List<string> 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<string> result = new List<string>();

    foreach (String entry in tmp)
    {
        result.Add(entry.Substring(0, entry.IndexOf("=")));
    }

    return result;
}

答案 1 :(得分:2)

我相信还有GetPrivateProfileSection()可以帮助,但我同意Zenwalker,有些图书馆可以提供帮助。 INI文件并不难读:部分,键/值和注释几乎就是它。

答案 2 :(得分:1)

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

答案 3 :(得分:0)

这些例程将读取整个INI部分,并将该部分作为原始字符串的集合返回,其中每个条目在INI文件中是单行(如果您使用INI结构但不一定有an =),另一个返回该部分中所有条目的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;
    }

    /// <summary> Return an entire INI section as a list of lines.  Blank lines are ignored and all spaces around the = are also removed. </summary>
    /// <param name="section">[Section]</param>
    /// <param name="file">INI File</param>
    /// <returns> List of lines </returns>
    public static IEnumerable<KeyValuePair<string, string>> GetIniSection(string section, string file) {
        var result = new List<KeyValuePair<string, string>>();
        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<string, string>(m.Groups[1].Value, m.Groups[2].Value)
                               : new KeyValuePair<string, string>(line, ""));
            }
        }

        return result;
    }

答案 4 :(得分:0)

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)