使用 GetPrivateProfileString 读取所有 ini 文件值

发布于 2024-11-30 03:42:06 字数 608 浏览 2 评论 0原文

我需要一种方法来读取 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?

感谢您的帮助!

问候莱昂22

I need a way to read all sections/keys of ini file in a StringBuilder variable:

[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);

    ...
}

In returnString is only the first key value! How it is possible to get all at once and write it to the StringBuilder and to List?

Thank you for your help!

greets leon22

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

乱了心跳 2024-12-07 03:42:06

可能的解决方案:

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

Possible solution:

[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;
}
亽野灬性zι浪 2024-12-07 03:42:06

我相信还有 GetPrivateProfileSection() 可以提供帮助,但我同意 Zenwalker 的观点,有一些库可以帮助解决这个问题。 INI 文件并不难读:部分、键/值和注释就差不多了。

I believe there's also GetPrivateProfileSection() that could help, but I agree with Zenwalker, there are libraries that could help with this. INI files aren't that hard to read: sections, key/value and comments is pretty much it.

深巷少女 2024-12-07 03:42:06

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

Why dont you use IniReader library to read INI files?? its easier and faster that way.

复古式 2024-12-07 03:42:06

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

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

These routines will read an entire INI section, and either return the section as a collection of raw strings where each entry is a single line in the INI file (useful if you're using the INI structure but don't necessarily have an =), and another that returns a collection of keyvalue pairs for all of the entries in the section.

    [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;
    }
謸气贵蔟 2024-12-07 03:42:06
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)
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)

If our function call succeeds, we will get the result in PtrToString memory address and RetVal will contain the length of the string in PtrToString. Else if this function failed due to the lack of enough BufferSize Then RetVal will contain BufferSize - 2. So we can check it and call this function again with larger BufferSize.

'Now, here is how we can get the string from memory address.

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

'Here i use " RetVal - 1 " to avoid the extra null string.

' Now, we need to split the string where null chars coming.

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

So this array contains all your keyvalue pair in that specific section.
And dont forget to free up the memory

Marshal.FreeHGlobal(PtrToString)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文