2012-03-06 11 views
12

E 'possibile utilizzare COM senza registrazione con Dotnet interop e C#? In tal caso, come si aggiunge un riferimento all'oggetto COM nel progetto C#?L'interoperabilità COM senza registri con C# è possibile?

Ho una DLL del server COM ATL senza reg con un manifest incorporato e due client di test, uno cpp l'altro C#. Il client cpp fa riferimento correttamente l'oggetto COM utilizzando un'istruzione di importazione e di

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

o l'impostazione a 'aggiuntive manifesto Dipendenze' "type = 'Win32' name = versione 'TestComSvr1' = '1.0.0.0'" sotto Linker -> Opzioni file manifest, dopo di che il client cpp verrà eseguito correttamente purché il componente COM si trovi nella stessa directory.

Il client C# si rifiuta comunque di giocare.

Il tentativo di aggiungere un riferimento al file sia alla non registrato dll componente COM o risultati TLB non registrati in errore:

"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".

Registrazione solo la libreria dei tipi con 'Regtlib TestComSvr' e quindi la creazione di un file o COM riferimento a tale risultato il progetto C# non riuscendo a costruire con:

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

Registrazione del componente COM e la creazione di un punto di riferimento normalmente nel progetto C#, impostando il riferimento alla isolato, la costruzione del progetto C# quindi l'annullamento della registrazione il componente e l'esecuzione dei C# risultati in questa eccezione:

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: Anche se questo ha funzionato non sarebbe un caso utile in ogni caso, dal momento che in ultima analisi, richiede ancora la registrazione del componente, ho appena provato per completezza.

Finora l'unico modo in cui sono riuscito a fare riferimento all'oggetto COM da C# è registrando l'oggetto COM stesso, che ovviamente sconfigge completamente il punto da allora non è affatto reg-free.

Qualcuno ha qualche idea?

(Questo è su WinXP con VS2010 sp1).

+0

Chiedersi se è necessario creare un file manifest per l'exe di Visual Studio stesso? trovato questo link, ma non sono sicuro che sia tutto così utile http://msdn.microsoft.com/en-us/library/ms973913.aspx – PeskyGnat

+2

Inoltre, cosa succede se si crea una dope di interoperabilità con tlbimp e si fa riferimento a questo? cioè con 'tlbimp '? – PeskyGnat

risposta

12

è necessario:


  1. È necessario venire con il manifesto dell'assembly COM senza registrazione, in cui dichiarate la vostra dipendenza su Neutrino.TestComSvr2 ​​ montaggio:

    <?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: Ho avuto un manifesto simile nella mia interrogazione Registration-Free COM from ASP.NET?

  2. allora avete bisogno di includere questa applicazione manifesto nella vostra C# exe:

    1. Fare clic con il tasto destro del mouse sul progetto in Esplora soluzioni.
    2. Fare clic su "Aggiungi nuovo elemento".
    3. Selezionare "File manifest applicazione".

Questi passaggi sono simili a quello che può essere trovato su MSDN per adding a manifest to a managed application.

È inoltre necessario garantire che il vostro Neutrino.TestComSvr2 ​​ assieme contiene è voci COM senza registrazione:

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> 

E Blingo blango, si dovrebbe lavorare.

+0

Una combinazione di questo e il suggerimento di PeskyGnat per generare direttamente l'assembly di interoperabilità da tlb ha finalmente funzionato senza registrare né il componente COM né la sua libreria dei tipi. Grazie mille. – Neutrino

+0

Questo manifest ha funzionato quasi come è, ma ho dovuto inserire ".dll" alla fine del nome di dependendAssebmly nel manifest dell'applicazione: name = "mycomserver.dll". –

Problemi correlati