Прочитайте все значения ini-файла с помощью GetPrivateProfileString
Мне нужен способ прочитать все разделы / ключи 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 и перечислить?
Спасибо за вашу помощь!
приветствует leon22
5 ответов
возможное решение:
[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('').Split('');
List<string> result = new List<string>();
foreach (String entry in tmp)
{
result.Add(entry.Substring(0, entry.IndexOf("=")));
}
return result;
}
Я считаю, что есть также GetPrivateProfileSection()
Это может помочь, но я согласен с Zenwalker, есть библиотеки, которые могут помочь в этом. 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;
}
/// <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;
}
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. Иначе, если эта функция не удалась из - за отсутствия достаточного размера буфера, RetVal будет содержать BufferSize-2. Поэтому мы можем проверить его и снова вызвать эту функцию с большим BufferSize.
'теперь, вот как мы можем получить строку из памяти.
MyString = Marshal.PtrToStringAuto(PtrToString, RetVal - 1)
'здесь я использую " RetVal-1", чтобы избежать дополнительная нулевая строка.
' теперь нам нужно разделить строку, в которой появляются нулевые символы.
Dim MyStrArray() As String = MyString.Split(vbNullChar)
таким образом, этот массив содержит всю вашу пару keyvalue в этом конкретном разделе. И не забудьте освободить память
Marshal.FreeHGlobal(PtrToString)