Office関連

VBAからRegistration-Freeで.NETベースのDLLを呼び出す方法

C#製のDLLをVBAから呼び出すのにいちいちRegAsmするのも面倒くさいなー、と思っていたところ、数年前のkumattiさんのツイートを思い出しました。

そういえばMicrosoft.Windows.ActCtxオブジェクトを使えばレジストリ登録不要でCOMコンポーネント呼び出せたなー、と。

やったことないし、一回くらいはやってみるか!
・・・というわけで、さっそく試してみることにしました。

ソースコードの準備

まずは呼び出すDLLのコードをC#で書きます。

C:\System\SampleNameSpace.cs

using System;
using System.Reflection;
using System.Runtime.InteropServices;

[assembly:AssemblyVersion("1.0.0.0")]

namespace SampleNameSpace
{
  [ComVisible(true), Guid("3ea27b1a-ac62-492e-8659-fd20402a629f"), InterfaceType(ComInterfaceType.InterfaceIsDual)]
  public interface ISample {
    string Hoge(string str);
  }
  
  [ClassInterface(ClassInterfaceType.None), Guid("14c829c3-4c16-4cb8-b1f1-7bec0528d009"), ProgId("Sample.ProgId")]
  public class SampleClass : ISample
  {
    public string Hoge(string str)
    {
      return "hogehoge:" + str;
    }
  }
}

文字列を返すだけの単純なコードです。

マニフェストファイルの作成

ソースコードの準備ができたら、次は「方法: 登録を必要としないアクティベーション用の .NET Framework ベースの COM コンポーネントを構成する」を参考に、DLLに埋め込むマニフェストファイルを作成します。

SampleNameSpace.manifest

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity name="SampleNameSpace" 
                    version="1.0.0.0" 
                    processorArchitecture="MSIL" />
  <clrClass clsid="{14C829C3-4C16-4CB8-B1F1-7BEC0528D009}" 
            progid="Sample.ProgId" 
            threadingModel="Both" 
            name="SampleNameSpace.SampleClass" 
            runtimeVersion="v4.0.30319;v2.0.50727" />
  <file name="SampleNameSpace.dll" />
</assembly>

上記参考ページを見る限り「/win32manifest」オプションでマニフェストを埋め込んでも良さそうな感じがしますが、手順として“コンポーネント マニフェストはリソースとしてアセンブリに埋め込む必要があります”とあるので、記載されている手順に従うことにします。

リソースファイルの作成

参考ページにはRc.exeを使用する旨が書いてあるのですが、「Win32ソースを実行ファイルに埋め込む: .NET Tips: C#, VB.NET」によるとGoRC.exeでもリソースのコンパイルができるようなので、これを使うことにします。

  1. 64-bit programming using the “Go” tools」から「Gorc.zip」ファイルをダウンロードして、「C:\System\Gorc」フォルダに解凍します。
  2. 上記手順で作成したマニフェストファイル(SampleNameSpace.manifest)をGoRC.exeと同じフォルダ(C:\System\Gorc)にコピーします。
  3. テキストエディタで下記ファイルを作成します。
  4. C:\System\Gorc\SampleNameSpace.rc

    #include <windows.h>
    #define MANIFEST_RESOURCE_ID 1
    MANIFEST_RESOURCE_ID RT_MANIFEST SampleNameSpace.manifest
  5. 下記コマンドを実行し、リソース(res)ファイルを作成します。
  6. C:\System\Gorc>GoRC /r "SampleNameSpace.rc"
  7. 作成したSampleNameSpace.resファイルを「C:\System」フォルダにコピーします。

ソースコードのコンパイル

リソースファイルの準備ができたら、次はコンパイル(/win32resオプションでリソースファイル指定)してDLLを作成します。

問題が無ければ「C:\System」フォルダに「SampleNameSpace.dll」ファイルが作成されます。

VBAからの呼び出し

VBAから呼び出す前に、呼び出し元(クライアント側)のマニフェストファイルを準備します。

C:\System\SampleNameSpace.client.manifest

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity name = "client" version = "1.0.0.0" />
  <dependency>
    <dependentAssembly>
      <assemblyIdentity name="SampleNameSpace" version="1.0.0.0" processorArchitecture="MSIL" />
    </dependentAssembly>
  </dependency>
</assembly>

マニフェストファイルの準備ができたら、いよいよVBAからの呼び出しです。

Public Sub Sample()
  Dim obj As Object
  
  With CreateObject("Microsoft.Windows.ActCtx")
    .Manifest = "C:\System\SampleNameSpace.client.manifest"
    Set obj = .CreateObject("Sample.ProgId")
    MsgBox obj.Hoge("ABC")
  End With
End Sub

ProgIdを指定してMicrosoft.Windows.ActCtx.CreateObjectメソッドを呼び出して、上手くいけばHogeメソッドの結果がメッセージボックスで表示されるはずです。

・・・が、返ってきたのは「実行時エラー ‘-2147024894 (80070002)’:オートメーション エラーです。指定されたファイルが見つかりません。」エラー。

Cannot get registration-free COM working from VBA」や「RegFree COM working from C#, NOT working from VBA」を見ると、“DLLをVBAの実行元(ExcelならEXCEL.EXE)と同じフォルダに置いたら動いた”とのことだったので、DLLファイルをOfficeのインストールフォルダにコピーして再実行したところ、無事にコードが実行できました。

しかしながら、RegAsmしたくないからMicrosoft.Windows.ActCtxオブジェクトを使ったというのに、結局Officeフォルダへのコピーが必要とは・・・。
これなら素直にRegAsmした方がマシなような気がします。

もしかしたら、コピー不要でDLLを呼び出す方法があるのかもしれませんが、そこまで調べきれていないので、何か進展があったらまた追記することにします。

中途半端なオチですが、参考にしたWebサイトとともにメモとして残しておきます。

参考Webページ

Microsoft EdgeのURL制限は2083文字なのか調べてみた。前のページ

Microsoft Edgeの「お気に入り」編集を楽にするバッチファイル次のページ

関連記事

  1. Excel

    Trello APIを使ってカードを投稿するVBAマクロ

    以前Fiddlerを使ってTrello APIを実行する記事を書きまし…

  2. Office関連

    ConvertToTextメソッドを使ってテーブルを二次元配列に変換するWordマクロ

    WordのTableオブジェクトには、テーブルを解除して文字列に変換す…

  3. Office関連

    アクティブなページ上のシェイプを一括でグループ化するWordマクロ

    Msdn フォーラムにあった質問「複数図形のグループ化」の回答用に書い…

  4. Office関連

    シート見出しの右クリックメニューから「コードの表示」を消す方法

    いつもお世話になっている「インストラクターのネタ帳」の管理人である伊藤…

  5. Office関連

    Computer Vision APIを使って画像から文字列を取得するVBAマクロ

    前々回の記事で、Fiddlerを使ってMicrosoft Cognit…

  6. アイコン一覧

    Office 365アイコン(imageMso)一覧(R)

    Office 365のデスクトップ版Officeアプリケーション(Wo…

コメント

  • コメント (0)

  • トラックバックは利用できません。

  1. この記事へのコメントはありません。

Time limit is exhausted. Please reload CAPTCHA.

※本ページはプロモーションが含まれています。

Translate

最近の記事

アーカイブ

PAGE TOP