我已经在这里使用了这个课程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);
部分,这似乎解决了问题,但它又开始发生了,所以我猜它没有用。
有没有人对我做错了什么有建议?
答案 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);