10

これが私が何らかの形で達成したいことです。

いくつかのオブジェクトを定義するカスタムアセンブリがあります。スクリプトでは、スクリプトブロックに渡したいカスタムオブジェクトを作成し、そのオブジェクトの動作を維持します。

Add-Type -AssemblyName MyCustomDLL

$global:object = new-object MyCustomDLL.MyCustomObject()
$object | gm

$jobWork = { param ($object) $object | gm } # I'd like to keep my object behavior in that block

$job = Start-Job -ScriptBlock $jobWork -ArgumentList $object
Wait-Job $job
Receive-Job $job

どうすればそれを行うことができますか、または同じ効果を達成できますか?ご協力いただきありがとうございます

4

2 に答える 2

12

バックグラウンドジョブの代わりに、、で使用PowerShellできBeginInvokeますEndInvoke。これは、「ジョブ」でライブオブジェクトを渡し、そこで変更して結果を取得する、単純ですが機能する例です。

# live object to be passed in a job and changed there
$liveObject = @{ data = 42}

# job script
$script = {
    param($p1)
    $p1.data # some output (42)
    $p1.data = 3.14 # change the live object data
}

# create and start the job
$p = [PowerShell]::Create()
$null = $p.AddScript($script).AddArgument($liveObject)
$job = $p.BeginInvoke()

# wait for it to complete
$done = $job.AsyncWaitHandle.WaitOne()

# get the output, this line prints 42
$p.EndInvoke($job)

# show the changed live object (data = 3.14)
$liveObject
于 2013-03-13T13:43:41.437 に答える
4

バックグラウンドジョブはPowerShellリモート処理の上に構築されているため、オブジェクトを渡すときに同様のアクションを実行します。それらは、すべての複雑さでそれらを渡すのではなく、それらをシリアル化/逆シリアル化します。

私の推測では、複雑なオブジェクトを取得する唯一の方法は、コンストラクターの引数や操作をasとして渡し、ジョブ内に-ArgumentListオブジェクトを作成することです。

このような場合、アセンブリの追加も作業の一部である必要があります。

Start-Job {
    param ($ConstructorArguments)
    Add-Type -AssemblyName MyCustomDll
    $object = New-Object MyCustomDll.MyCustomObject $ConstructorArguments
    $object | Get-Member
} -ArgumentList Foo, Bar | Wait-Job | Receive-Job 
于 2013-03-13T11:25:53.957 に答える