sexta-feira, 11 de maio de 2012

Erro de VB: 5981 - "Não foi possível abrir o armazenamento de macro"


Tentar rodar macros no Microsoft Word 97, sem ter permissões especiais na estação local resulta na seguinte mensagem de erro: 
HRESULT: 0x800A175D
Erro de VB: 5981
"Não foi possível abrir o armazenamento de macro"


Já tem um certo tempo que venho convivendo com esse erro dentro da empresa onde presto serviços, a solução encontrada pelo cliente, foi transformar todos os usuários, que necessitam usar do recurso, em administradores de suas estações de trabalho, eu não vou entrar no mérito de explicar o quão isso é um problema.


Como em muitas instituições públicas no país, o Windows XP e o Office 97 ainda são amplamente utilizados (infelizmente).


 O erro aconteceu quando tentamos utilizar macros no Office 97, sem que o usuário tenha um certo nível de permissão.


Pesquisando sobre o assunto na internet, não achei nada de muito direto para o meu problema, apenas outros fatores que podem levar ao mesmo erro, daí veio a idéia de juntar tudo isso num blog, primeiro porque é conhecimento adquirido e aqui é um bom lugar para persisti-lo, segundo porque por mais que pareça inútil tem pessoas que enfrentam o mesmo problema.


Sintomas:

Comandos não são corretamente executados ou retornam a mensagem "Não foi possível abrir o armazenamento de macro". Quado é executado o VBA (Visual Basic for Application)  a partir do Word 97 ou funcionalidades contidas no Normal.dot carregadas no procedimento Sub Main() do módulo da macro.


Mais Informações:


- MSForms.twd


Quando o usuário acessa o VBA (Visual Basic for Application) pela primeira vez, o VBA cria um arquivo chamado MSForms.twd na pasta %windir%\system32, este arquivo é uma espécie de cache de um objeto COM utilizado pelo VBA, um breve resumo sobre sua utilização:
Quando um controle é adicionado a um aplicativo habilitado para VBA, o Visual Basic for Applications (VBA) cria uma cópia de sua biblioteca de tipos em um arquivo com uma extensão .TWD ou um .exd. Esse arquivo é usado para mesclar as informações de tipo do controle, que ajuda a fornecer funcionalidades durante a execução dentro do aplicativo. 
 O arquivo MSForms.twd é utilizado pela COM Microsoft Forms 2.0 Object Library (fm20.dll), referência da maioria dos componentes visuais dos formulários, como botões, lista e caixas de texto por exemplo. É preciso regerar estes arquivos (.twd) sempre que há alterações no arquivo.


Usuário sem permissões especiais, não conseguem alterar o arquivo que esta contido na pasta do sistema.


- Procmon


Para os que não conhecem, procmon ou Process Monitor (link para download), é um app que deveria ser incluso na suite de aplicativos do windows, ele nada mais faz do que monitorar o comportamento de todos os processos abertos no windows, registrando tos os I/O's e entradas no regedit.

Foi através deste que consegui monitorar quais entradas de registro, o Microsoft Word 97 não conseguia acessar, para usuários sem permissão especial.

Eis a cara do aplicativo:
Process Monitor v3.01


Com a utilização do aplicativo encontrei restrição para acessar as seguintes chaves:


HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Help
HKEY_LOCAL_MACHINE\Software\Microsoft\Office\8.0\Common
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Proofing Tools\Spelling
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Proofing Tools\Grammar
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Proofing Tools\Thesaurus
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Proofing Tools\Hyphenation
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Type 1 Installer\Type 1 Fonts
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\WinSock2\Parameters


Usuários sem permissões especiais não conseguem acessar estas chaves de registro, é preciso liberar o acesso destas para usuários fracos.


- Batch (automatizar)


Uma vez localizada as entradas de registro, preparei um arquivo .cmd, para ser rodado pelo administrador da rede, para automatizar ao máximo a solução.


Para alterar a permissão de arquivos é preciso aplicar o comando: Cacls (ver referência).
Para alterar a permissão de entradas de registro é preciso usar: Regini (ver referência).


@echo off
@echo §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
@echo Dando permissão no arquivo MSForms.Twd e RefEdit.Twd 
@echo ... ... ... ... ... ... ... ... ... ... ... ... ... 
If Exist %systemroot%\system32\MsForms.Twd Goto JaExiste
Copy Nul: %systemroot%\system32\MsForms.Twd >Nul: 2>&1
:JaExiste
Cacls %systemroot%\system32\MsForms.Twd /E /P EveryOne:F


If Exist %systemroot%\system32\RefEdit.Twd Goto JaExiste2
Copy Nul: %systemroot%\system32\RefEdit.Twd >Nul: 2>&1
:JaExiste2
Cacls %systemroot%\system32\RefEdit.Twd /E /P EveryOne:F
@echo §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
@echo Dando permissão total em alguns registros
echo HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Help [1 5 7 11 14 17 21] >> c:\regs_temp.txt
echo HKEY_LOCAL_MACHINE\Software\Microsoft\Office\8.0\Common [1 5 7 11 14 17 21] >> c:\regs_temp.txt
echo HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Proofing Tools\Spelling [1 5 7 11 14 17 21] >> c:\regs_temp.txt
echo HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Proofing Tools\Grammar [1 5 7 11 14 17 21] >> c:\regs_temp.txt
echo HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Proofing Tools\Thesaurus [1 5 7 11 14 17 21] >> c:\regs_temp.txt
echo HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Proofing Tools\Hyphenation [1 5 7 11 14 17 21] >> c:\regs_temp.txt
echo HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks [1 5 7 11 14 17 21] >> c:\regs_temp.txt
echo HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Type 1 Installer\Type 1 Fonts [1 5 7 11 14 17 21] >> c:\regs_temp.txt
echo HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\WinSock2\Parameters [1 5 7 11 14 17 21] >> c:\regs_temp.txt
@echo ... ... ... ... ... ... ... ... ... ... ... ... ... 
@echo arquivo com lista de registros a serem alterados criado
@echo arquivo: c:\reg_temp.txt
regini c:\regs_temp.txt
@echo permissoes aplicadas
@echo ... ... ... ... ... ... ... ... ... ... ... ... ... 
pause

É isso ai galera, espero que isso, de alguma forma ajude alguém!