PowerShellで.net remotingを使う

とりあえず、IPCね。
ライフサイクルタイムの件はとりあえず無視。(なので、5分何もしないと切れる)
ライフサイクルタイムの設定するなら、チャネル登録前にやらないといけない。



スクリプト

サーバー側準備

Add-Type -AssemblyName System.Runtime.Remoting
$channel = New-Object System.Runtime.Remoting.Channels.Ipc.IpcServerChannel('ipcSample')
[System.Runtime.Remoting.Channels.ChannelServices]::RegisterChannel($channel, $true)

クライアント側準備

Add-Type -AssemblyName System.Runtime.Remoting
$channel = New-Object System.Runtime.Remoting.Channels.Ipc.IpcClientChannel
[System.Runtime.Remoting.Channels.ChannelServices]::RegisterChannel($channel, $true)

RegisterChannelの第二引数は暗号化指定。


サーバー側オブジェクト登録(MemoryStreamにする)

$remoteObj = New-Object System.IO.MemoryStream
$objRef = [System.Runtime.Remoting.RemotingServices]::Marshal([MarshalByRefObject]$remoteObj, 'test', [System.IO.MemoryStream])

クライアント側オブジェクト取得

$remoteObj = [Activator]::GetObject([System.IO.MemoryStream], 'ipc://ipcSample/test')

クライアント側で全てのメソッド・プロパティが使えるわけではないことに注意。
Read/Writeはできる。
ここ、私が嵌ったポイント。
CanReadプロパティ見ようとしてもさ、見えないからオブジェクトが取れてないのかと思ったよ。
MarshalByRefObjectを継承する規定のクラスで適当に選んだのがいけなかったかな?


サーバー側後片付け

[System.Runtime.Remoting.RemotingServices]::Unmarshal($objRef)
[System.Runtime.Remoting.RemotingServices]::Disconnect($remoteObj)
$remoteObj.Dispose()
[System.Runtime.Remoting.Channels.ChannelServices]::UnregisterChannel($channel)

UnmarshalしてDisconnectする。
それから使ったオブジェクトの破棄と、チャンネルの破棄。


クライアント側後片付け

[System.Runtime.Remoting.Channels.ChannelServices]::UnregisterChannel($channel)

クライアント側は、チャンネル破棄するだけだね。(サーバーより前にすべき?)
クライアント側からDisposeメソッド呼ぶと、オブジェクトの破棄もできちゃうけど、それはなんか変かな。
作った側(サーバー側)が破棄するのが筋でしょう。
クライアント側は、Remove-Variable程度にするのが良いかと思います。
まあでも、クライアント側の意思として、クライアント側からDisposeして、サーバー側は使えなくなったら終了、というのも手は手ですけどね。