Como registrar programaticamente (defina o caminho correto para) uma biblioteca de tipos no .NET?
Usando o .NET 4.0, criei uma DLL habilitada para COM (vamos chamá-la de exemplo.dll) e a registrei e gerei a respectiva biblioteca de tipos usando o regasm.exe (regasm.exe / tlb / codebase example.dll); a biblioteca de tipos é chamada exemplo.tlb. A montagem é fortemente nomeada.
Isso funciona até agora e eu posso usar a DLL e o TLB de dentro do VBA.
Mas, por certas razões, preciso criar meu próprio utilitário, que faz o registro de DLL e a geração de TLB. Basicamente, esse utilitário estará no mesmo diretório da DLL e deve registrar a DLL encontrada nesse diretório, além de gerar o arquivo TLB a partir da DLL encontrada nesse diretório.
O registro de DLL e a geração de TLB parecem funcionar, mas existe o seguinte problema: Não encontrei nenhum meio aceitável de definir o caminho correto para o arquivo TLB no .NET 4.0, e é nesse ponto que ficaria muito grato por qualquer Socorro.
Para reproduzir e ilustrar, imagine a seguinte situação:
Eu tenho c: \ test_1 \ example.dll, altere o diretório para c: \ test_1 e execute regasm.exe / tlb / codebase example.dll. Isso faz pelo menos essas coisas, tanto quanto eu entendi: ele registra a DLL, cria o TLB (c: \ test_1 \ example.tlb) e de alguma forma registra o próprio TLB (veja abaixo o que quero dizer com isso).
Agora movo a DLL para c: \ test_2, coloco meu utilitário de registro e geração de TLB em c: \ test_2, altero o diretório para c: \ test_2 e execute meu utilitário. Aparentemente, a DLL é registrada corretamente e o TLB é gerado. Mas o TLB não éregistrado (ver abaixo).
Minha pergunta agora é como eu poderia registrar o TLB de dentro do .NET.
Ao registrar um TLB, quero dizer o seguinte: Ao usar o regasm.exe como mostrado acima, ele obviamente coloca o caminho para o TLB no registro (pelo menos, eu o encontrei lá). Quando você usa o oleview.exe para exibir a respectiva biblioteca de tipos, ele mostra esse caminho. Quando eu uso meu próprio utilitário para registro e geração de TLB, esse caminho não é atualizado - o caminho é sempre aquele que foi definido durante a execução do regasm.exe pela última vez.
Isso leva à situação em que o TLB não pode ser encontrado, por exemplo pelo Excel depois de mover a DLL e meu utilitário para outro diretório e executar o utilitário.
Esta é a parte relevante do código fonte dos utilitários (VB.net, tratamento de erros e interface do usuário removidos):
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
Espero ter conseguido expressar o problema com clareza suficiente. Minha pergunta se resume a saber se existe um método razoável no .NET que permita definir o caminho para o TLB no registro ou se eu tenho que manipular as respectivas entradas diretamente no registro (o que seria tolo porque ninguém sabe se o a próxima versão do Windows usa as mesmas entradas); um bônus seria saber como o regasm.exe faz isso.