从C#应用程序运行PowerShell ISE

时间:2015-08-28 16:27:55

标签: c# powershell biztalk powershell-ise

我尝试使用可用的PowerShell命令(https://psbiztalk.codeplex.com)自动执行BizTalk部署。当我从PowerShell ISE UI运行我的脚本时,情况正常。但我想拥有自己的部署UI,这就是我的问题所在。脚本行为不同,并且在某一点上找不到任何导致错误的资源(当前):

  

键入' Microsoft.BizTalk.ApplicationDeployment.ResourceCollection'在   汇编' Microsoft.BizTalk.ApplicationDeployment.Engine,   Version = 3.0.1.0,Culture = neutral,PublicKeyToken = 31bf3856ad364e35'是   没有标记为可序列化。

Get-ApplicationResourceSpec的输出将是System.Xml.XmlDocument对象。看起来命令无法从托管的PowerShell中找到BizTalk应用程序资源,但ISE环境可以这样我认为应该可能以某种方式。

感谢任何想法和/或帮助。

PowerShell脚本:

$SnapIn = Get-PSSnapin | Where-Object { $_.Name -eq "BizTalkFactory.PowerShell.Extensions" }
if ($SnapIn -eq $null)
{
    Add-PSSnapin -Name "BizTalkFactory.Powershell.Extensions"
}

Set-Location -Path BizTalk:
cd "BizTalk:\Applications"
Get-ApplicationResourceSpec -Path "MyTestApplication"

从C#应用程序调用

string script = File.ReadAllText("GetResources.ps1")));

Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();

Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(script);

StringBuilder builder = new StringBuilder();
Collection<PSObject> objects = pipeline.Invoke();
foreach (PSObject obj in objects.Where(t => t != null))
{
    builder.AppendLine(obj.ToString());
}

runspace.Close();

更新

由于BizTalk PowerShell命令是开源的,我深入挖掘并尝试隔离失败的命令。我发现以下代码给出了不同的结果:

# Replace Get-ApplicationResourceSpec -Path "MyTestApplication" from the
# other script with these lines
$App = Get-ChildItem | Where-Object { $_.Name -eq $Application } | Select-Object -First 1
$Group = New-Object Microsoft.BizTalk.ApplicationDeployment.Group
$Group.DBName = $App.Catalog.Database
$Group.DBServer = $App.Catalog.Instance
$Group.SqlConnection.ConnectionString

在ISE环境中,ConnectionString设置为有效值,但不在C#情况下。这导致第二种情况下不存在的资源:

$App = $Group.Applications["MyTestApplication"]
$App.ResourceCollection.Count # equals 88 vs. 0

因此,似乎BizTalk内部类型Microsoft.BizTalk.ApplicationDeployment.Group的行为方式不同。有关这一发现的更多想法吗?

2 个答案:

答案 0 :(得分:1)

我不能声称在这方面有任何专业知识,但很明显PowerShell ISE与您的托管环境之间存在某种环境差异。

关于某些不可序列化的内容的运行时抱怨表明它正在跨进程边界进行编组,或者可能在应用程序域之间进行编组,这两者都要求对象可序列化。您的对象是否可以加载到不同的AppDomain中?

答案 1 :(得分:1)

尝试更改配置文件中的启动模式:

<configuration>
  <startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
  </startup>
</configuration>

正如BizTalk360 Blog所述:

  

...当你尝试访问资源集合时,你会这样做   收到以下错误

     
    

输入'Microsoft.BizTalk.ApplicationDeployment.ResourceCollection'     程序集'Microsoft.BizTalk.ApplicationDeployment.Engine,     Version = 3.0.1.0,Culture = neutral,PublicKeyToken = 31bf3856ad364e35'是     没有标记为可序列化。

  
     

这是因为支持并行运行时,.NET 4.0具有   改变了它与旧的混合模式组件绑定的方式。这些   例如,程序集是从C ++ \ CLI编译的程序集。   混合模式程序集是针对版本'v1.1.4322'构建的   运行时无法在没有附加的情况下加载到4.0运行时   配置信息。

此外,在编写C#应用程序时,请注意您可以在项目中引用BizTalkFactory.Management.Automation.dllBizTalkFactory.HealthAndActivity.Automation.dll并在不需要PowerShell的情况下实现相同的功能:

  

BizTalk Factory Management Automation旨在成为BizTalk PowerShell Provider的支持库,但它可以用作独立项目,不会对PowerShell产生任何依赖性。这使它成为您自己的编程项目中使用管理和操作BizTalk工件的理想选择。 psbiztalk on CodePlex