Using .NET 4.0, I have made a COM-enabled DLL (let's call it example.dll), and I have registered it and generated the respective type library using regasm.exe (regasm.exe /tlb /codebase example.dll); the type library is called example.tlb. The assembly is strongly named.
This works so far, and I can use the DLL and the TLB from within VBA.
But for certain reasons, I need to make my own utility which does the DLL registration and TLB generation. Basically, this utility will be in the same directory as the DLL and should register the DLL which it finds in that directory as well as generate the TLB file from the DLL which it finds in that directory.
DLL registration and TLB generation seem to work, but there is the following problem: I have not found any acceptable means to set the correct path to the TLB file from within .NET 4.0, and that's the point where I would be very grateful for any help.
To reproduce and illustrate, imagine the following situation:
I have c:\test_1\example.dll, change directory into c:\test_1 and run regasm.exe /tlb /codebase example.dll. This does at least these things as far as I have understood: It registers the DLL, creates the TLB (c:\test_1\example.tlb) and somehow registers the TLB itself (see below what I mean by that).
Now I move the DLL to c:\test_2, put my registration and TLB generation utility into c:\test_2, change directory into c:\test_2 and run my utility. Apparently, the DLL gets registered correctly, and the TLB is generated. But the TLB is not registered (see below).
My question now is how I could register the TLB from within .NET.
By registering a TLB, I mean the following: When using regasm.exe like shown above, it obviously puts the path to the TLB into the registry (at least, I have found it there). When you use oleview.exe to view the respective type library, it shows that path. When I use my own utility for registration and TLB generation, this path is not updated - the path is always the one which has been set when lastly running regasm.exe.
This leads to the situation that the TLB cannot be found e.g. by Excel after moving the DLL and my utility to another directory and running the utility.
This is the relevant part of the utilities source code (VB.net, error handling and user interface stripped out):
sub Register()
Dim s_Path As String
Dim asm_DLL As [Assembly]
Dim rs_DLL As RegistrationServices
Dim tlc_DLL As TypeLibConverter
Dim ns_DLL As cls_TLBCreatorNotifySink
Dim tlb_DLL As UCOMICreateITypeLib
s_Path = Application.StartupPath & "\example.dll"
asm_DLL = Assembly.LoadFrom(s_Path)
rs_DLL = New RegistrationServices()
rs_DLL.RegisterAssembly(asm_DLL, AssemblyRegistrationFlags.SetCodeBase)
s_Path = Application.StartupPath & "\example.tlb"
ns_DLL = New cls_TLBCreatorNotifySink
tlc_DLL = New TypeLibConverter
tlb_DLL = CType(tlc_DLL.ConvertAssemblyToTypeLib(asm_DLL, s_Path, TypeLibExporterFlags.None, ns_DLL), UCOMICreateITypeLib)
tlb_DLL.SaveAllChanges()
end sub
Public Class cls_TLBCreatorNotifySink
Implements ITypeLibExporterNotifySink
Public Sub ReportEvent(eventKind As System.Runtime.InteropServices.ExporterEventKind, eventCode As Integer, eventMsg As String) Implements System.Runtime.InteropServices.ITypeLibExporterNotifySink.ReportEvent
End Sub
Public Function ResolveRef(assembly As System.Reflection.Assembly) As Object Implements System.Runtime.InteropServices.ITypeLibExporterNotifySink.ResolveRef
Return Nothing
End Function
End Class
I hope I have been able to express the problem clearly enough. My question boils down to whether there is a reasonable method within .NET which enables me to set the path to the TLB in the registry or if I have to manipulate the respective entries in the registry directly (which would be silly because nobody knows if the next windows version uses the same entries); a bonus would be to know how regasm.exe does it.