我在利用这个装置..。方法(如SetupGetLineText)从inf文件中读取某些内容(我需要这样做,而不是对泛型ini解析器感兴趣)。这些方法使用Windows1252编码,我需要将其转换为Unicode。我使用了一个字符串,比如这个(输入是string类型的):
Encoding.UTF8.GetString(Encoding.GetEncoding(1252).GetBytes(input));
即使这很好,您也可以立即从SetupGetLineText方法(和其他方法)中检索字节。但是,我现在并不完全确定如何转换字节,因为它们与Encoding.GetEncoding(1252)返回的字节不同。为了更清楚地说明这一点,我上传了一个当前情况的屏幕截图。正如您所看到的,大多数字符是匹配的(忽略0),但是有几种不同的情况。例如,4和5是26和32,而字符串变体仅列出130。从26到32到130怎么走?或者更好的方法是,如何直接从字节数组转到UTF-8字符串?
一些代码:
public static readonly IntPtr INVALID_HANDLE = new IntPtr(-1);
public const int INF_STYLE_OLDNT = 0x00000001;
public const int INF_STYLE_WIN4 = 0x00000002;
[StructLayout(LayoutKind.Sequential)]
public struct InfContext
{
IntPtr Inf;
IntPtr CurrentInf;
uint Section;
uint Line;
}
[DllImport("setupapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool SetupGetLineText([MarshalAs(UnmanagedType.Struct)] ref InfContext context, IntPtr infHandle, string section, string key, string returnBuffer, int returnBufferSize, out int requiredSize);
[DllImport("setupapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr SetupOpenInfFile([MarshalAs(UnmanagedType.LPWStr)] string fileName, [MarshalAs(UnmanagedType.LPWStr)] string infClass, Int32 infStyle, out uint errorLine);
[DllImport("setupapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool SetupEnumInfSections(IntPtr infHandle, uint index, string returnBuffer, int returnBufferSize, out int requiredSize);
[DllImport("setupapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool SetupFindFirstLine(IntPtr infHandle, string section, string key, [MarshalAs(UnmanagedType.Struct)]ref InfContext context);
[DllImport("setupapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool SetupFindNextLine([MarshalAs(UnmanagedType.Struct)] ref InfContext contextIn, [MarshalAs(UnmanagedType.Struct)] ref InfContext contextOut);
[DllImport("setupapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool SetupFindNextMatchLine([MarshalAs(UnmanagedType.Struct)] ref InfContext contextIn, string key, [MarshalAs(UnmanagedType.Struct)] ref InfContext contextOut);
// InfFile class
public InfFile(string path)
{
_file = path;
}
public bool Open()
{
uint errorLineNumber;
_handle = NativeMethodsInf.SetupOpenInfFile(_file, null, INF_STYLE_OLDNT | INF_STYLE_WIN4, out errorLineNumber);
return _handle != INVALID_HANDLE;
}
public string EnumSection(uint index)
{
int requiredSize;
string result = String.Empty.PadLeft(75-1);
bool success = SetupEnumInfSections(_handle, index, result, 75, out requiredSize);
if (requiredSize > 75)
{
result = result.PadLeft(requiredSize - 1);
success = SetupEnumInfSections(_handle, index, result, requiredSize, out requiredSize);
}
return !success ? null : result.Substring(0, requiredSize - 1); // Still needs to be converted to proper encoding.
}
public InfLine FindFirstLine(string section)
{
return FindFirstKey(section, null);
}
public InfLine FindFirstKey(string section, string key)
{
InfContext infContext = new InfContext();
return !SetupFindFirstLine(_handle, section, key, ref infContext) ? null : new InfLine(infContext);
}
// InfLine class
public bool FindNextLine()
{
return SetupFindNextLine(ref _context, ref _context);
}
public bool FindNextMatchLine(string key)
{
return SetupFindNextMatchLine(ref _context, key, ref _context);
}
public string GetCompleteValue()
{
int requiredSize;
string result = String.Empty.PadLeft(250-1);
bool success = SetupGetLineText(ref _context, IntPtr.Zero, null, null, result, 250, out requiredSize);
if (requiredSize > 250)
{
result = result.PadLeft(requiredSize - 1);
success = SetupGetLineText(ref _context, IntPtr.Zero, null, null, result, requiredSize, out requiredSize);
}
return !success ? null : result.Substring(0, requiredSize - 1);
}
// And then use with something like:
using (InfFile file = new InfFile(@"..\..\..\test.inf"))
{
if (file.Open())
{
uint currentSection = 0;
string section;
while ((section = file.EnumSection(currentSection++)) != null)
{
Console.WriteLine("Section: " + section);
var x = file.FindFirstKey(section, null);
if (x != null)
while (true)
{
string key = x.GetFieldValue(0);
string value = x.GetCompleteValue();
Console.WriteLine("Key: " + key + " || Value: " + value);
if (!x.FindNextLine())
break;
}
}
}
}实例inf:
; German Specific
[Strings.0007] ; German
Provider="Hewlett-Packard"
Mfg="Hewlett-Packard"
CD="hp cd"
BUTTON_SCAN="Taste "Scannen" gedrückt"
LAUNCH_APPLICATION_SCAN="HP Scansoftware"
; Japanese Specific
[Strings.0411] ; Japanese
Provider="Hewlett-Packard"
Mfg="Hewlett-Packard"
CD="hp cd"
BUTTON_SCAN="[スキャン] ボタンを押す"
LAUNCH_APPLICATION_SCAN="hp スキャニング ソフトウェア"我需要使用以下方法转换节、键和值:
public static string ConvertToUTF8(string input)
{
try
{
return Encoding.UTF8.GetString(Encoding.GetEncoding(1252).GetBytes(input)).Trim().Trim('\0');
}
catch
{
return input;
}
}要获得适当的值,否则您将看到它们不是原始字符。
例如:味道的“扫描”gedrückt变成味觉扫描
而不首先调用ConvertToUTF8。
发布于 2014-05-01 13:50:22
您目前正在将字符串转换为Windows1252,然后通过将这些字节解释为UTF-8将其转换回字符串。
这不是很好-基本上是坏了。
如果你已经有了一个字符串,它不在Windows1252中.它是在UTF-16内部,但你可以认为它是一个字符序列。如果实际上已经从字节数组开始,那么应该使用Encoding.GetEncoding(1252).GetString(bytes)将该字节数组转换为字符串。
(如果您可以使用SetupGetLineTextW,则可以完全避免所有这些ANSI业务。)
https://stackoverflow.com/questions/23409005
复制相似问题