Os resources de uma aplicação permitem guardar diversa informação, como ícones, imagens, etc. Essa informação é usada normalmente dentro da própria aplicação e simplifica no desenvolvimento do código, pois temos acesso a ela através do intellissense.
No entanto, e por diversos motivos, podemos querer guardar dentro do próprio executável outro ficheiro e extrai-lo para, por exemplo, criar um instalador personalizado.

Para se conseguir isto é apenas necessário criar um novo projecto, ir às propriedades do projecto (My Properties ou menu Project – «Nome da Aplicação» Properties) e no separador Resources adicionar o executável pretendido.

Depois, no Solution Explorer, selecciona-se o executável e na janela de propriedades (Properties Window) definir na Build Action como Embedded Resource.

Depois, no código, pode-se usar uma função semelhante a esta, que irá ler o executável dos resources usando Reflection para uma Stream, e que irá depois gravar para o disco usando um FileStream.
''' <summary>
''' Extrai um ficheiro executável dos resources da aplicação
'''</summary>
'''<param name="fileName">Nome completo do ficheiro a extrair</param>
'''<returns>Localização do ficheiro extraido</returns>
'''<remarks></remarks>
Private Function GetResourceFile(ByVal fileName As String) As String
Try
' Cria um nome/localização temporária para o ficheiro. Por defeito é criado um
' ficheiro com o a extensão *.tmp e por isso é necessário alterar o para *.exe
Dim tempPath As String = IO.Path.ChangeExtension(IO.Path.GetTempFileName(), ".exe")
' Verifica o nome da aplicação (Assembly)
Dim currentAssembly As Reflection.Assembly = Reflection.Assembly.GetExecutingAssembly()
' Verifica todos os objectos disponíveis nos resources
Dim arrResources As String() = currentAssembly.GetManifestResourceNames()
For Each resource As String In arrResources
' Verifica se o resource tem o nome do ficheiro a extrair
If resource.Contains(fileName) Then
' Lê o executável dos resources para uma Stream
Using resourceStream As IO.Stream = currentAssembly.GetManifestResourceStream(resource)
' Cria um novo FileStream que irá escrever o ficheiro final
Using writer As New IO.FileStream(tempPath, IO.FileMode.Create, IO.FileAccess.Write)
Const size As Int16 = 4096
Dim bytes(size) As Byte
Dim numBytes As Int32 = 0
' Escreve todos os bytes da Stream criada, usando
' o FileStream e o método Write() num ciclo Do
Do
numBytes = resourceStream.Read(bytes, 0, size)
writer.Write(bytes, 0, numBytes)
Loop While (numBytes > 0)
End Using ' writer
End Using ' resourceStream
' Retorna a localização do ficheiro
Return tempPath
End If
Next
' Caso não tenha encontrado o ficheiro pretendido
Return String.Empty
Catch ex As Exception
Return String.Empty
End Try
End Function
Finalmente, é apenas necessário chamar a função indicando o nome do executável e, neste caso, executá-lo.
If file <> String.Empty Then
' Inicia a aplicação da localização temporária. Se fosse necessário
' podia-se copiar o ficheiro final para outra localização qualquer
Process.Start(file)
Else
MessageBox.Show("Não foi possível extrair o executável")
End If
Este exemplo, bastante simples, utiliza apenas um pequeno ficheiro, mas permite ver o funcionamento geral deste processo. Foi escolhido um executável para o exemplo mas pode ser utilizado outro tipo de ficheiros.
Exemplo do artigo: DOWNLOAD
PS: Como sempre, qualquer dúvida, comentário ou correcção ao artigo é sempre bem vinda!
5 comentários:
Já precisei de fazer isto, mas na altura como não sabia, mandei o executável ao "lado" da aplicação, mas assim parece-me uma melhor maneira de a segunda aplicação "não fugir"
olá tenho um executavel de programa feito em vb5, e está descontinuado, minha quetão é seguinte, eu poderia mudar alguma coisa nele para ele poder rodar no windows xp??? é q o programa só roda em windows 98 e windows 2000, e tbm gostaria de mudar uma imagem q tem detro dele.
Sem mais fico no aguardo
Olá truta,
Nunca experimentei, mas tente clicar com o botão direito do rato no executável e seleccionar propriedades. Existe um separador para compatibilidade que permite correr o executável de uma forma compativel com algumas versões anteriores.
Pode ser que funcione ;)
Boa sorte!
teria como extrair o executavel sem executar automaticamente??
Ou seja, estou extraindo outro tipo de arquivo e ele esta abrindo o bloco de notas, só quero extrair ele, tem como?
Ótima rotina para extrair arquivos dos Resources.
Enviar um comentário