Как получить все имена разделов из INI-файла - PullRequest
0 голосов
/ 17 мая 2019

Я хочу получить список разделов из INI-файла. У меня сейчас только один раздел в моем файле, и мой код ниже возвращает ноль.

Я пробовал различные методы, используя GetSectionNamesListA и GetPrivateProfileSectionNames.Кажется, ни один из них не помогает

   public string[] GetSectionNames(string path)
    {
        byte[] buffer = new byte[1024];
        GetPrivateProfileSectionNames(buffer, buffer.Length, path);
        string allSections = System.Text.Encoding.Default.GetString(buffer);
        string[] sectionNames = allSections.Split('\0');
        return sectionNames;
    }

Использование:

[DllImport("kernel32")]
  static extern int GetPrivateProfileSectionNames(byte[] pszReturnBuffer, int nSize, string lpFileName);

Я получаю нулевое возвращение, несмотря на наличие раздела.

1 Ответ

0 голосов
/ 17 мая 2019

Самый простой способ - использовать такую ​​библиотеку, как INI Parser

Вот пример использования библиотеки:

var parser = new FileIniDataParser();
IniData data = parser.ReadFile("file.ini");
foreach (var section in data.Sections)
{
   Console.WriteLine(section.SectionName);
}

А в вашем случае GetPrivateProfileSectionNames не дает имен разделов, потому что ожидает полный путь к файлу. Если вы укажете относительный путь, он попытается найти его в папке Windows.

Имя файла инициализации. Если этот параметр равен NULL, функция ищет файл Win.ini. Если этот параметр не содержит полный путь к файлу, система выполняет поиск файла в каталоге Windows.

Один из способов исправить это использовать Path.GetFullPath(path):

path = Path.GetFullPath(path);

А на этой странице показано правильное использование GetPrivateProfileSectionNames:

[DllImport("kernel32")]
static extern uint GetPrivateProfileSectionNames(IntPtr pszReturnBuffer, uint nSize, string lpFileName);

public static string[] SectionNames(string path)
{
    path = Path.GetFullPath(path);
    uint MAX_BUFFER = 32767;
    IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER);
    uint bytesReturned = GetPrivateProfileSectionNames(pReturnedString, MAX_BUFFER, path);
    if (bytesReturned == 0)
        return null;
    string local = Marshal.PtrToStringAnsi(pReturnedString, (int)bytesReturned).ToString();
    Marshal.FreeCoTaskMem(pReturnedString);
    //use of Substring below removes terminating null for split
    return local.Substring(0, local.Length - 1).Split('\0');
}
...