写入INI文件中的部分

时间:2014-02-20 22:24:36

标签: c# ini

我已经在这里使用了这个课程http://www.codeproject.com/Articles/1966/An-INI-file-handling-class-using-C并且效果很好,我试图将其扩展到处理部分。

[DllImport("kernel32")]
private static extern long WritePrivateProfileSection(string section,
string val, string filePath);

public void IniWriteSection(string Section, string Value)
{
    WritePrivateProfileSection(Section, Value, this.path);
    WritePrivateProfileSection(null, null, null);
 }

如果快速连续编辑INI文件,我原本在编写两次数据时遇到了一些麻烦,所以添加了

WritePrivateProfileSection(null, null, null);

部分,这似乎解决了问题,但它又开始发生了,所以我猜它没有用。

有没有人对我做错了什么有建议?

2 个答案:

答案 0 :(得分:2)

问题是你写入ini文件的内容无效。您编写的值必须采用key1=value1\0key2=value2\0形式。根据您之前对原始代码的修订,您不会以该形式编写任何内容,只需填写文本。

ini文件解析器会在节开始后将任何内容视为该节的一部分。但是,它仅将key=value行视为有效键/值对。它只会替换最后一个有效键/值对的任何内容。除此之外的任何其他内容都将保留原样。

至少......这就是我所观察到的......我不知道这是否是Windows实施的实际规范。


您必须使用正确的格式编写。您编写的每个值都必须与密钥配对。应将多个值写为由空字符分隔的单独键。如果要写多行,则必须将它们写入单独的(唯一)键。

你应该使用更像这样的东西:

public class IniFile
{
    private readonly string path;
    public IniFile(string path)
    {
        if (path == null)
            throw new ArgumentNullException("path");
        this.path = path;
    }
    public string Path { get { return path; } }

    public bool WriteSection(string section, string key, IEnumerable<string> lines)
    {
        if (String.IsNullOrWhiteSpace(section))
            return false;
        if (String.IsNullOrWhiteSpace(key))
            return false;
        return WritePrivateProfileSection(section, ToSectionValueString(key, lines));
    }

    private string ToSectionValueString(String key, IEnumerable<string> lines)
    {
        if (lines == null)
            return null;
        if (lines.Count() == 1)
            return key + "=" + lines.Single();
        return String.Join("\0",
            lines.Select((line, i) => (key + "." + i) + "=" + line)
        );
    }

    public bool WriteSection(string section, IEnumerable<KeyValuePair<string, string>> values)
    {
        if (String.IsNullOrWhiteSpace(section))
            return false;
        return WritePrivateProfileSection(section, ToSectionValueString(values));
    }

    private string ToSectionValueString(IEnumerable<KeyValuePair<string, string>> values)
    {
        if (values == null)
            return null;
        return String.Join("\0", values.Select(kvp => kvp.Key + "=" + kvp.Value));
    }

    public List<KeyValuePair<string, string>> ReadSection(string section)
    {
        var buff = new byte[SectionSizeMax];
        var count = GetPrivateProfileSection(section, buff);
        return ToSectionValueList(buff, (int)count);
    }

    private List<KeyValuePair<string, string>> ToSectionValueList(byte[] buff, int count)
    {
        return EnumerateValues(buff, count)
            .Select(v => v.Split('='))
            .Where(s => s.Length == 2)
            .Select(s => new KeyValuePair<string, string>(s[0], s[1]))
            .ToList();
    }

    private IEnumerable<string> EnumerateValues(byte[] buff, int count)
    {
        var value = new StringBuilder();
        foreach (var b in buff)
        {
            var c = (char)b;
            if (c != '\0')
            {
                value.Append(c);
            }
            else
            {
                yield return value.ToString();
                value.Clear();
            }
        }
    }

    [DllImport("kernel32")]
    private static extern bool WritePrivateProfileSection(string lpAppName, string lpString, string lpFileName);
    private bool WritePrivateProfileSection(string lpAppName, string lpString)
    {
        return WritePrivateProfileSection(lpAppName, lpString, path);
    }

    [DllImport("kernel32")]
    private static extern uint GetPrivateProfileSection(string lpAppName, byte[] lpReturnedString, uint nSize, string lpFileName);
    private uint GetPrivateProfileSection(string lpAppName, byte[] lpReturnedString)
    {
        return GetPrivateProfileSection(lpAppName, lpReturnedString, (uint)lpReturnedString.Length, path);
    }
    const uint SectionSizeMax = 0x7FFF;
}

然后这样写:

var lines = new List<string>();
lines.Add("...");
lines.Add("...");
// ...

ini.WriteSection("autoexec", "line", lines);

答案 1 :(得分:1)

我找到了一种解决方法,您需要删除您要写的部分

ini.IniWriteValue("autoexec", null, null);

然后写下你的部分

ini.IniWriteSection("autoexec", strAutoexecSection);

此行不是必需的。

WritePrivateProfileSection(null, null, null);