ID do artigo: 164787 - Última revisão: domingo, 3 de outubro de 2004 - Revisão: 2.3

INFO: Interface Windows Rundll e Rundll32

Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.

Nesta página

Expandir tudo | Recolher tudo

Sumário

O Microsoft Windows 95, Windows 98 e o Windows Millennium Edition (Me) possuem dois programas utilitários de linha de comando chamados Rundll.exe e Rundll32.exe, que permitem invocar uma função exportada por uma DLL, tanto de 16 bits quanto 32 bits. Não entanto, os programas Rundll e Rundll32 não lhe permitem chamar qualquer função exportada de uma DLL. Por exemplo, não é possível usar esses programas utilitários para chamar as chamadas API do Win32 (Application Programming Interface) exportadas por DLLs de sistema. Os programas lhe permitem somente que chame funções por uma DLL que esteja explicitamente escrita para ser chamada por eles. Esse artigo fornece detalhes adicionais sobre o uso dos programas Rundll e Rundll32 nos sistemas operacionais do Windows relacionados acima.

O Microsoft Windows NT 4.0, Windows 2000 e Windows XP vêm apenas com o Rundll32. Não há suporte para o Rundll (o utilitário Win16) em qualquer uma das plataformas.

Os programas utilitários Rundll e Rundll32 foram desenvolvidos originalmente somente para uso interno da Microsoft. Mas a funcionalidade oferecida por eles é tão genérica que agora estão disponíveis para uso geral. Note que o Windows NT 4.0 vem somente com o programa utilitário Rundll32 e oferece suporte somente para Rundll32.

Mais Informações

Rundll vs. Rundll32

O Rundll carrega e executa DLLs de 16 bits enquanto o Rundll32 carrega e executa DLLs de 32 bits. Se o tipo errado de DLL for passado para o Rundll ou Rundll32, poderão ocorrer falhas na execução sem que haja a indicação de mensagens de erro.

Linha de comando Rundll

A linha de comando para Rundll é da seguinte maneira:
   RUNDLL.EXE <dllname>,<entrypoint> <optional arguments>
				
Segue um exemplo:
   RUNDLL.EXE SETUPX.DLL,InstallHinfSection 132 C:\WINDOWS\INF\SHELL.INF
				
Existem três problemas a serem cuidadosamente considerados na linha de comando acima:
  1. O Rundll ou o Rundll32 procura o nome da DLL dada nos locais padrão (para ver maiores detalhes da função LoadLibrary(), consulte a documentação pertinente) Recomenda-se que seja forneçido o caminho completo para a DLL, para ter certificar-se de que encontre a DLL correta. Para melhores resultados, use o nome de arquivo curto em vez do nome de arquivo longo, para ter certeza de que nenhum caractere inválido aparecerá. Note que isso, em especial, significa que a DLL na pasta"C:\Arquivos de Programas" deve ser convertido para um nome menor.
  2. O nome da DLL <dllname> não pode conter nenhum espaço, vírgulas ou aspas. Isso é uma limitação no analisador de linha de comando do Rundll.
  3. Na linha de comando acima, a vírgula (,) entre o<dllname> e a função <entrypont> é extremamente importante. Se a virgula estiver faltando, o Rundll ou o Rundll32 irá falhar sem que haja a indicação de erro. Além disso, não pode existir nenhum espaço entre o <dllname>, a vírgula e a função <entrypoint>.

Como funciona o Rundll

O Rundll realiza as seguintes etapas:
  1. Ele analisa a linha de comando.
  2. Ele carrega a DLL específica pela LoadLibrary ().
  3. Ele obtém o endereço da função <entrypoint> via GetProcAddress().
  4. Ele chama a função <entrypoint>, passando a extensão da linha de comando que são os <optional arguments>.
  5. Quando a função <entrypoint> retorna, o Rundll.exe descarrega a DLL e fecha.

Como escrever sua DLL

Na sua DLL, escreva a função <entrypoint> com o seguinte protótipo:

DLL de 16 bits:

  void FAR PASCAL __loadds
  EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
				
DLL de 32 bits:
  void CALLBACK
  EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
				
Novamente, existem 3 questões a serem consideradas com a função EntryPoint:
  1. É claro que o nome "EntryPoint" deve ser substituído com o nome real de sua função de ponto de entrada. Note que o ponto de entrada do Rundll32 não possui nenhuma relação com a função DllEntryPoint em uma DLL de 32 bits que controla processos e thread anexar/retirar notificações.
  2. A função de ponto de entrada para Rundll32 precisa ser definida usando a convenção de chamada _stdcall (padrões CALLBACK de uso do atributo _stdcall) Se o atributo _stdcall estiver faltando, os padrões de função para convenção de chamada _cdecl e o Rundll32 serão terminados anormalmanete após chamar a função.
  3. Uma vez que você deve declarar a função com a convenção de chamada _stdcall, da maneira descrita acima, o resultado será que o compilador Visual C++ irá exportá-la como _EntryPoint@16 se a DLL estiver escrita em C ou simplificará o nome se a DLL estiver escrita em C++. Por isso, esteja atento para usar o nome de exportação correto na linha de comando para Rundll ou Rundll32. Se você deseja evitar o uso de nomes simplificados, use um arquivo .def e exporte a função do ponto de entrada pelo nome. Consulte a documentação do produto e o seguinte artigo para obter informações adicionais sobre simplificação de nome quando estiver usando compiladores Visual C++:
    140485  (http://support.microsoft.com/kb/140485/PT-BR/ ) Exporting PASCAL-Like Symbols in 32-bit DLLs
Os parâmetros para o ponto de entrada do Rundll são da seguinte maneira:
   hwnd - identificador de janela que deveria ser usado como a janela owner para 
           quaisquer janelas que a sua DLL criar
   hinst - seu identificador de ocorrências da DLL
   lpszCmdLine - Linha de comando ASCIIZ que sua DLL deve analisar
   nCmdShow - descreve como suas janelas da DLL devem ser exibidas
				
No exemplo seguinte:
     RUNDLL.EXE SETUPX.DLL,InstallHinfSection 132 C:\WINDOWS\INF\SHELL.INF
				
O Rundll chamaria a função entrypoint InstallHinfSection() no Setupx.dll e passaria os seguintes parâmetros:
   hwnd = (identificador de janela pai)
   hinst = HINSTANCE do SETUPX.DLL
   lpszCmdLine = "132 C:\WINDOWS\INF\SHELL.INF"
   nCmdShow = (Qualquer coisa que o nCmdShow tenha passado para CreateProcess)
				
Note que é a função <entrypoint> (ou InstallHinfSection() no exemplo acima) que deve analisar sua própria linha de comando (o parâmetro lpszCmdLine acima) e usar os parâmetros individuais da maneira necessária. O Rundll.exe analisa somente até os argumentos opcionais passados para sua linha de comando. O resto da análise fica por conta da função <entrypoint>.

Observações especiais com relação a diferença entre o Windows 95 e Windows NT

No Windows NT, Windows 2000 e Windows XP o comportamento do Rundll32.exe é um pouco diferente, para acomodar as linhas de comando UNICODE.

O Windows NT tenta encontrar primeiramente o GetProcAddress para <EntryPoint>W. Se esse ponto de entrada for encontrado, então ele assume que o protótipo é:
   void CALLBACK
   EntryPointW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine,
               int nCmdShow);
				
Isso é o mesmo que o ANSI EntryPoint, com exceção de que o parâmetro lpszCmdLine é agora uma sequência UNICODE.

Se o ponto de entrada <EntryPoint>W não for encontrado, o Windows NT irá executar o GetProcAddress para <entrypoint>A e para <entrypoint>. Se ambos forem encontrados, será então considerado um ponto de entrada ANSI e é tratado da mesma maneira que o Windows 95/98/Me. No entanto, se você quiser que sua DLL seja executada em um Windows 95 com suporte para ANSI e em Windows NT/2000/XP com suporte para UNICODE, você deve exportar duas funções: EntryPointW e EntryPoint. No Windows NT/2000/Me, a função EntryPointW será chamada com a linha de comando UNICODE; no Windows 95/98/Me, a função EntryPoint será chamada com uma linha de comando ANSI.

Referências

Para obter um exemplo do uso do Rundll, consulte o seguinte artigo sobre como lançar um miniaplicativo do painel de controle no Windows 95 usando o utilitário da linha de comando do Rundll:
135068  (http://support.microsoft.com/kb/135068/PT-BR/ ) HOWTO: Start a Control Panel Applet in Windows 95, 98, or WinNT

A informação contida neste artigo aplica-se a:
  • Interface de Programação de Aplicativos do Microsoft Win32 nas seguintes plataformas
    • Microsoft Windows 95
    • Microsoft Windows 98 Standard Edition
    • Microsoft Windows Millennium Edition
    • Microsoft Windows NT 4.0
    • Microsoft Windows 2000 Standard Edition
    • Microsoft Windows XP Professional
Palavras-chave: 
kbinfo kbdll kbprogramming kbkernbase kbfaq kbusage KB164787