关于c#:与PowerShell CmdLets互操作

Interoping With PowerShell CmdLets

我一直在写一些利用PowerShell Cmdlet for App-V的实用程序。有趣的是,Microsoft似乎只记录了cmdlet,而不记录了Powershell模块后面使用的.net程序集。

现在,我熟悉P / Invoke和COM Interop,并且已经学习了如何使用System.Management.Automation创建Powershell会话并调用cmdlet。

但是有些东西对我来说不对。我基本上是在编写自己的package器类,以隐藏其余代码中的Powershell调用。似乎我应该要么a)绕过powershell并直接进入其背后的托管库,要么b)应该有更好的机制为powershell cmdlet生成互操作库。

如今看来,微软正在大量使用PS CmdLets,它实际上已成为要与之交互的新API。

我错过了什么吗?在这种情况下可以使用什么好的策略?


令人痛苦的是,通过System.Managment.Automation与cmdlet进行交互并将结果转换为管道另一侧的强类型对象将是解决问题的最稳定方法。

查看Microsoft自己的AppV Client托盘应用程序。它提供了运行所需的powershell命令以完成其所做的所有操作。

您可能会成功访问提供cmdlet的托管库,但是正如您所指出的那样,它们没有文档记载,并且很可能会从您的下方更改。即使这样,也可能会缺少一些无法使用Powershell的东西,例如从Get-AppVirtualProcess获得的AppVPackageData NoteProperty。


您对"气味"是正确的。
绕过Powershell并不是编写实用程序的最佳方法,因为它背后的未记录托管库比cmdlet更可能以静默方式进行更改。使用这种方法可能会给您带来麻烦。

您正在尝试合并难以组合的事物。
解决方案是引入一个代理,该代理允许以更自然的方式将您的代码与ps cmdlet结合在一起。

根据您的情况,可以创建ps脚本,以自然方式与cmdlet通信并提供必要的功能。在您的C#代码中,您可以简单地调用powershell.exe。如果那也不适合您,那么只需使用System.Management.Automation创建powershell会话并调用您的脚本。这种方法比较安全,因为现在您可以在Powershell代理中与记录的ps cmdlet进行通信(自然的Powershell方式),并通过c#代码与ps脚本进行通信(这使您可以更好地控制代码)