C#などで作った外部の「マネージドな.dll」の読み込み

概要

一般論の話をしますと、「C#」「VB.net」「C++/CLI」「F#」「JScript.net」などで作成したdllを「マネージドなアセンブリdll」として読み込む場合、
普通なら「読み込み対象となるdllファイル置き場の位置に大きな制約」があるのです。(ネットなどで調べてみてください)
特殊な設定でもしない限り、「exeと同じ場所か、dll名と同じ名前のサブフォルダに入れる」必要があります。

しかし、hmPS・PowerShellにはそのような制限は一切ありません。
好きなフォルダに置いた自作のマネージドな.dllを(特に署名などもなく)突如自由に読みだして利用可能です。

C#のソースから.dllを作成。

最小限のサンプルとするため、わかりやすい構成としましょう。

hmPS/PowerShell自体は、.NET Framework 4.5で構成されていますが、
あなたが利用する.dllは、.NET Framework 4.7など、hmPSより新しいバージョンのアセンブリでも大丈夫です!!
ここも普通の.NETの考え方の制限とは大きく異なるとここです。
あなたのPCに入っている.NET Frameworkの一番新しいバージョンで作成しても問題ありません。

  • ファイル名は「TestSample.dll」
  • 名前空間は「TestNameSpace」
  • クラス名は「TestClass」
  • メソッドは「TestFunc」

とします。

コンパイルし、TestSample.dllといった名前にしたとしましょう。

using System;

namespace TestNameSpace
{
    public class TestClass
    {
        public TestClass() { }
        public int TestFunc(int x)
        {
            return x + 3;
        }
    }
}

C#等のアセンブリをloadする例

PowerShellは、普通にユーザーが制作したC#を読み込めますので、適当に読み込めば良いでしょう。

ファイル名は、適当に「loaddlltest.mac」とでもしてみましょう。

#PS = loaddll( hidemarudir + "\\" + "hmPS.dll" );

#_ = dllfuncw(#PS, "DoString", R"PS(

$AssemblyPath.Add( $hm::Macro::Var['currentmacrodirectory'] )
[System.Reflection.Assembly]::LoadWithPartialName("TestSample")

$obj = New-Object TestNameSpace.TestClass
$hm::debuginfo($obj);
$total = $obj.TestFunc(10)

$hm::Macro::Var['#total'] = $total;

$hm::debuginfo($total)


$hm::Macro::Eval( @'
    message(str(#total));
'@
);

)PS"
);

// 解放
freedll(#PS);

好きなフォルダに置く

以上、TestSample.dllとloaddlltest.macの2つのファイルを好きなフォルダ(秀丸と一切関係ないフォルダでもよい)に置いて、
「loaddlltest.mac」を適当に秀丸に登録して実行してみてください。
.dllが読みだされ計算結果がダイアログに表示されるハズです。

PICTURE

currentmacrodirectoryはアセンブリの読み込み対象に入っている

先述の例では、より正確な例を示すために、「$AssemblyPath.Add(...)」を使った例を示しました。

hmPSでは、実行するマクロファイルと同じ場所(currentmacrodirectory)に、読み込み対象の.dllがある場合、
$AssemblyPathにcurrentmacrodirectoryをAddする必要はありません。

以下のように簡潔な記述が可能です。

#PS = loaddll( hidemarudir + @"\hmPS.dll" );

#_ = dllfuncw( #PS, "DoString", R"PowerShell(

[System.Reflection.Assembly]::LoadWithPartialName("TestSample")

$obj = New-Object TestNameSpace.TestClass
$hm::debuginfo($obj);
$total = $obj.TestFunc(10)

$hm::Macro::Var['#total'] = $total;

$hm::debuginfo($total)


$hm::Macro::Eval( @'
    message(str(#total));
'@
);

)PowerShell"
);

freedll( #PS );