Pregunta

Estoy tratando de exponer nuestra biblioteca a través de COM pero parece estar luchando contra las herramientas más que el problema real. Independientemente de cómo escriba mi clase expuesta COM, recibo la advertencia: & Quot; XXX.dll no contiene ningún tipo que pueda registrarse para la interoperabilidad COM & Quot; (proyecto marcado como Registrarse para interoperabilidad COM en las propiedades del proyecto). Incluso la clase simple a continuación (como la única clase en un ensamblado que está firmada y marcada con ComVisible (falso)) aún persiste:

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

He intentado ejecutar el regasmo desde la línea de comandos en la salida que con gusto dice " Tipos registrados con éxito " ;. Sin embargo, al ejecutar con el modificador / verbose no se muestra información adicional (parece recordar que enumera el nombre o tal vez solo el número de tipos registrados). También intenté ejecutar regasm con el modificador / regfile para generar un archivo de registro que genera esto:

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

No soy un asistente COM de ninguna medida, pero el registro me parece válido. Sin embargo, nada parece aparecer en el registro cuando se ejecuta regasm en el ensamblado.

Entonces, mi pregunta es si me falta algo en mi ejemplo simple para que el registro funcione, ¿estoy viendo indicaciones falsas y el registro es realmente correcto y cómo puedo determinar mejor si el registro COM realmente funciona?

EDITAR: Utilizando las modificaciones sugeridas por Kev, no pude evitar las advertencias de VS2008, pero en realidad pude obtener algo registrado en el registro usando el regasmo directamente (nada en el registro solo por la integración de VS2008).

Luego intenté eliminar la clase simple, así que tenía un ensamblaje vacío. Ejecutar el regasmo sobre esto no informó ningún tipo de advertencia, solo & Quot; Tipos registrados con éxito & Quot ;. Veo advertencias como & Quot; RegAsm: advertencia RA0000: No se registraron tipos & Quot; cuando ejecuto RegAsm en algunos de mis otros ensamblados que pueden estar expuestos incorrectamente a COM. ¿Qué está pasando aquí? ¿Puedo confiar en otra cosa que no sea el registro y qué pasa con las advertencias de encendido / apagado del regasmo?

¿Fue útil?

Solución

Creé un proyecto de biblioteca de clases basado en su código de la siguiente manera:

En la página de propiedades del proyecto, seleccione la pestaña Firma. Marque la casilla de verificación 'Firmar el ensamblaje' y seleccione <New...> en el cuadro desplegable 'Elija un archivo de clave de nombre seguro:'.

Luego agregué la siguiente clase (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;
    }
}

Luego construí el proyecto y luego lo dejé caer en una línea de comando donde la DLL salió de la compilación.

Para registrarse:

  

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

Si su componente necesita ser accesible para múltiples aplicaciones:

  

gacutil.exe -i COMInteropTesting.dll

Todo esto funcionó bien en Windows 2003 de 32 bits, Windows 2008 de 32 bits y Windows 7 de 64 bits.

Sin embargo, un problema es que si está probando el componente con, por ejemplo, CScript en un sistema de 64 bits, debe ejecutar el intérprete CScript correcto. Si registró el ensamblado utilizando 32 bits RegAsm.exe (en C:\Windows\Microsoft.NET\Framework\v2.0.50727), entonces debe ejecutar el intérprete CScript de 32 bits en c:\Windows\SysWOW64.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top