如何解决PowerShell调用Add-Type时出现的CS1701版本不匹配错误?
解决PowerShell中Add-Type引用Microsoft.SqlServer.Smo.dll的CS1701版本冲突错误
这个错误是由于Microsoft.SqlServer.Smo.dll依赖的System.Runtime版本(6.0.0.0)与当前PowerShell环境加载的System.Runtime版本(8.0.0.0)不匹配导致的,以下是几种可行的修复方案:
方案1:使用程序集绑定重定向
通过配置绑定重定向,让编译器将旧版本的System.Runtime引用重定向到当前环境的新版本,步骤如下:
# 获取已加载的Microsoft.SqlServer.Smo程序集路径 $smoAssembly = [Microsoft.SqlServer.Management.Smo.Database].Assembly $smoPath = $smoAssembly.Location # 构建绑定重定向配置内容 $bindingRedirectConfig = @" <configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <bindingRedirect oldVersion="6.0.0.0" newVersion="8.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration> "@ # 生成临时配置文件 $tempConfigFile = [System.IO.Path]::GetTempFileName() -replace '\.tmp$', '.config' $bindingRedirectConfig | Out-File -FilePath $tempConfigFile -Encoding UTF8 # 配置编译参数 $compilerParams = New-Object System.CodeDom.Compiler.CompilerParameters $compilerParams.ReferencedAssemblies.Add($smoPath) | Out-Null $compilerParams.GenerateInMemory = $true # 指定配置文件和Smo所在目录作为库路径 $compilerParams.CompilerOptions = "/lib:`"$([System.IO.Path]::GetDirectoryName($smoPath))`" /appconfig:`"$tempConfigFile`"" # 自定义C#代码示例 $customCSharpCode = @" using Microsoft.SqlServer.Management.Smo; public class CustomSmoUtility { public static string GetDatabaseStatus(Database db) { return db.Status.ToString(); } } "@ # 编译自定义类型 Add-Type -TypeDefinition $customCSharpCode -CompilerParameters $compilerParams # 清理临时文件 Remove-Item $tempConfigFile -Force
方案2:显式引用匹配版本的System.Runtime程序集
直接在Add-Type时引用当前PowerShell环境中加载的System.Runtime版本,确保版本一致:
# 获取已加载的Smo和System.Runtime程序集 $smoAssembly = [Microsoft.SqlServer.Management.Smo.Database].Assembly $runtimeAssembly = [System.Runtime.InteropServices.RuntimeInformation].Assembly # 自定义C#代码 $customCSharpCode = @" using Microsoft.SqlServer.Management.Smo; public class CustomSmoHelper { public static void PrintDbInfo(Database db) { System.Console.WriteLine($"数据库名称:{db.Name},状态:{db.Status}"); } } "@ # 显式引用两个程序集进行编译 Add-Type -TypeDefinition $customCSharpCode -References $smoAssembly, $runtimeAssembly
方案3:手动加载程序集后再编译
先手动加载正确版本的System.Runtime,再加载Smo程序集,确保加载顺序正确:
# 加载System.Runtime 8.0(PowerShell 7.4环境下路径示例) $runtimePath = [System.IO.Path]::Combine($PSHome, "System.Runtime.dll") $runtimeAssembly = [System.Reflection.Assembly]::LoadFrom($runtimePath) # 加载Microsoft.SqlServer.Smo程序集 $smoPath = [Microsoft.SqlServer.Management.Smo.Database].Assembly.Location $smoAssembly = [System.Reflection.Assembly]::LoadFrom($smoPath) # 自定义C#代码 $customCSharpCode = @" using Microsoft.SqlServer.Management.Smo; public class CustomSmoOps { public static bool IsDbOnline(Database db) { return db.Status == DatabaseStatus.Normal; } } "@ # 编译自定义类型 Add-Type -TypeDefinition $customCSharpCode -References $smoAssembly, $runtimeAssembly
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

