WinForms应用启动PowerShell脚本时遇程序集加载错误求助
问题重现
你当前的VB.Net代码尝试调用Exchange相关的PowerShell脚本,但在创建Runspace时抛出错误:
{"Cannot load Windows PowerShell snap-in Microsoft.PowerShell.Diagnostics because of the following error: Could not load file or assembly 'Microsoft.PowerShell.Commands' or one of its dependencies.The system cannot find the file specified."}
来源:System.Management.Automation
你的核心代码如下:
Dim myRunSpace As Runspace = RunspaceFactory.CreateRunspace myRunSpace.Open() Dim mypipeline As Pipeline = myRunSpace.CreatePipeline() Dim command As String = " .'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'; Connect-ExchangeServer -auto; get-mailbox -recipienttypedetails UserMailbox | select-object DisplayName,RecipientTypeDetails,PrimarySmtpAddress" mypipeline.Commands.AddScript(command) mypipeline.Commands.Add("Out-String") Dim outputs As Collection(Of PSObject) = mypipeline.Invoke() 'myRunSpace.Close() Dim MyStringBuiler As New StringBuilder() For Each result As PSObject In outputs MyStringBuiler.AppendLine(result.ToString()) Next MessageBox.Show(MyStringBuiler.ToString)
问题根源
正如你推测的,这是项目引用的System.Management.Automation程序集版本与目标机器上的PowerShell版本不匹配导致的。不同PowerShell版本对应不同的程序集版本:
- PowerShell 2.0 →
System.Management.Automationv1.0.0.0 - PowerShell 3.0~5.1 →
System.Management.Automationv3.0.0.0
如果项目引用的版本和机器上的PowerShell版本不兼容,就会出现程序集找不到的错误。
解决方案
1. 先确认目标机器的PowerShell版本
打开PowerShell控制台,执行以下命令查看版本:
$PSVersionTable.PSVersion
记录下Major版本号(比如5代表PowerShell 5.1)。
2. 调整项目的程序集引用
方法一:使用匹配版本的NuGet包
右键你的WinForms项目 → 管理NuGet程序包,卸载当前的System.Management.Automation包,然后安装与目标PowerShell版本匹配的包:- 针对PowerShell 5.1:安装
System.Management.Automationv6.2.5(该版本向下兼容PS5.1) - 针对PowerShell 2.0:安装
System.Management.Automationv1.0.0.0
- 针对PowerShell 5.1:安装
方法二:设置程序集为非特定版本
右键项目中的System.Management.Automation引用 → 属性,将特定版本设置为False,这样运行时会自动加载目标机器上匹配的版本。
3. 修改Runspace创建代码,指定兼容的会话配置
不要使用默认的RunspaceFactory.CreateRunspace(),而是显式创建会话配置,确保加载正确的PowerShell环境:
' 针对PowerShell 3.0+的版本,使用InitialSessionState Dim initialState As InitialSessionState = InitialSessionState.CreateDefault() ' 设置执行策略(根据你的需求调整,比如RemoteSigned) initialState.ExecutionPolicy = ExecutionPolicy.RemoteSigned ' 创建Runspace时传入会话配置 Dim myRunSpace As Runspace = RunspaceFactory.CreateRunspace(initialState) myRunSpace.Open()
4. 额外的排查点
- 确保目标机器安装了Exchange Server管理工具(因为你调用的
RemoteExchange.ps1是Exchange的工具脚本) - 检查你的WinForms应用的平台目标:Exchange 2010(V14)是64位程序,所以你的应用需要编译为
x64(项目属性→生成→平台目标),否则会加载32位的PowerShell环境,找不到64位的Exchange程序集 - 尝试以管理员身份运行你的应用,Exchange管理命令通常需要管理员权限
内容的提问来源于stack exchange,提问作者justALostCoder

