1

COMを介してライブラリを公開しようとしていますが、実際の問題よりもツールと戦っているようです。COM公開クラスの記述方法に関係なく、「XXX.dllにはCOM相互運用機能に登録できるタイプが含まれていません」(プロジェクトのプロパティでプロジェクトをCOM相互運用機能に登録としてマーク)と表示されます。以下の単純なクラス(ComVisible(false)で署名およびマークされているアセンブリ内の唯一のクラスとして)でも、警告が持続します。

  [Guid("77699130-7D58-4d29-BE18-385871B000D1")]
  [ComVisible(true)]
  public interface IExample
  {
    string GetText();
    void SetText(string text);
  }

  [Guid("F91E5EE1-D220-43b5-90D1-A48E81C478B7")]
  [ComVisible(true)]
  public class Example : IExample
  {
    private string m_text = "default text";

    public string GetText()
    {
      return m_text;
    }

    public void SetText(string text)
    {
      m_text = text;
    }
  }

「タイプが正常に登録されました」と喜んで表示される出力のコマンドラインからregasmを実行しようとしました。ただし、/ verboseスイッチを指定して実行すると、追加情報は表示されません(名前または登録されているタイプの数だけがリストされていることを思い出しているようです)。また、/ regfileスイッチを使用してregasmを実行し、これを生成するregfileを生成してみました。

[HKEY_CLASSES_ROOT\ComExample.Example]
@="ComExample.Example"

[HKEY_CLASSES_ROOT\ComExample.Example\CLSID]
@="{F91E5EE1-D220-43B5-90D1-A48E81C478B7}"

[HKEY_CLASSES_ROOT\CLSID\{F91E5EE1-D220-43B5-90D1-A48E81C478B7}]
@="ComExample.Example"

[HKEY_CLASSES_ROOT\CLSID\{F91E5EE1-D220-43B5-90D1-A48E81C478B7}\InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="ComExample.Example"
"Assembly"="COMInteropTesting, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8568e57f6b170d6c"
"RuntimeVersion"="v2.0.50727"

[HKEY_CLASSES_ROOT\CLSID\{F91E5EE1-D220-43B5-90D1-A48E81C478B7}\InprocServer32\1.0.0.0]
"Class"="ComExample.Example"
"Assembly"="COMInteropTesting, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8568e57f6b170d6c"
"RuntimeVersion"="v2.0.50727"

[HKEY_CLASSES_ROOT\CLSID\{F91E5EE1-D220-43B5-90D1-A48E81C478B7}\ProgId]
@="ComExample.Example"

[HKEY_CLASSES_ROOT\CLSID\{F91E5EE1-D220-43B5-90D1-A48E81C478B7}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}]

私はCOMウィザードではありませんが、登録は有効に見えます。ただし、アセンブリでregasmを実行すると、レジストリに何も表示されないようです。

だから私の質問は、登録を機能させるための簡単な例に何かが欠けているかどうか、誤った表示が表示されているかどうか、登録は実際に正しいかどうか、そしてCOM登録が実際に機能するかどうかをより適切に判断するにはどうすればよいですか?

編集:Kevによって提案された変更を使用して、VS2008からの警告を回避することはできませんでしたが、実際にはregasmを直接使用してレジストリに登録されたものを取得できました(VS2008統合だけのレジストリには何もありません)。

次に、単純なクラスを削除しようとしたため、アセンブリが空になりました。これでregasmを実行しても、「タイプは正常に登録されました」という警告のみが報告されました。COMに誤って公開されている可能性のある他のアセンブリの一部でRegAsmを実行すると、「RegAsm:警告RA0000:タイプが登録されていません」などの警告が表示されます。ここで何が起こっているのですか、レジストリ以外のものを信頼できますか?また、レガスムからのオン/オフ警告はどうですか?

4

1 に答える 1

2

次のように、コードに基づいてクラスライブラリプロジェクトを作成しました。

プロジェクトのプロパティページで、[署名]タブを選択します。[アセンブリに署名する]チェックボックスをオンにして、[厳密<New...>な名前のキーファイルを選択する:]ドロップダウンボックスから選択します。

次に、次のクラスを追加しました(Example.cs)

[Guid("77699130-7D58-4d29-BE18-385871B000D1")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[ComVisible(true)]
public interface IExample
{
    [DispId(1)]
    string GetText();

    [DispId(2)]
    void SetText(string text);
}

[Guid("F91E5EE1-D220-43b5-90D1-A48E81C478B7")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class Example : IExample
{
    private string m_text = "default text";

    [ComVisible(true)]
    public string GetText()
    {
      return m_text;
    }

    [ComVisible(true)]
    public void SetText(string text)
    {
      m_text = text;
    }
}

次に、プロジェクトをビルドしてから、ビルドからDLLが出力されるコマンドラインにドロップしました。

登録するために:

regasm.exe COMInteropTesting.dll /register /codebase /tlb

コンポーネントに複数のアプリケーションからアクセスできるようにする必要がある場合:

gacutil.exe -i COMInteropTesting.dll

これはすべて、Windows 2003 32ビット、Windows 2008 32ビット、およびWindows764ビットで正常に機能しました。

ただし、64ビットシステムでCScriptを使用してコンポーネントをテストする場合は、正しいCScriptインタープリターを実行する必要があります。RegAsm.exe32ビット(で)を使用してアセンブリを登録した場合はC:\Windows\Microsoft.NET\Framework\v2.0.50727、で32ビットCScriptインタープリターを実行する必要がありますc:\Windows\SysWOW64

于 2009-10-30T10:24:18.760 に答える