Você está na página 1de 5

Como embutir uma DLL no executvel evitando sua distribuio separadamente por Adenilton Rodrigues Basicamente a tcnica consiste

em transformar o arquivo DLL (pode ser qualquer arquivo: imagem, som, etc) em um arquivo de recursos e adicion-lo ao pacote do executvel (extenso .res). Quando houver a necessidade do seu uso, ele pode ser extrado e salvo temporariamente (ou definitivamente). TRANSFORMANDO O ARQUIVO DLL em RES Neste pequeno roteiro irei demonstrar como incorporar o arquivo MIDAS.DLL ao seu arquivo EXE e sua extrao automtica quando o programa for executado. Primeiro precisamos transformar o arquivo MIDAS.DLL em um arquivo de recursos, o qual chamaremos de MIDAS.RES.

1.

V ao prompt do DOS e crie um arquivo qualquer no formato texto com a extenso .rc (para manter uma coerncia, chamarei-o de MIDAS.RC). Esse arquivo dever possuir uma linha para cada arquivo a ser transformado em recurso. Nesse exemplo conter apenas uma linha, pois trabalharei apenas com o MIDAS.DLL. Sua estrutura dever ser: MIDASDLL DLLFILE C:\WINDOWS\SYSTEM\MIDAS.DLL O primeiro parmetro o label a ser atribuido ao arquivo (Ser utilizado pelo delphi pra achar o recurso). O segundo apenas um identificador do tipo de arquivo. O terceiro o path onde o compilador de recursos ir buscar o arquivo para transformar em .RES.

2.

Execute o compilador de recursos que acompanha o delphi: Est na pasta BIN e se chama BRCC32.EXE. Este um programa do DOS, portanto se voc no estiver na pasta BIN do delphi, tenha a certeza que sua vriavel PATH esteja apontando para l. ( Se quiser configurar na mo digite no DOS: SET PATH=%PATH%;diretorio_delphi\bin) Para transformar o arquivo .RC em .RES digite: BRCC32 MIDAS.RC D um comando DIR e verifique a existncia do arquivo MIDAS.RES (Se no encontrar, revise os procedimentos).

CRIANDO UM PROGRAMA QUE LEVA A DLL EMBUTIDA Veja agora como criar um programa que embute a DLL no seu executvel:

1. 2.

Crie um projeto com um form e coloque um TButton. No cdigo fonte da Unit voc encontrar o seguinte include: {$R *.DFM} Logo abaixo dele inclua o seu arquivo de recurso da seguinte maneira: {$R MIDAS.RES} Ficar assim: {$R *.DFM} {$R MIDAS.RES} Obs: Voc pode colocar sua include em qualquer parte do programa (o linker o achar), contudo o ideal nesta seo para facilitar a localizao visual dos recursos utilizados pela sua aplicao. Nesse momento se voc compilar seu projeto, o arquivo MIDAS.DLL j estar incorporado ao executvel da aplicao.

Veja como extrair a DLL em tempo de cdigo. Uma veja incorporado ao executvel um recurso, ser necessrio extrai-lo antes do seu uso (Depois mostrarei uma tcnica de autoextrao). O Delphi possui uma Classe que permite a manipulao de recursos, a TResourceStream. A rotina abaixo extrai o arquivo MIDAS.DLL e salva no diretorio da aplicao: Procedure SaveMidas; Var PathToSave : String; Res : TResourceStream; Begin PathToSave := ExtractFilePath(Application.ExeName)+'\MIDAS.DLL'; If not FileExists(PathToSave) Then Begin Res := TResourceStream.Create(Hinstance, 'MIDASDLL', 'DLLFILE'); Try Res.SavetoFile(PathToSave); Finally Res.Free; End; End; End; Para execut-la, no OnClick do boto escreva: SaveMidas; Veja o cdigo completo: uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations }

public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} {$R MIDAS.RES} Procedure SaveMIDASDLL; Var PathToSave:String; Res : TResourceStream; Begin PathToSave := ExtractFilePath(Application.ExeName)+'\MIDAS.DLL'; If not FileExists(PathToSave) Then Begin Res := TResourceStream.Create(Hinstance, 'MIDASDLL', 'DLLFILE'); Try Res.SavetoFile(PathToSave); Finally Res.Free; End; End; End; procedure TForm1.Button1Click(Sender: TObject); begin SaveMidasDLL; end; end. Se voc quiser salvar no diretrio System do Windows, a procedure abaixo facilitar sua vida: Function ExtractSystemDir : String; Var Buffer : Array[0..255] of Char; Begin GetSystemDirectory(Buffer,144); Result := StrPas(Buffer); End; end. AUTO-EXTRAINDO A DLL Uma tcnica interessante a auto-extrao da DLL no momento da inicializao de sua aplicao sem a necessidade da chamada explicita procedure SaveMidasDLL. Vamos utilizar o recurso de auto-inicializao das Units implementado pelo Delphi. Para quem no conhece, o Delphi quando carrega uma Unit ele executa automaticamente o cdigo dentro do bloco INITIALIZATION antes mesmo da aplicao ser totalmente inicializada, um excelente gancho para se colocar rotinas de inicializao. O mais espertos j perceberam que o Bloco FINALIZATION faz o mesmo efeito, porm ao finalizar a execuo da aplicao.

Para ver a auto-extrao, acrescente o bloco de cdigo abaixo ao final da Unit do Form: Initialization Begin ShowMessage('Gerando o arquivo MIDAS.DLL'); SaveMidasDLL; End; End. Veja que agora, quando o form criado (e a unit acionada), a procedure SaveMidasDLL executada automaticamente. PROBLEMAS Dependendo da forma como sua aplicao foi criada voc pode se deparar com um problema: Uma parte do cdigo pode estar chamando um arquivo que ainda no foi extraido (situao muito comum com aplicaes que chamam DLL's na sua inicializao). Uma boa tcnica acrescentar o cdigo de extrao no arquivo .DPR, assim ele ser acionado antes de qualquer outra rotina da aplicao. Eu particularmente prefiro outra tcnica: Colocar as rotinas de auto-extrao em uma unit exclusiva e cham-la primeiramente na minha aplicao, o cdigo fica mais limpo, e todas as vezes que voc precisar usar o recurso basta apenas acrescent-la sua clusula Uses. Veja o cdigo pronto: unit AutoMidas; interface Uses Windows, Classes, Sysutils, Forms,Dialogs; Function ExtractSystemDir : String; Procedure SaveMIDASDLL; implementation {$R MIDAS.RES} Procedure SaveMIDASDLL; Var PathToSave:String; Res : TResourceStream; Begin PathToSave := ExtractFilePath(Application.ExeName)+'\MIDAS.DLL'; If not FileExists(PathToSave) Then Begin Res := TResourceStream.Create(Hinstance, 'MIDASDLL', 'DLLFILE'); Try Res.SavetoFile(PathToSave); Finally Res.Free; End;

End; End; Function ExtractSystemDir : String; Var Buffer : Array[0..255] of Char; Begin GetSystemDirectory(Buffer,144); Result := StrPas(Buffer); End; Initialization Begin ShowMessage('Gerando o arquivo MIDAS.DLL'); SaveMidasDLL; End; end. Importante: Para evitar o problema mencionado acima, onde a aplicao chama o arquivo antes de sua extrao, coloque sempre a sua Unit na primeira posio da lista da clusula Uses, assim ela ser a primeira a ser executada. PS: uso da MIDAS.DLL foi apenas para fins didticos, o delphi permite o uso das units MidasLib+Crtl para distribuio desse arquivo de forma mais simples. Adenilton Rodrigues tem formao superior em Anlise de Sistemas. Consultor em Tecnologias de Desenvolvimento Internet e atualmente responde pelo Departamento de Tecnologia da SOL - Servios Online (www.solnet.com.br), onde implanta solues em Delphi, Java e .NET.