Is it possible to use registration free COM with Dotnet interop and C#? If so how does one add a reference to the COM object in the C# project?
I have a reg free ATL COM server dll with an embedded manifest and two test clients, one cpp the other c#. The cpp client correctly references the COM object using an import statement and either
#pragma comment(linker, "\"/manifestdependency:type='win32' name='TestComSvr2' version='1.0.0.0'\"")
or setting 'Additional Manifest Dependencies' to "type='win32' name='TestComSvr1' version='1.0.0.0'" under Linker->Manifest File options, after which the cpp client will run correctly just so long as the COM component is in the same directory.
The c# client though refuses to play at all.
Attempting to add a file reference to either the unregistered COM component dll or unregistered tlb results in the 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".
Registering just the type library with 'regtlib TestComSvr' and then creating either a file or COM reference to that results in the c# project failing to build with:
"Error loading type library/Dll. (Exception from HRESULT: 0x80029C4A (TYPE_E_CANTLOADLIBRARY))".
Registering the COM component and creating a reference normally in the c# project, setting the reference to Isolated, building the c# project then unregistering the component and running the c# project results in this exception:
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)).
Note: Even if this worked it wouldn't be a useful case anyway, since ultimately it still requires registration of the component, I just tested it for thoroughness.
So far the only way I've been able to reference the COM object from C# at all is by registering the COM object itself, which of course utterly defeats the point since then it isn't reg-free at all.
Anyone got any ideas?
(This is on WinXP with VS2010 sp1).
You need to:
You need to come up with your registration-free COM assembly manifest, where you state your dependancy on Neutrino.TestComSvr2 assembly:
<?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>
Note: i had a similar manifest in my question Registration-Free COM from ASP.NET?
Then you need to include this application manifest in your C# exe:
These steps are similar to what can be found on MSDN for adding a manifest to a managed application.
You also need to ensure that your Neutrino.TestComSvr2 assembly contains it's registration-free COM entries:
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>
And blingo blango, you should be working.
User contributions licensed under CC BY-SA 3.0