Como obter o COM sem registro funcionando em interoperabilidade gerenciada / não gerenciada

StackOverflow https://stackoverflow.com/questions/5392152

  •  28-10-2019
  •  | 
  •  

Pergunta

Tenho um objeto COM em processo C ++ / ATL não gerenciado (em Unmanaged.dll) que estou tentando usar de uma DLL C # gerenciada (Managed.dll). No entanto, quero usar o COM grátis de registro. Eu descubro até estas etapas:

  • Registre o objeto COM na máquina de desenvolvimento. O servidor em processo deve ter uma biblioteca de tipos devidamente registrada.
  • Adicione uma referência ao objeto COM dentro do projeto C # e, a seguir, defina as Propriedades da referência como Isolado= Verdadeiro.

Isso produz Unmanaged.dll, Managed.dll e Native.Managed.manifest. Abrindo o manifesto, fica bem claro como o sistema o usa para carregar o objeto COM de uma forma sem registro.

Aqui está o problema. Eu tenho um EXE gerenciado (Managed.exe) que carrega dinamicamente Managed.dll para acessar tipos públicos. O que quero dizer com "dinamicamente" é que ele usa Assembly.LoadFrom ("Managed.dll"). Quando o código dentro de Managed.dll tenta criar o objeto COM, ele obtém uma exceção "classe não registrada". Parece que o contexto de ativação não é configurado corretamente quando Managed.dll é carregado.

Existe uma maneira de fazer o registro COM grátis funcionar nesse cenário?

Foi útil?

Solução

Dois dias sem resposta, então aqui está o que descobri nesse período ...

Na verdade, parece que o contexto de ativação é configurado pelo sistema operacional na inicialização do processo com base no manifesto associado ao EXE principal. Isso significa que todos os elementos relacionados ao COM sem registro devem estar no Main.exe.manifest no momento em que o processo é iniciado. Isso quebra o isolamento entre EXE e DLLs. Se uma DLL for responsável pela criação de objetos COM, você não esperaria que o manifesto EXE contivesse as informações COM sem registro. Você pode ter esperado que o manifesto associado à DLL fosse mesclado ao contexto de ativação do processo no momento em que a DLL fosse carregada, mas isso não aconteceu.

Para contornar isso, a DLL deve configurar um novo contexto de ativação antes de criar o objeto COM. Para piorar as coisas, atualmente (a partir do .NET 4.0) não há uma maneira gerenciada de fazer isso. Portanto, a DLL terá que invocar as seguintes funções do Win32:

Eu envolvi essas chamadas com uma classe gerenciada que chama CreateActCtx e ActivationActCtx no construtor e DeativateActCtx e ReleaseActCtx em IDisposable :: Dispose.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top