当前位置: 首页 > 知识库问答 >
问题:

Windows-1252通过字节[]编码

锺离德运
2023-03-14

我正在利用设置。。。方法(例如SetupGetLineText)从inf文件中读取一些内容(我需要它,对通用ini解析器不感兴趣)。这些方法使用Windows-1252编码,我需要将其转换为Unicode。我使用一个字符串得到了这个结果,比如这个(输入类型为string):

编码。UTF8.编码。编码(1252).GetBytes(输入));

即使这很好,您也可以立即从SetupGetLineText方法(和其他方法)检索字节。但是,我不完全确定现在如何转换字节,因为它们与什么编码不同。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;
        }
    }

以获得正确的值,否则您将看到它们不是原始字符。

例如:味觉“Scannen”gedrückt变为味觉Scannen gedrückt

没有先调用ConvertToUTF8。

共有1个答案

洪浩
2023-03-14

您当前正在将字符串转换为Windows-1252,然后通过将这些字节解释为UTF-8将其转换回字符串。

这不是很好,基本上是坏的。

如果你已经有一个字符串,它不在Windows-1252中。。。它在内部是UTF-16格式的,但您可以将其视为一个字符序列。如果您实际上是从字节数组开始的,那么应该使用编码。GetEncoding(1252)。GetString(bytes)将该字节数组转换为字符串。

(如果您可以使用SetupGetLineTextW,则可以完全避免所有这些ANSI业务。)

 类似资料:
  • 我有一个缓冲区与字符编码在Windows 1252。然而,当我用适当的编码创建一个新的字符串时,而不是预期的结果,我经常会得到询问标记,例如。 因此,系统应在其上方显示带“^”的“u”字符。而是显示“?”。 任何想法?

  • 在我的Silverlight应用程序中,我得到了一个用windows-1252编码的XML文件。现在我的问题,它不会正确显示,直到Windows-1252字符串转换为UTF8字符串。在一个正常的C#环境中,这不会是一个大问题:在那里我可以做这样的事情: (将字符串的字符编码从windows-1252转换为utf-8) 但是silverlight不支持windows-1252,它只支持unicode

  • 我遇到了一个编码问题。不确定它是否与IDE相关,但我使用的是NetBeans 7.4。我在J2EE项目中得到了这段代码: 当我运行它时,它从来没有正确显示。UTF-8应该可以打印出来,但它没有。还有当我尝试: 它返回了windows-1252。项目设置为UTF-8编码。我甚至尝试过用UTF-8重新保存这个特定的java文件,但它仍然不能正确显示。 另一方面,我尝试创建J2SE项目,当我运行相同的代

  • 我在Perl中有一个旧版应用程序,最有可能处理以编码的XML,并且需要将该XML的某些数据存储在某个数据库中,该数据库出于历史原因使用。是的,此设置不能支持Unicode标准的所有可能字符,但在实践中,我不需要这样做,并且可以尝试合理的兼容性。 当前的具体问题是一个包含(>)的文件,这使得Perl将Unicode字符串的现有编码中断为 “\x{0308}”未映射到cp1252 我使用Unicode

  • 我需要将上传的文件名转换为未知编码的Windows 1252,同时保持UTF-8兼容性。 当我将这些文件传递给控制器(我对其没有任何影响)时,这些文件必须经过Windows-1252编码。然后,该控制器再次生成通过MySQL存储到数据库中的有效文件(名称)列表-因此我需要UTF-8兼容性。传递给控制器的文件名和写入数据库的文件名必须匹配。到目前为止还不错。 在一些罕见的情况下,当转换为“Windo

  • 我有一个旧数据库,声称已将排序规则设置为windows-1252,并将文本字段的内容存储为 当它显示在遗留的网络应用程序中时,它在浏览器中显示为。浏览器报告一个UTF-8编码的页面。我不知道这种转换是如何完成的(几乎可以肯定的是,它不是通过动态搜索和替换完成的)。这对我来说是个问题,因为我将文本字段(和许多其他类似的字段)从遗留数据库中取出,并放入一个新的UTF-8数据库。新的Web应用程序将新数