Прочитать все значения INI-файла с помощью GetPrivateProfileString - PullRequest
11 голосов
/ 17 августа 2011

Мне нужен способ прочитать все разделы / ключи ini-файла в переменной StringBuilder:

[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 ]

19 голосов
/ 19 августа 2011

Возможное решение:

[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;
}
2 голосов
/ 17 августа 2011

Я верю, что есть также GetPrivateProfileSection(), который может помочь, но я согласен с Zenwalker, есть библиотеки, которые могут помочь с этим. INI-файлы не так сложны для чтения: разделы, ключ / значение и комментарии - это почти все.

1 голос
/ 17 августа 2011

Почему вы не используете библиотеку IniReader для чтения INI-файлов? так проще и быстрее.

0 голосов
/ 09 декабря 2017
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)

Таким образом, этот массив содержит все ваши пары ключей в этом конкретном разделе. И не забудьте освободить память

Marshal.FreeHGlobal(PtrToString)
0 голосов
/ 10 января 2016

Эти подпрограммы будут читать весь раздел INI и либо возвращать раздел как коллекцию необработанных строк, где каждая запись представляет собой одну строку в файле INI (полезно, если вы используете структуру INI, но не обязательно имеете an =) и другой, который возвращает коллекцию пар ключ-значение для всех записей в разделе.

    [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;
    }
...