簡體   English   中英

從 C# 應用程序運行時,PowerShell 腳本的行為與從 PowerShell ISE 運行時不同

[英]PowerShell script acts different when run from C# application then from PowerShell ISE

我正在嘗試使用可用的 PowerShell 命令 ( https://psbiztalk.codeplex.com ) 自動化 BizTalk 部署。 當我從 PowerShell ISE UI 運行我的腳本時,一切正常。 但我想擁有自己的部署 UI,這就是我的問題所在。 該腳本的行為有所不同,並且在某一點找不到任何導致錯誤的資源(當前):

在程序集“Microsoft.BizTalk.ApplicationDeployment.Engine,版本=3.0.1.0,文化=中性,PublicKeyToken=31bf3856ad364e35”中鍵入“Microsoft.BizTalk.ApplicationDeployment.ResourceCollection”未標記為可序列化。

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行為方式不同。 關於這個發現還有什么想法嗎?

我不能聲稱在這方面擁有任何專業知識,但很明顯 PowerShell ISE 和您的托管環境之間存在某種環境差異。

運行時對某些不可序列化的抱怨表明它正在跨進程邊界或可能在應用程序域之間進行編組,這兩者都需要對象可序列化。 您的對象是否正在加載到不同的 AppDomains 中?

嘗試在配置文件中更改啟動模式:

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

正如BizTalk360 博客所寫

...否則當您嘗試訪問資源集合時,您將收到以下錯誤

在程序集“Microsoft.BizTalk.ApplicationDeployment.Engine,版本=3.0.1.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35”中鍵入“Microsoft.BizTalk.ApplicationDeployment.ResourceCollection”未標記為可序列化。

這是因為支持並行運行時,.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 提供程序的支持庫,但它可以用作獨立項目,不會對 PowerShell 產生任何依賴關系。 這使其成為在您自己的編程項目中圍繞管理和操作 BizTalk 工件的理想選擇。 CodePlex 上的 psbiztalk

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM