首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过byte[]进行Windows-1252编码

通过byte[]进行Windows-1252编码
EN

Stack Overflow用户
提问于 2014-05-01 13:47:53
回答 1查看 2.8K关注 0票数 0

我在利用这个装置..。方法(如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字符串?

一些代码:

代码语言:javascript
复制
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:

代码语言:javascript
复制
; 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 スキャニング ソフトウェア"

我需要使用以下方法转换节、键和值:

代码语言:javascript
复制
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。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-01 13:50:22

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

这不是很好-基本上是坏了。

如果你已经有了一个字符串,它不在Windows1252中.它是在UTF-16内部,但你可以认为它是一个字符序列。如果实际上已经从字节数组开始,那么应该使用Encoding.GetEncoding(1252).GetString(bytes)将该字节数组转换为字符串。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23409005

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档