C#调用PowerShell操作打印机端口遇PSInvalidCastException问题求助
解决System.Management.Automation.PSInvalidCastException枚举类型转换异常
针对基于.NET Framework 4.6.2、使用Microsoft.PowerShell.5.1.ReferenceAssemblies.1.0.0中System.Management.Automation.dll操作打印机端口时出现的枚举字符串转System.Type失败的PSInvalidCastException异常,提供以下几个解决思路:
手动处理枚举类型转换
避免依赖PowerShell自动类型映射,在获取输出结果后,显式对涉及枚举的字段进行解析:using (var powerShell = Create()) { powerShell.AddCommand("Get-PrinterPort").AddParameter("Name", "somePortName"); var output = powerShell.Invoke(); foreach (var portItem in output) { if (portItem.Properties["RenderingMode"]?.Value != null) { string modeStr = portItem.Properties["RenderingMode"].Value.ToString(); var renderingMode = Enum.Parse(typeof(Microsoft.PowerShell.Cmdletization.GeneratedTypes.Printer.RenderingModeEnum), modeStr); // 后续使用转换后的枚举值即可 } } }调整PowerShell输出格式
通过PowerShell命令筛选或转换输出,减少复杂类型的自动转换压力。比如只选择需要的字段,让返回结果以基础类型呈现:using (var powerShell = Create()) { powerShell.AddScript(@"Get-PrinterPort -Name 'somePortName' | Select-Object Name, PortNumber, RenderingMode"); var output = powerShell.Invoke(); }配置程序集重定向
由于受限于System.Runtime 4.1.2版本,可能存在依赖版本冲突。在应用的app.config中添加程序集重定向,确保依赖版本统一:<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Management.Automation" publicKeyToken="31bf3856ad364e35" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-1.0.0.0" newVersion="1.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime>注册自定义类型转换器
创建自定义的PowerShell类型转换器,处理枚举字符串到System.Type的转换逻辑,并注册到Runspace中:var runspaceConfig = RunspaceConfiguration.Create(); // 注册自定义转换器 runspaceConfig.TypeTable.AddType(new TypeConverterAttribute(typeof(string), typeof(Type)) { ConverterType = typeof(CustomEnumTypeConverter) }); using (var runspace = RunspaceFactory.CreateRunspace(runspaceConfig)) { runspace.Open(); using (var powerShell = PowerShell.Create()) { powerShell.Runspace = runspace; powerShell.AddCommand("Get-PrinterPort").AddParameter("Name", "somePortName"); var output = powerShell.Invoke(); } } // 自定义转换器实现 public class CustomEnumTypeConverter : PSTypeConverter { public override bool CanConvertFrom(object sourceValue, Type destinationType) { return sourceValue is string && destinationType == typeof(Type); } public override object ConvertFrom(object sourceValue, Type destinationType, IFormatProvider formatProvider, bool ignoreCase) { if (sourceValue is string enumFullName && enumFullName.Contains("Microsoft.PowerShell.Cmdletization.GeneratedTypes.Printer.")) { // 尝试加载目标枚举类型 return Type.GetType(enumFullName, false); } return base.ConvertFrom(sourceValue, destinationType, formatProvider, ignoreCase); } public override bool CanConvertTo(object sourceValue, Type destinationType) => false; public override object ConvertTo(object sourceValue, Type destinationType, IFormatProvider formatProvider, bool ignoreCase) => null; }
内容的提问来源于stack exchange,提问作者piort
相关产品推荐
相关产品推荐

