VB.NET FindPrinter打印函数转C#时EnumValues方法未定义问题
错误根因
你遇到的编译/运行报错是C#的静态类型检查机制导致的:VB.NET默认支持后期绑定,可以直接调用object类型变量的动态COM/WMI成员,而C#默认不允许该操作,因此编译器无法识别声明为object类型的RegObj下的EnumValues、GetStringValue方法。
解决方案1:最小改动适配原有逻辑
只需要修改变量类型为dynamic开启动态绑定,同时替换VB专属工具类为C#原生实现即可:
using System; using System.Collections; public string FindPrinter(string printerName) { const int HKEY_CURRENT_USER = unchecked((int)0x80000001); // 用dynamic声明WMI对象,开启后期绑定 dynamic regObj = Microsoft.VisualBasic.Interaction.GetObject(@"winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv"); dynamic devices = null; dynamic arr = null; regObj.EnumValues(HKEY_CURRENT_USER, @"Software\Microsoft\Windows NT\CurrentVersion\Devices", out devices, out arr); foreach (var device in (IEnumerable)devices) { string regValue = null; regObj.GetStringValue(HKEY_CURRENT_USER, @"Software\Microsoft\Windows NT\CurrentVersion\Devices", device, out regValue); string port = regValue.Split(',')[1]; string printerFullName = $"{device} on {port}"; if (printerFullName.IndexOf(printerName, StringComparison.OrdinalIgnoreCase) >= 0) { return printerFullName; } } return string.Empty; }
该方案需要保留对Microsoft.VisualBasic程序集的引用。
解决方案2:更推荐的原生C#实现(无需WMI、无需引用VB组件)
不用绕路读取注册表,直接用.NET内置的打印相关API获取打印机列表,构造Excel要求的[打印机名] on [端口名]格式即可,稳定性和兼容性更好:
using System.Drawing.Printing; using System; public string FindPrinter(string targetPrinterName) { // 遍历所有已安装的打印机 foreach (string printer in PrinterSettings.InstalledPrinters) { var printerSettings = new PrinterSettings { PrinterName = printer }; // 确认打印机有效 if (printerSettings.IsValid) { // 构造Excel要求的打印机格式 string excelPrinterName = $"{printer} on {printerSettings.PortName}"; if (excelPrinterName.IndexOf(targetPrinterName, StringComparison.OrdinalIgnoreCase) >= 0) { return excelPrinterName; } } } return string.Empty; }
注意事项:.NET Framework环境下直接引用内置的System.Drawing程序集即可;.NET Core/.NET 5+环境需要安装NuGet包System.Drawing.Common。
内容的提问来源于stack exchange,提问作者Ryan Rosso
相关产品推荐
相关产品推荐

