WritePrivateProfileString - 不可预测
WritePrivateProfileString - is unpredictable
我们使用的工具在内部使用简单的 Win-Api 调用 WritePrivateProfileString
。
我知道定义标志 UNICODE 映射到 WritePrivateProfileString**A**
或 WritePrivateProfileString**W**
我正在向 INI 文件写入一些内容,该文件之前不存在。
并且它在某些系统上的行为有所不同。为什么?
例如:一个字符“§”在ASCI中是A7(十六进制),有时写成Unicode格式C2 A7(十六进制)。
但只在某些系统上,我不知道为什么?!写入 ANSI 或 UNICODE 的系统条件是什么?
我试图先创建文件,然后再写入文件,甚至尝试通过添加一些字符来定义格式,因为我认为 WritePrivateProfileString
在内部使用 isTextUnicode
,
但这里没有机会。
有没有人理解这个API-正确的文档:
https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-writeprivateprofilestringa
If the file was created using Unicode characters, the function writes Unicode characters to the file. Otherwise, the function writes ANSI characters.
我真的不能同意这里的文档。我知道我在这里一定是错的 ;-) 或者如何做对?
我们想要的只是在任何情况下将任何系统写入任何系统,只是将普通 ANSI 写入 INI 文件。 (我无法将其更改为 WritePrivateProfileString**A**
方法,因为我们使用的工具仅在内部使用 WritePrivateProfileString
函数。)无论如何,它适用于 90% 的 PC 是正确的,但是有些我们在 INI 文件中仍然有 unicode 字母。
我也知道 ASCI 不是最先进的,但我们正在对该 INI 值执行一些 CRC 计算,而“A7”不是“C2 A7”,这会导致计算错误,这就是为什么我们需要纯 ASCII 格式的背景。
感谢您的帮助。
我找到了根本原因:
https://en.wikipedia.org/wiki/Unicode_in_Microsoft_Windows
In April 2018 with insider build 17035 (nominal build 17134) for Windows 10, a "Beta: Use Unicode UTF-8 for worldwide language support" checkbox appeared for setting the locale code page to UTF-8.[a] This allows for calling "narrow" functions, including fopen and SetWindowTextA, with UTF-8 strings. In May 2019 Microsoft added the ability for a program to set the code page to UTF-8 itself, and started recommending that all software do this and use UTF-8 exclusively.
此设置在某些系统上已激活,它负责将 INI-file 中我预期的 ANSI 代码更改为 UNICODE。
是的,我明白我们以后要往UNICODE方向走。不过现在微软也把我们往这个方向推了,这也不错,只是以前不知道这个设定或者策略。
@IInspectable:是的,你是对的,0xA7 不是 ASCII,而是 ANSI(或 ASCII-8,扩展 ASCII),我搞混了,谢谢。
始终使用 WritePrivateProfileStringW
版本。
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true,
EntryPoint = "WritePrivateProfileStringW")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WritePrivateProfileString(string lpAppName, string lpKeyName, string lpString, string lpFileName);
当INI文件不存在时,用Unicode文件标记(前两个字节FF FE)创建。通过这种方式,所有字符串都存储为 Unicode。要创建一个空白的 ini 文件,您可以使用:
File.WriteAllText(ini_file_path, "; Your comment\r\n", Encoding.Unicode);
建议在blank/comment行开头。至少写 "\r\n"
.
我们使用的工具在内部使用简单的 Win-Api 调用 WritePrivateProfileString
。
我知道定义标志 UNICODE 映射到 WritePrivateProfileString**A**
或 WritePrivateProfileString**W**
我正在向 INI 文件写入一些内容,该文件之前不存在。
并且它在某些系统上的行为有所不同。为什么?
例如:一个字符“§”在ASCI中是A7(十六进制),有时写成Unicode格式C2 A7(十六进制)。 但只在某些系统上,我不知道为什么?!写入 ANSI 或 UNICODE 的系统条件是什么?
我试图先创建文件,然后再写入文件,甚至尝试通过添加一些字符来定义格式,因为我认为 WritePrivateProfileString
在内部使用 isTextUnicode
,
但这里没有机会。
有没有人理解这个API-正确的文档:
https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-writeprivateprofilestringa
If the file was created using Unicode characters, the function writes Unicode characters to the file. Otherwise, the function writes ANSI characters.
我真的不能同意这里的文档。我知道我在这里一定是错的 ;-) 或者如何做对?
我们想要的只是在任何情况下将任何系统写入任何系统,只是将普通 ANSI 写入 INI 文件。 (我无法将其更改为 WritePrivateProfileString**A**
方法,因为我们使用的工具仅在内部使用 WritePrivateProfileString
函数。)无论如何,它适用于 90% 的 PC 是正确的,但是有些我们在 INI 文件中仍然有 unicode 字母。
我也知道 ASCI 不是最先进的,但我们正在对该 INI 值执行一些 CRC 计算,而“A7”不是“C2 A7”,这会导致计算错误,这就是为什么我们需要纯 ASCII 格式的背景。
感谢您的帮助。
我找到了根本原因:
https://en.wikipedia.org/wiki/Unicode_in_Microsoft_Windows
In April 2018 with insider build 17035 (nominal build 17134) for Windows 10, a "Beta: Use Unicode UTF-8 for worldwide language support" checkbox appeared for setting the locale code page to UTF-8.[a] This allows for calling "narrow" functions, including fopen and SetWindowTextA, with UTF-8 strings. In May 2019 Microsoft added the ability for a program to set the code page to UTF-8 itself, and started recommending that all software do this and use UTF-8 exclusively.
此设置在某些系统上已激活,它负责将 INI-file 中我预期的 ANSI 代码更改为 UNICODE。
是的,我明白我们以后要往UNICODE方向走。不过现在微软也把我们往这个方向推了,这也不错,只是以前不知道这个设定或者策略。
@IInspectable:是的,你是对的,0xA7 不是 ASCII,而是 ANSI(或 ASCII-8,扩展 ASCII),我搞混了,谢谢。
始终使用
WritePrivateProfileStringW
版本。[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "WritePrivateProfileStringW")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WritePrivateProfileString(string lpAppName, string lpKeyName, string lpString, string lpFileName);
当INI文件不存在时,用Unicode文件标记(前两个字节FF FE)创建。通过这种方式,所有字符串都存储为 Unicode。要创建一个空白的 ini 文件,您可以使用:
File.WriteAllText(ini_file_path, "; Your comment\r\n", Encoding.Unicode);
建议在blank/comment行开头。至少写 "\r\n"
.