Pergunta

Eu estou tentando expor nossa biblioteca via COM, mas parecem estar a lutar as ferramentas mais do que o problema real. Independentemente da forma como eu escrevo minha classe COM expostos eu recebo o aviso: "XXX.DLL não contém quaisquer tipos que podem ser registrados para interoperabilidade" (projeto marcado como Registrar para interoperabilidade nas propriedades do projeto). Mesmo a classe simples abaixo (como a única classe em uma montagem que é assinado e marcado com ComVisible (false)) persiste ainda Aviso:

  [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;
    }
  }

Eu tentei regasm correr a partir da linha de comando na saída que os estados de bom grado "Tipos registrado com sucesso". No entanto, correndo com o / verbose mudar nenhuma informação extra é exibido (eu me lembro que ele lista o nome ou talvez apenas o número de tipos registrados). Também tentei executar regasm com o parâmetro / regfile para gerar um regfile que gera o seguinte:

[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}]

Eu não sou nenhum mago COM de qualquer medida, mas o registro parece válida para mim. No entanto, nada parece aparecer no registro ao executar regasm no conjunto.

Assim, a minha pergunta é se eu estou faltando alguma coisa no meu exemplo simples para ter o trabalho de registro, estou vendo falsas indicações e é o registro realmente correto e como posso melhor determinar se o registro COM realmente funciona

EDIT: Usando as alterações sugeridas pelo Kev eu não podia evitar os avisos do VS2008, mas eu poderia realmente obter algo registrado no registro usando regasm diretamente (nada no registro de apenas o VS2008 integração).

Então eu tentei remover a classe simples então eu tive uma assembleia vazia. Correndo regasm neste não relataram qualquer tipo de avisos, apenas "Tipos registrado com sucesso". Eu vejo avisos como "RegAsm: RA0000 Aviso: Não foram registradas tipos" ao executar RegAsm em alguns dos meus outros conjuntos que podem ser expostas incorretamente para COM. O que está acontecendo aqui, posso confiar em qualquer coisa, exceto o registro e que sobre o on / off avisos de regasm?

Foi útil?

Solução

Eu criei um projeto de biblioteca de classe com base no seu código da seguinte forma:

Na página de propriedades do projeto, selecione a guia Assinatura. Marque a opção 'Assinar o assembly' e selecione <New...> do 'Escolha um arquivo de chave nome forte:'. Caixa suspensa

Eu adicionei então o seguinte (Example.cs) classe:

[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;
    }
}

Eu, então, construiu o projeto, em seguida, caiu para uma linha de comando onde o DLL foi a saída da compilação.

Para se inscrever:

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

Se as suas necessidades de componentes para ser acessível a múltiplas aplicações:

gacutil.exe -i COMInteropTesting.dll

Esta multa toda trabalhou em 32bit Windows 2003, Windows 2008 de 32 bits e Windows 7 de 64 bits.

Uma pegadinha, porém, é que, se você está testando o componente com digamos CScript em um sistema de 64 bits, você precisa executar o intérprete CScript correta. Se você registrou a montagem usando RegAsm.exe de 32 bits (pelo C:\Windows\Microsoft.NET\Framework\v2.0.50727), então você precisa executar o intérprete CScript 32 bit em c:\Windows\SysWOW64.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top