Registration COM-Interop (.tlb) including Assembly (.dll) references - c#

I'm trying to register my Classlib.dll for using COM interop with the regasm.exe tool.
In general this is not a problem.
like this: > regasm.exe MyAsm.dll /tlb: MyAsm.tlb
But now I use a .dll reference in my classlib project. The general registration still works but then the dll reference gets lost and the functions are useless.
I'm sure there is a simple solution for this as the automatic registration via VisualStudio Build settings works fine.
So how can I manually adjust my script?
My current approaches are:
uing the option: regasm /asmpath
use of the tools: Tlbexp.exe, Tlbimp.exe
My current information sources:
Regasm.exe (Assembly Registration Tool)
Registration free COM interop. assembly B reference assembly A?
Registration-Free COM Interop and Dependent Assemblies
Since the documentaries are unfortunately very limited and I am new to the COM topic it would be great if you could help me.

Related

Does GAC conflict with the Registry for Assembly Loading?

I have a DLL I generate from a C# project. I then register it via regasm so that the library can be used inside several legacy VB scripts.
Recently I created a new project (C# console app) that will reuse certain modular aspects of the original library, and per good programming practice it made sense to add the library to the GAC for reuse by this and any future projects.
I've found that it plays nice at first, but after the server is rebooted, the VB scripts crash and burn, claiming they are unable to create an object of one of the types defined in the library.
The fix involves removing the library from the GAC and re-registering the library via regasm.
The libraries in the registry and GAC come from the same physical DLL file - same directory and everything.
I've confirmed the existence of registry entries for the library every step of the way, which says regasm did its job.
GAC entries only exist when the library is installed, and properly disappear when it is uninstalled. They only ever appear under GAC_MSIL, where, to my knowledge, they should be.
Any ideas why this is happening?
EDIT: I did not read the fine print, haha. On the regasm documentation I just saw this: "Creates a Codebase entry in the registry. The Codebase entry specifies the file path for an assembly that's not installed in the global assembly cache. Don't specify this option if you will subsequently install the assembly that you're registering into the global assembly cache. It is strongly recommended the assemblyFile argument that you specify with the /codebase option be a strong-named assembly." I was using that switch, so I will dig deeper. In the meantime any additional insights are greatly appreciated.
I would guess you didn't renew the GUIDs and/or distinguish the fully qualified type names of the new library and when you installed it with regasm, the old entries in the registry got overwritten. Registering the old library again has overwritten the new library's registry, but as you don't use it through COM that didn't affect it and now the scripts work again.

My DLL should use another DLL dynamically

I have created a COM DLL in C#.
In this DLL I am linking against a third party DLL ("thirdpartydll.dll").
When I set "thirdpartydll.dll" to be output into the Release folder during the compilation, all works fine.
But I do not want to distribute "thirdpartydll.dll" with my DLL.
I would like my DLL to use the "thirdpartydll.dll" that may (or may not) have been registered by the third party.
For example, if the third party installed "thirdpartydll.dll" to C:\Program Files (x86)\Third Party\thirdpartydll.dll, then my COM DLL should use this.
Currently this does not work. I get the automatic error 80070002. I guess it means that my COM DLL can not find "thirdpartydll.dll". I am not sure why. I thought my COM DLL would find it automatically.
If you do not want to care where (non COM) thirdparty.dll is installed on the target system, it has to be install into the Global Assembly Cache (GAC).

Configure .NET-Based Components for Registration-Free Activation

I've been trying to get a registration-free .NET based COM DLL to work, but without success.
In Visual Studio 2008 I added a new C# class library.
I enabled the 'make assembly COM-visible' and 'register for COM interop' options.
I added a public interface and class with some functions.
I added a manifest dependency to my C++ client application: #pragma comment(linker,"/manifestdependency ...
But when I start my application I get 'the application has failed to start because the application configuration is incorrect'.
I've used Microsoft's mt tool to extract the manifest files of both the C++ client application and the C# COM DLL and the information in both is the same (the dependentAssembly in the C++ manifest file contains the same name and version as the assemblyIdentity in the COM manifest file).
I've also tried the approach described on http://msdn.microsoft.com/en-us/library/eew13bza.aspx but with similar results.
Similarly I tried to add a reference to my COM project in 'Framework and References' of my C++ client application. The information on that property page looked promising (it shows options like 'copy local', 'copy dependencies', etc and properties like the 'assemblyIdentity'), but Visual Studio neither copies the DLLs nor adds a dependency to the manifest file automatically.
Note that the 'registered variant' works fine.
Anyone have any ideas of what I'm doing wrong?
Update:
When I create a simple C++ DLL and embed a manifest with the same name and version of my .NET COM DLL (same assemblyIdentity) my application starts up fine. So the problem lies with the manifest file of my .NET COM DLL.
I can successfully extract the manifest from the DLL with mt -managedassemblyname:... and then embed the same manifest with mt -outputresource:..., but this also doesn't cause Windows to successfully resolve the dependency.
I found the steps needed to get registration-free .NET COM interop working myself :-)
Run: mt -managedassemblyname:"myDll.dll" -out:"myDll.manifest"
Clean manifest (see format at http://msdn.microsoft.com/en-us/library/eew13bza.aspx). Mainly I needed to remove all tags except for assemblyIdentity, clrClass and file (and specifically remove the runtime, mvid and dependency tags).
Run mt -outputresource:"myDll.dll" -manifest "myDll.manifest". Basically this adds the modified manifest as a resource to the DLL. Note that this is apparently not the same manifest (location)! If I reextract the manifest with the managedassemblyname option I still get the 'old' manifest. If I extract it with the inputresource option I get the new one.
I pretty much found this all thanks to Windows Vista. Unlike my Windows XP it contains a tool called sxstrace that gives rather detailed information about the problems with side-by-side execution.
When I did this, I started with a very simple, basic component to get the COM stuff sorted. Also I used a script client in the initial development.
I did not use Visual Studio, but instead a text editor for the .NET code. I inserted the GUIDs for the assembly and for the Interfaces, and marked the interfaces for AutoDispatch.
using System;
using Interop=System.Runtime.InteropServices;
namespace Whatever
{
[Interop.Guid("xxxxxxxx-9120-4283-b972-changethis05")]
[Interop.ComVisible(true)]
[Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)]
public partial class MyClass :
...
}
I made sure my class had a default (no-arguments) constructor.
I ran regasm /codebase by hand, from the command line, specifying the .NET assembly.
I hand-coded the javascript to instantiate the object.
When things were confusing, I checked the ProgId with OleView.exe.
Once you have the very basic stuff working, add complexity gradually, until you get the working solution.
You can also use the approach from the other direction; from the client. .NET Assemblies like System.Random are marked for COM interop when you install .NET, so you can use them to verify that your approach in C++ is correct. Instantiating a System.Random ProgId is something like the "hello, World" of C++-to-.NET-via-COM. If that succeeds, then you know the basic approach in C++ is sound.

How to deploy a COM

I just finished building my new COM project (C#, .NET 3.5). This project will be called by a VFP application. It's working great on my development machine, but now I need to know how to deploy it on the user's machine. Click Once isn't available for this kind of project, so I guess I'm stuck with manually distributing the DLL.
So, where should I put the DLL and how do I register it?
BTW, the 3.5 framework is already installed on the user's machine.
TIA
I've really never used RegSvr32 with .Net assemblies, rather I use the regasm with the /codebase option:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\regasm.exe /codebase mydll.dll
You can also use the /tlb option to export the type library and register it.
Of course the easiest way, just create an installer with vstudio and it will do this for you.
Creating a Description of the COM class and Interfaces
.Net assemblies don't include information in Type Library compatible format. So it is necessary for the programmer to run one of two .Net-supplied utilities to extract the assembly description of a class into a Type Library file.
One utility is TLBEXP.EXE, the .Net Type Library Exporter. This command line utility takes as input the name of an assembly DLL file to be converted to a Type Library. The programmer can also specify the name of a Type Library file to be created.
tlbexp ComServer.dll /out:ComServer.tlb
Assembly exported to C:\Magellan\Source\Output\Debug\ComServer.tlb
Once a Type Library has been created, it can be referenced by a COM client to obtain the information necessary for the COM client to bind to the interfaces of the COM class, and activate the COM class at runtime.
Registration of the COM Class and Interfaces
For a COM class to be accessible by the client at runtime, the COM infrastructure must know how to locate the code that implements the COM class. The following command accomplishes this:
regasm ComServer.dll
Your DLL can be put anywhere you wish, but a good choice is C:\Program Files\MyApplication.
http://www.csharphelp.com/archives/archive190.html

Building .NET COMInterop project without first registering the COM service

I am building a C# UI to interact with a COM Service (.exe). The VS2005 COM project outputs a valid typelib (TLB), which is referenced by the C# project. However, the VS2005 C# project insists that the service be registered in order to build the C# project, even though the typelib appears perfectly valid when examined with the OLE Object Viewer.
We would rather not register the service on the build server, if possible. Further, debug builds cannot register the COM object as a service, since this makes debugging in general, and startup code in particular, more difficult (can't use F5 - Start Debugging).
What should I look for in order to get this working? Do I need to register just the TypeLib? If so, why would COMInterop insist on having the service or TLB registered in order to build correctly (and, is there a command-line tool for this on Win2003 with VS2005)?
If I recall correctly, once apon a time I built a C# web service which referenced the Win2003 firewall COM object, but we built it on Win2000 (which does not have such a thing) simply by referencing the TLB file with no registration required, so I don't understand why this should be a problem now.
You need to create interop assembly using tlbimp.exe tool. And add reference to this assembly in your project instead of typelib. In this case building will not require registered com server.
If you do not want to ship yet another assembly, you can extract interface description from generated interop assembly using Reflector and include them into project as source files.
Solved this by adding a -regtypelib command to the COM service, which calls the AtlRegisterTypeLib function but does not register the service. Suboptimal because it will leave registery entries on the build server, but quick and it works.

Categories

Resources