C# e LibreOffice SDK

Estou desenvolvendo um aplicativo desktop em .NET (C# + WPF) e na minha máquina funciona corretamente, consigo fazer a chamada do LibreOffice, abrir um arquivo e customizar a interface tudo através do meu aplicativo em .NET, porém para funcionar, é necessário que a versão do SDK seja a mesma do LibreOffice instalado na máquina, bem como a arquitetura da aplicação deve ser a mesma do LibreOffice (32 ou 64 bits).

Para funcionar a integração, tive que adicionar nas referências do meu projeto as DLLs que vem junto com o SDK:

  • cli_basetypes.dll
  • cli_cppuhelper.dll
  • cli_oootypes.dll
  • cli_ure.dll
  • cli_uretypes.dll

Então a princípio tudo certo, mas a minha dúvida é a seguinte:
Desenvolvi o aplicativo usando o LibreOffice 6.1 junto com o SDK de mesma versão e agora preciso que a aplicação rode em outra máquina com uma versão inferior do LibreOffice, o que não estou conseguindo atualmente, ocorrendo o seguinte erro:

  • System.IO.FileNotFoundException: Não foi possível carregar arquivo ou assembly ‘cli_cppuhelper.dll’ ou uma de suas dependências. Não foi possível encontrar o módulo especificado.

É possível executar a aplicação em outra máquina com versão diferente do LibreOffice? Como?
Além disso, é possível evitar os erros por a aplicação ser desenvolvida em 64bits e o LibreOffice instalado ser 32 bits por exemplo?

Pela especificidade da pergunta, eu sugiro assinar a lista de correio do desenvolvimento e perguntar lá. Veja em Development/Mailing List - The Document Foundation Wiki. Também pode ser legal acessar o canal IRC em irc://irc.freenode.net/#libreoffice-dev . A maioria dos desenvolvedores vive no fuso da Europa.

Depois de muitas tentativas consegui resolver o problema.

Foi necessário sobrescrever o evento AssemblyResolve para buscar as DLL do LibreOffice a partir do GAC (C:\Windows\Microsoft.NET\assembly).

Além disso a aplicação deve executar com a mesma arquitetura do LibreOffice instalado então foi necessário gerar dois executáveis, um 32bits e outro 64bits (marcando/desmarcando a propriedade do projeto “Prefer 32-bit”) para que o evento AssemblyResolve encontre a DLL certa no GAC.

Outra alteração necessária foi necessário setar no código a váriável de ambiente “UNO_PATH” que é possível encontrar nos registros do Windows

string unoPath = "";
RegistryKey hkcuView32 = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.CurrentUser, RegistryView.Default);
RegistryKey hkcuUnoInstallPathKey = hkcuView32.OpenSubKey(@"SOFTWARE\LibreOffice\UNO\InstallPath", false);
if (hkcuUnoInstallPathKey != null && hkcuUnoInstallPathKey.ValueCount > 0)
{
	unoPath = (string)hkcuUnoInstallPathKey.GetValue(hkcuUnoInstallPathKey.GetValueNames()[hkcuUnoInstallPathKey.ValueCount - 1]);
}
else
{
	RegistryKey hklmView32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default);
	RegistryKey hklmUnoInstallPathKey = hklmView32.OpenSubKey(@"SOFTWARE\LibreOffice\UNO\InstallPath", false);
	if (hklmUnoInstallPathKey != null && hklmUnoInstallPathKey.ValueCount > 0)
	{
		unoPath = (string)hklmUnoInstallPathKey.GetValue(hklmUnoInstallPathKey.GetValueNames()[hklmUnoInstallPathKey.ValueCount - 1]);
	}
}

Environment.SetEnvironmentVariable("UNO_PATH", unoPath, EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + @";" + unoPath, EnvironmentVariableTarget.Process);

Depois destas alterações, minha aplicação funcionou corretamente.