无需引入CodePagesEncodingProvider NuGet包,如何获取OEM编码?
解决方法
1. 硬编码常见OEM编码(适合目标环境明确的场景)
如果你的类库只针对特定操作系统或区域(比如国内常用的GBK对应OEM代码页936,英文系统的437),可以直接判断当前区域返回对应编码实例,完全不需要额外依赖:
var oemCodePage = CultureInfo.CurrentCulture.TextInfo.OEMCodePage; Encoding oemEncoding; switch(oemCodePage) { case 936: oemEncoding = Encoding.GetEncoding("GBK"); break; case 437: oemEncoding = Encoding.GetEncoding("IBM437"); break; // 按需添加其他常用OEM代码页 default: throw new NotSupportedException($"OEM代码页 {oemCodePage} 未被支持"); }
缺点是覆盖范围有限,仅适合你能提前确定目标环境编码的场景。
2. 手动封装轻量编码映射(平衡覆盖范围与依赖)
部分OEM编码是.NET运行时内置的,不需要注册额外Provider。你可以自己维护一个常用OEM代码页与编码名称的映射表,直接通过编码名称获取实例:
private static readonly Dictionary<int, string> OemCodePageMap = new Dictionary<int, string> { { 437, "IBM437" }, { 850, "IBM850" }, { 936, "GBK" }, { 950, "Big5" }, // 补充其他需要支持的映射 }; public static Encoding GetOemEncoding() { var codePage = CultureInfo.CurrentCulture.TextInfo.OEMCodePage; if (OemCodePageMap.TryGetValue(codePage, out var encodingName)) { return Encoding.GetEncoding(encodingName); } throw new NotSupportedException($"不支持的OEM代码页:{codePage}"); }
这种方法既不用带额外依赖,也能覆盖多数主流场景。
3. 动态加载Provider(兼容全量编码但不强制依赖)
如果必须支持所有OEM编码,但不想把依赖包随DLL发布,可以将System.Text.Encoding.CodePages设为可选依赖,代码中先尝试直接获取编码,失败时再尝试加载Provider:
Encoding GetOemEncoding() { var codePage = CultureInfo.CurrentCulture.TextInfo.OEMCodePage; try { return Encoding.GetEncoding(codePage); } catch (ArgumentException) { try { var providerType = Type.GetType("System.Text.CodePagesEncodingProvider, System.Text.Encoding.CodePages"); if (providerType != null) { var instanceProp = providerType.GetProperty("Instance"); if (instanceProp != null) { var provider = instanceProp.GetValue(null) as EncodingProvider; Encoding.RegisterProvider(provider); return Encoding.GetEncoding(codePage); } } } catch { } throw new InvalidOperationException($"无法获取编码 {codePage},请安装System.Text.Encoding.CodePages NuGet包以支持该编码"); } }
这种方式下,大部分场景不需要携带额外DLL,仅当用户遇到冷门编码时才需要安装依赖。
内容的提问来源于stack exchange,提问作者ArtemiZ Studio
相关产品推荐
相关产品推荐

