WPF调用PowerShell遇System.Management.Automation缺失及CosmosDB IP规则更新
我在基于net6.0-windows的WPF应用中尝试调用PowerShell脚本更新Azure上的IP规则,但即使执行简单的Write-Output 'Hello, World!'脚本也出现如下错误:
Could not load file or assembly 'System.Management.Automation, Version=7.2.8.0, Culture=neutral, PublicKeyToken=token123456'. The system cannot find the file specified.
以下是我的代码:
public Collection<PSObject> GetExistingFirewallIPRules(string script, Dictionary<string, object> scriptParameters) { PowerShell ps = PowerShell.Create(); ps.AddScript(script); return ps.Invoke(); }
以及.csproj配置:
<PropertyGroup> <TargetFramework>net6.0-windows</TargetFramework> <Nullable>enable</Nullable> <UseWPF>true</UseWPF> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> </PropertyGroup> <ItemGroup> <PackageReference Include="Azure.ResourceManager.AppService" Version="1.0.0" /> <PackageReference Include="Azure.ResourceManager.CosmosDB" Version="1.2.0" /> <PackageReference Include="Microsoft.PowerShell.SDK" Version="7.3.1" /> <PackageReference Include="Prism.Core" Version="8.1.97" /> <PackageReference Include="Prism.Wpf" Version="8.1.97" /> <PackageReference Include="System.Management.Automation" Version="7.2.8" /> </ItemGroup>
请问如何修复该错误?或者是否有无需执行PowerShell脚本(如Update-AzCosmosDBAccount -ResourceGroupName $resourceGroupName -Name $accountName -IpRangeFilter $ipFilter)的方式来更新Azure门户中的CosmosDB IP规则?
一、修复PowerShell程序集加载错误
统一PowerShell相关包版本
当前你引用的Microsoft.PowerShell.SDK(7.3.1)和System.Management.Automation(7.2.8)版本不一致,会导致程序集依赖冲突。将两个包的版本统一为相同版本,比如都使用7.3.1:<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.3.1" /> <PackageReference Include="System.Management.Automation" Version="7.3.1" />验证程序集复制情况
虽然已设置<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>,仍需确认System.Management.Automation.dll是否被复制到项目输出目录。可以右键项目→属性→生成→查看输出路径,手动检查该目录下是否存在目标dll。若缺失,尝试清理项目后重新生成。指定PowerShell运行时创建方式
替换默认的PowerShell.Create(),使用指定运行时的方式初始化:// 创建默认的.NET Core会话状态 var sessionState = InitialSessionState.CreateDefault2(); var runspace = RunspaceFactory.CreateRunspace(sessionState); runspace.Open(); // 绑定运行空间到PowerShell实例 var ps = PowerShell.Create(); ps.Runspace = runspace;
二、无需PowerShell,直接用Azure SDK更新CosmosDB IP规则
你已引用Azure.ResourceManager.CosmosDB包,可直接通过该SDK操作IP规则,完全无需依赖PowerShell:
示例代码
using Azure.Identity; using Azure.ResourceManager.CosmosDB; using Azure.ResourceManager.CosmosDB.Models; public async Task UpdateCosmosDbIpRules(string subscriptionId, string resourceGroupName, string accountName, string ipFilter) { // 初始化Azure资源管理客户端 var armClient = new ArmClient(new DefaultAzureCredential()); var subscription = await armClient.GetSubscriptionAsync(subscriptionId); var resourceGroup = await subscription.GetResourceGroupAsync(resourceGroupName); var cosmosDbAccount = await resourceGroup.GetCosmosDBAccountAsync(accountName); // 构建IP规则更新参数 var updateParams = new CosmosDBAccountUpdateParameters { IpRules = new List<IpAddressOrRange> { new IpAddressOrRange(ipFilter) // 如需添加多个IP,继续追加 // new IpAddressOrRange("192.168.1.0/24"), // new IpAddressOrRange("10.0.0.1") } }; // 执行更新操作 await cosmosDbAccount.UpdateAsync(WaitUntil.Completed, updateParams); }
说明
- 身份验证使用
DefaultAzureCredential,它会自动从环境变量、Azure CLI、Visual Studio等渠道获取凭据,适配本地开发和生产部署场景。 - 若需要追加IP规则而非覆盖,可先通过
cosmosDbAccount.Data.IpRules获取当前规则列表,添加新IP后再传入更新参数。
内容的提问来源于stack exchange,提问作者Maltion

