segunda-feira, fevereiro 12, 2007

Problemas com Crystal Reports após instalação do Visual Studio 2005 SP1


Não sei quantos de vocês já tiveram o problema que eu vou descrever agora, mas me parece que ocorreu logo após a instalação do Service Pack 1 do Visual Studio 2005, que pode ser encontrado aqui.

Let´s get down to business.

Após instalar o SP 1 do Visual Studio 2005, fiquei um tempo sem ter que trabalhar em um projeto que usa extensivamente relatórios feitos em Crystal Reports. Semana passada, quando tive que efetuar uma alteração em um dos relatórios desse projeto, abri a solução rodei o projeto e vejam a tela bacaninha que pipocou.



Legal, não?

A única pista que eu tinha até o momento era o bendito CLSID {11BD5260-15B6-412D-80DB-12BB60B8FE50}, abri o regedit e fiz uma procura por esse CLSID, o que me deu uma pista um pouco melhor de quem poderia ser o culpado de toda essa bagunça. Imagem abaixo mostra que esse CLSID se refere á uma biblioteca do Crysta Reports chamada sacommlayer.dll.



Procurei a abençoada da sacommlayer.dll no caminho que estava no Registro, C:\Arquivos de programas\Arquivos comuns\Business Objects\2.7\Bin\, para minha não muita surpresa, a criatura não estava lá. Entrei em uma outra máquina que o Service Pack 1 não tinha sido instalado, e como eu aprendi que tudo na vida só a violência constrói, copiei todas as dlls existentes no diretório onde a sacommlayer.dll se encontrava para a minha máquina.

Tentei acessar novamente a página em que o relatório estava dando problema e dessa vez a página abriu sem problemas. Antes a página que tinha o componente do Crystal Reports nem abria, agora já estava abrindo. Apliquei alguns filtros no relatório e mandei executar e para minha não grande surpresa novamente mais um problema.



Como vocês podem ver pela imagem, por algum motivo na minha super cópia de arquivos de uma máquina para outra, eu devo ter esquecido de incluir essa tal de crpe32.dll. Entrei no diretório C:\Arquivos de programas\Arquivos comuns\Business Objects\2.7\Bin\, e a dll estava lá. Imaginei que aquele não seria o local correto dessa dll, para tirar essa dúvida abri o FileMon e apliquei o filtro para crpe32.dll. Pra minha supresa o FileMon não "pegava" nada, então possivelmente a excessão estava ocorrendo no lado gerenciado da coisa.

Se nós dermos uma olhada na stack trace da última imagem, podemos ver que a excessão foi lançada no construtor da classe CrystalDecisions.CrystalReports.Engine.CRPE. Abrindo o Reflector e tentarmos localizar o assembly CrystalDecisions.CrystalReports.Engine, não será possível. Não sei o motivo, mas para resolver isso tem um jeitinho.

Abra o prompt e navegue até o diretório, %windir%\Assembly\GAC_MSIL\CrystalDecisions
.CrystalReports.Engine\10.2.3600.0__692fbea5521e1304, e lá estará a CrystalDecisions.CrystalReports.Engine.dll. Copie a dll para um outro diretório fora dessa árvore de diretórios e será possível abrir esse assembly pelo Reflector.

Ufa, depois de tudo isso vamos voltar ao nosso problema.

Navegando pelo Reflector será possível ver que existem dois construtores para essa classe, um estático e ou de instancia, abra o construtor estático e veremos a imagem a seguir.



A linha marcada em vermelho chama o método estático CRPE.GetDllPath() que pode ser a nossa fonte de respostas, abrindo o código desse método no Reflector temos o seguinte:



Opa, agora sim hein, parece que esse método "descobre" o caminho da crpe32.dll acessando a seguinte chave no registro HKLM\SOFTWARE\Crystal Decisions\10.2\Crystal Reports e procurando pelo caminho contido no valor CommonFiles, entrando no registro da minha máquina, como mostra a imagem abaixo, não existe o valor CommonFiles.



Daí em diante a coisa foi simples, criei o valor CommonFiles e o defini o caminho C:\Arquivos de programas\Arquivos comuns\Business Objects\2.7\Bin.

Executei novamente o projeto e abri a página que tinha o relatório com problema e agora tudo funciona perfeitamente. :)

Cagamba, que trabalho, mas o importante é que agora está tudo funcionando como era antes, espero que isso tenha ajude alguém.

[]´s

Thiago