2012-03-06 18 views
12

¿Es posible usar COM libre de registro con DotNet interop y C#? Si es así, ¿cómo se agrega una referencia al objeto COM en el proyecto C#?Interoperación COM libre de Reg con C#, posible?

Tengo un dll de servidor COM ATL sin registro con un manifiesto incrustado y dos clientes de prueba, uno cpp el otro C#. El cliente CPP hace referencia correctamente el objeto COM utilizando una declaración de importación y de

#pragma comment(linker, "\"/manifestdependency:type='win32' name='TestComSvr2' version='1.0.0.0'\"") 

o la creación de 'Manifiesto adicional Dependencias' "type = 'win32' name = versión 'TestComSvr1' = '1.0.0.0'" bajo Enlazador -> Opciones de archivo de manifiesto, después de lo cual el cliente cpp se ejecutará correctamente siempre que el componente COM esté en el mismo directorio.

El cliente de C# se niega a jugar.

El intento de añadir una referencia de archivo a la DLL de componente COM registrado o resultados TLB no registrados en el error:

"A reference to 'blah blah' could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component".

Registro sólo la biblioteca de tipos con 'regtlib TestComSvr' y luego la creación de un archivo o COM referencia a que da lugar el proyecto de C# no haber construido con:

"Error loading type library/Dll. (Exception from HRESULT: 0x80029C4A (TYPE_E_CANTLOADLIBRARY))".

Registro del componente COM y la creación de una referencia normalmente en el proyecto C#, el establecimiento de la referencia a Aislado, la construcción del proyecto de C# y luego la anulación del registro el componente y la ejecución de los resultados del proyecto de C# en esta excepción:

Retrieving the COM class factory for component with CLSID {B1D0A80F-0050-4856-BACD-87D664E58CBE} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).

Nota: Incluso si esto funcionó no sería un caso útil de todos modos, ya que en última instancia, que todavía requiere el registro del componente, Acabo de prueba para minuciosidad.

Hasta ahora, la única manera en que he podido hacer referencia al objeto COM desde C# es registrando el objeto COM en sí, lo que desde luego derrota por completo el punto, ya que no está libre de registro.

¿Alguien tiene alguna idea?

(Esto está en WinXP con VS2010 sp1).

+0

¿Se pregunta si necesitaría crear un archivo de manifiesto para el propio Visual Studio? encontré este enlace, pero no estoy seguro de si es tan útil http://msdn.microsoft.com/en-us/library/ms973913.aspx – PeskyGnat

+2

Además, ¿qué ocurre si crea un dll de interoperabilidad con tlbimp y lo referencia? por ejemplo con 'tlbimp '? – PeskyGnat

Respuesta

12

es necesario:


  1. tiene que venir para arriba con su manifiesto de ensamblado COM sin registro, cuando usted indica su dependencia en neutrinos.TestComSvr2 ​​ montaje:

    <?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 version="1.0.0.0" name="MyApplication.app"/> 
    
        <!-- We depend on our COM object --> 
        <dependency> 
         <dependentAssembly> 
          <assemblyIdentity type="win32" name="Neutrino.TestComSvr2" version="1.0.0.0" /> 
         </dependentAssembly> 
        </dependency> 
    
    
        <!-- 
         Everything else in this sample manifest is not relavent to this answer, 
         but every developer should be doing their job and writing correct 
         Windows programs 
        --> 
    
        <!-- Disable file and registry virtualization. --> 
        <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> 
         <security> 
         <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> 
          <requestedExecutionLevel level="asInvoker" uiAccess="false" /> 
         </requestedPrivileges> 
         </security> 
        </trustInfo> 
    
        <!-- We are high-dpi aware on Windows Vista --> 
        <asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> 
         <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> 
         <dpiAware>true</dpiAware> 
         </asmv3:windowsSettings> 
        </asmv3:application> 
    
        <!-- Declare that we were designed and tested on Windows 7--> 
        <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 
         <application> 
          <!--The ID below indicates application support for Windows 7 --> 
          <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> 
          <!--The ID below indicates application support for Windows Vista --> 
          <!-- supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/ --> 
         </application> 
        </compatibility> 
    
        <!-- We depend on Common Controls version 6 (i.e. "enable themes") --> 
        <dependency> 
         <dependentAssembly> 
         <assemblyIdentity 
           type="win32" 
           name="Microsoft.Windows.Common-Controls" 
           version="6.0.0.0" 
           processorArchitecture="*" 
           publicKeyToken="6595b64144ccf1df" 
           language="*" 
         /> 
         </dependentAssembly> 
        </dependency> 
    

    Nota: que tuve un manifiesto similar en mi pregunta Registration-Free COM from ASP.NET?

  2. Luego hay que incluir esta aplicación se manifiestan en su C# exe:

    1. Haga clic derecho en el proyecto en el Explorador de soluciones.
    2. Haga clic en "Agregar nuevo artículo".
    3. Seleccione "Archivo de manifiesto de la aplicación".

Estos pasos son similares a lo que se puede encontrar en MSDN para adding a manifest to a managed application.

También es necesario asegurarse de que su montajeNeutrino.TestComSvr2 ​​contiene entradas es COM sin registro:

Neutrino.TestComSvr2.manifest

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 

    <assemblyIdentity type="win32" name="Neutrino.TestComSvr2" version="1.0.0.0" /> 

    <file name = "ContosoFrobber.dll"> 

     <comClass 
      progid="Frobber.Gizmo" 
      clsid="{00028C00-0000-0000-0000-000000000046}" 
      description="Gizmo Frobber by Contoso" 
      threadingModel = "Apartment" /> 

     <typelib 
      tlbid="{00028C01-0000-0000-0000-000000000046}" 
      version="1.0" 
      helpdir=""/> 
    </file> 
</assembly> 

Y blango blingo, usted debe estar trabajando.

+0

Una combinación de esto y la sugerencia de PeskyGnat de generar el ensamblado de interoperabilidad directamente desde el tlb finalmente funcionó sin registrar el componente COM o su biblioteca de tipos. Muchas gracias. – Neutrino

+0

Este manifiesto funcionó para mí casi como está, pero tuve que poner ".dll" al final del nombre de la dependenciandAssebmly en el manifiesto de la aplicación: name = "mycomserver.dll". –