运行我在64位Vista上编写的c#控制台应用程序。这是代码:
class Class1
{
static void Main(string[] args)
{
Debug.Assert(File.Exists(@"c:\test.ini"));
StringBuilder sb = new StringBuilder(500);
uint res = GetPrivateProfileString("AppName", "KeyName", "", sb, sb.Capacity, @"c:\test.ini");
Console.WriteLine(sb.ToString());
}
[DllImport("kernel32.dll")]
static extern uint GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, int nSize, string lpFileName);
}
我相信我会得到一个很大的“DUH!”作为答案,但我不明白为什么这不起作用。除了Debug.Assert之外,此代码是从this page
处的c#示例中删除的答案 0 :(得分:5)
这一整天都在破坏我的排骨。我想我找到了一个解决方法,我真的不想处理它:在.ini文件的第一个节头之前插入一个空行。现在运行您的应用程序,看看您是否开始看到您期望的值。
考虑到这个错误显然已存在多年,我很惊讶MS现在还没有解决它。但是,几年前.ini文件应该已经消失了。这当然很有趣,因为MS使用很多地方.ini文件(例如desktop.ini)。但我认为MS知道这个错误,因为我注意到我的desktop.ini文件包含一个前导空行。嗯...
答案 1 :(得分:1)
我看到的主要是你应该为nSize传递一个 uint ,以及返回值。这是因为GetPrivateProfileString的return和nSize参数是DWORD
值,它们是无符号的32位整数。
我个人使用PInvoke.net上的语法:
[DllImport("kernel32.dll", CharSet=CharSet.Unicode)]
static extern uint GetPrivateProfileString(
string lpAppName,
string lpKeyName,
string lpDefault,
StringBuilder lpReturnedString,
uint nSize,
string lpFileName);
此外,除非文件位于Windows目录中,否则您需要将文件的完整路径放在适当的位置。来自文档:
如果此参数不包含文件的完整路径,系统将在Windows目录中搜索该文件。
答案 2 :(得分:1)
如果未指定路径,GetPrivateProfileString将在Windows目录中查找Test.ini。
像GetPrivateProfileString这样的旧API不能很好地处理Unicode(即使有GetPrivateProfileStringW函数)。如果Test.ini包含UTF标头或Unicode字符,则可能足以阻止GetPrivateProfileString正常工作。
此外,Vista的UAC可以处理处于“特殊”位置的文件很棘手(C:\,C:\ Windows,C:\ Program Files等)。尝试将Test.ini放在文件夹中,而不是放在C:驱动器的根目录中,或者关闭UAC。有一个thread on CodeProject讨论了GetPrivateProfileString在尝试从UAC控制的文件夹中读取.ini时无声地失败。
答案 3 :(得分:0)
根据pinvoke.net,nSize应该是UINT。他们也在他们的例子中使用绝对路径。
除了这些差异之外,我什么也看不见。
假设它抛出了无效的格式异常,请尝试将目标平台设置为x86以解决问题。
pinvoke.net的用法示例是
[DllImport("kernel32.dll", CharSet=CharSet.Unicode)]
static extern uint GetPrivateProfileString(
string lpAppName,
string lpKeyName,
string lpDefault,
StringBuilder lpReturnedString,
uint nSize,
string lpFileName);
static void Main(string[] args)
{
StringBuilder sb = new StringBuilder(500);
uint res = GetPrivateProfileString("AppName", "KeyName", "", sb, (uint)sb.Capacity, @"c:\test.ini");
Console.WriteLine(sb.ToString());
}
答案 4 :(得分:0)
也许你应该研究一下开源解决方案,它可以做到这一点而不用担心p / Invoke。针对.NET的项目名为nini我在我正在开发的项目中使用它,我推荐它。
希望这有帮助, 最好的祝福, 汤姆。
答案 5 :(得分:0)
您可以验证test.ini
文件的内容吗?鉴于您尝试过的所有步骤,我开始怀疑您的数据文件格式不正确(拼写错误等)换句话说,GetPrivateProfileString
可能“正在工作”,但只是没有找到你的字符串。根据您发布的代码,您的test.ini
文件应如下所示:
[AppName的]
关键名= FOO