10

私は現在、Excel をクライアントとして、.NET dll をサーバーとして、登録不要の COM を動作させようとしています。現在、概念実証を機能させようとしているだけですが、問題が発生しています。

明らかに、私はExcelを使用しているため、実行可能ファイルと一緒にクライアントマニフェストを単純に使用することはできないため、Microsoft.Windows.ActCtxリンク)を使用しています

クライアント マニフェスト、アセンブリ マニフェスト、および dll はすべて同じ場所にあります。

残念ながら、C# で機能するものは Excel / VBA では機能しないようで、その理由がわかりません。C# テスト クライアントは完全に動作しますが、VBA では80070002エラーが発生し、メッセージMethod 'CreateObject' of object 'IActCtx' failed が表示されます。

COMTestObject次のように、単一のクラス/インターフェイスを COM ( / ) に公開する .NET dll (COMTestService.dll) がありICOMTestObjectます。

[ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("EEE50CDF-D8EC-4F38-B986-C231EC45171E")]
public interface ICOMTestObject
{
    [ComVisible(true)]
    string GetString(int number);
}

[ComVisible(true), ClassInterfaceAttribute(ClassInterfaceType.None), ComDefaultInterface(typeof(ICOMTestObject))]
[Guid("6E54611B-8B56-49E0-9415-E59B0774A4BE")]
public class COMTestObject : ICOMTestObject
{
    public COMTestObject()
    {
    }

    public string GetString(int number)
    {
        return string.Format("The number is: {0}", number);
    }
}

クライアント マニフェスト (COMTestService_Client.manifest):

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

アセンブリ マニフェスト (COMTestService.manifest):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly 
    manifestVersion="1.0" 
    xmlns="urn:schemas-microsoft-com:asm.v1" >
    <assemblyIdentity 
        name="COMTestService" 
        version="1.0.0.0" 
        processorArchitecture="msil" />
    <clrClass 
        clsid="{6E54611B-8B56-49E0-9415-E59B0774A4BE}" 
        progid="COMTestService.COMTestObject" 
        threadingModel="Both" 
        name="COMTestService.COMTestObject"
        runtimeVersion="v4.0.30319">
    </clrClass>
    <file 
        name="COMTestService.dll"
        hashalg="SHA1">        
    </file>
</assembly>

VBA クライアント コード:

Dim actCtx As Object
Set actCtx = CreateObject("Microsoft.Windows.ActCtx")
actCtx.Manifest = "...\COMTestService_Client.manifest"

Dim testObject As Object
Set testObject = actCtx.CreateObject("COMTestService.COMTestObject") 'This line throws... 

Dim text As String
text = thing.GetString(42)

Debug.Print text

C# クライアント コード:

var actCtxType = System.Type.GetTypeFromProgID("Microsoft.Windows.ActCtx");
dynamic actCtx = System.Activator.CreateInstance(actCtxType);
actCtx.Manifest = @"...\COMTestService_Client.manifest";

var type = System.Type.GetTypeFromProgID("COMTestService.COMTestObject");
dynamic obj = System.Activator.CreateInstance(type);
dynamic s = obj.GetString(42);

編集

プロットが厚くなります...ちょっとした楽しみとして、C# でオブジェクトを作成するための簡単な COM 可視の REGISTERED ヘルパー クラスを作成し、次にpublic object CreateObject(string manifestPath, string typeName)、C# exe からこれを呼び出すという行に沿ったメソッドを使用してそれを返します。問題はありませんが、VBA からの呼び出しは失敗します (80070002 再び、メッセージ: The system cannot find the file specified. )。今、私はさらに混乱しています...

ご協力いただきありがとうございます。さらに情報を提供する必要がある場合はお知らせください。喜んで対応させていただきます。

4

2 に答える 2

2

Process Monitorを使用して、dllがC:/ Program Files / Microsoft Office /Office11/で検索されていることを発見しました。すべてのdllをそこに移動すると、エラーはなくなりました。

ちなみに、Excelにファイルを探すのではなく、.tlbが見つかった場所を探すように指示する方法を誰かが知っている場合は、興味があります。(私はすでにPATH環境変数にパスを追加しようとしました)

于 2013-02-19T11:32:40.867 に答える
0

私はそのテクニックを使おうとしたことがあるとは言えませんし、何年にもわたって多くのインストールを行ってきました. なぜ .NET COM Visible サーバーを登録しないのでしょうか? Regasm は、レジストリに非常にクリーンで軽量な COM 登録を作成する傾向があります。古い管理されていない DllRegisterServer() のものよりもはるかにクリーンです。

于 2012-03-26T20:12:08.053 に答える