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.0で構成されていますが、
    あなたが利用する.dllは、.NET Framework 4.6など、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)
    
    
    )PS"
    );
    
    // 解放
    freedll(#PS);

    好きなフォルダに置く

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

    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 );