問題是,你寫入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);
後的代碼中要更新的INI文件。 – Aybe
1966年聽起來很正確;)似乎可能有這方面的已知問題。看到這個討論:http://www.codeproject.com/Questions/200917/WritePrivateProfileSection-does-not-over-write。你應該開始考慮使用除ini文件之外的其他東西。 –
我還不能,因爲我問了這個問題還沒有8個小時。 – Beresford