更新:簡単な例を機能させるために20時間以上費やした後、これは見た目ほど単純ではないことに気付きました。このような記事は「落とし穴」を明らかにします-そしてこれはWindows7の前に書かれました(マニフェストの扱いが異なります)。VSTOを介して.NETアセンブリをVBAに公開することに固執しています。
単純なCOM-Visible.NETアセンブリを作成し、ExcelVBAから呼び出そうとしています。.NETビルド中に「COM相互運用機能に登録」すると、VBAから正常に呼び出すことができます。
Sub VBA()
Dim obj As Object
Set obj = actCtx.CreateObject("ComTest.Main")
MsgBox obj.Test() '<-- Displays "Hello"
End Sub
ただし、登録なしでやりたいです。
ハンスからのアドバイスごとに更新:
[COM相互運用機能の登録]のチェックを外し、app.Manifestを次のように設定しました。
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly
manifestVersion="1.0"
xmlns="urn:schemas-microsoft-com:asm.v1"
xmlns:asmv1="urn:schemas-microsoft-com:asm.v1"
xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity
type="win32"
version="1.0.0.0"
name="ComTest"
publicKeyToken="a36a7110110d7bd7" />
<clrClass
clsid="{975DC7E0-4596-4C42-9D0C-0601F86E3A1B}"
progid="ComTest.Main"
threadingModel="Both"
name="ComTest.Main"
runtimeVersion="v4.0.30319">
</clrClass>
<file name = "ComTest.dll"></file>
</asmv1:assembly>
次のようなダミーの「client.manifest」を作成しました。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<asmv1:assembly
manifestVersion="1.0"
xmlns="urn:schemas-microsoft-com:asm.v1"
xmlns:asmv1="urn:schemas-microsoft-com:asm.v1"
xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
manifestVersion="1.0"
xmlns="urn:schemas-microsoft-com:asm.v1" >
<assemblyIdentity
name="xxx"
version="1.0.0.0" />
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="ComTest"
version="1.0.0.0"
publicKeyToken="a36a7110110d7bd7" />
</dependentAssembly>
</dependency>
</asmv1:assembly>
オブジェクトの作成時にclient.manifestを使用するようにVBAを変更しました。
Sub VBA()
Dim actCtx As Object
Set actCtx = CreateObject("Microsoft.Windows.ActCtx")
actCtx.Manifest = "C:\Users\me\Desktop\COM Test\ComTest\ComTest\bin\Debug\client.manifest"
Dim obj As Object
Set obj = actCtx.CreateObject("ComTest.Main") '<-- Fails here.
MsgBox obj.Test()
End Sub
CreateObjectで失敗し、役に立たないエラーが発生しますMethod 'CreateObject' of object 'IActCtx' failed
。
sxstraceは、client.manifestを読み取り、アクティベーションコンテキストを作成することを示しています。プロセスモニターは、ComTest.dllにアクセスし、レジストリでクラス975DC7E0-4596-4C42-9D0C-0601F86E3A1Bを検索することを示しています。
私は何が欠けていますか?
.NETコードは次のとおりです。
<ComVisible(True)>
<Guid("EB6AA207-ECC7-413B-9A9B-9D142FF2701D")>
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)>
Public Interface IMain
Function Test() As String
End Interface
<ComVisible(True)>
<Guid("975DC7E0-4596-4C42-9D0C-0601F86E3A1B")>
<ProgId("ComTest.Main")>
<ClassInterface(ClassInterfaceType.None)>
<ComDefaultInterface(GetType(IMain))>
Public Class Main
Implements IMain
Public Function Test() As String Implements IMain.Test
Return "HELLO"
End Function
End Class
64ビットのWindows7を実行しています。