VB 2005 - Revisitando .NET Assemblies


No ambiente da plataforma .NET o assembly é a unidade de distribuição para programas e livrarias de classes. Um Assembly é apenas um arquivo com a extensão .exe, para programas executáveis, ou  com a extensão .dll, para livraria de classes que residem em uma DLL - Dinamic Link Library.

Um assembly consiste de uma ou mais módulos (arquivos como um programa executável ou dll requerem). Cada módulo em um assembly possui um correspondente arquivo manisfest que fornece os metadados (informação sobre o módulo). O próprio assembly trata o manifest master que descreve cada módulo que o assembly contém bem como os atributos específicos do assembly.

No assembly, o código reside no formato de uma linguagem intermediária (IL);  antes que o código do assembly seja executado, um compilador just-in-time (JIT) no sistema de origem compila o código IL em um código nativo.

Assemblies podem ser privativos para uma aplicação ou compartilhados entre múltiplas aplicações.  Um assembly privativo de uma aplicação esta localizado no subdiretório da aplicação. Já um assembly compartilhado esta localizado no Global Assembly Cache - GAC (em geral na pasta c:\Windows\Assembly). Para colocar um assembly no GAC, você pode usar o utilitário de linha de comando GACUTIL. Um assembly compartilhado difere de um privado pois o assembly compartilhado possui uma chave pública que identifica de forma única o assembly ( um nome forte ou strong name).

Nota: Você pode compilar previamente um arquivo executável para código nativo usando o utilitário NGEN. Ao fazer isto o ele será colocado no GAC. Este processo torna a carga e execução do executável mais rápida mas a imagem nativa deixa de ser gerenciada automaticamente.

Para visualizar o conteúdo de um assembly você pode rodar o programa ILDASM (Intermediate Language Disassembler) a partir da linha de comando:

ildasm assembly.ext <enter>

Nota:  Você deve ajustar o seu ambiente para localizar o arquivo ildasm.exe ou acionar o Visual Studio Command Prompt a partir do menu Iniciar->Todos os Programas->Visual Studio 2005, para poder executar o ildasm.exe com sucesso.

Clicando em Manifest iremos obter informações sobre o assembly :

Você pode ver no conteúdo do assembly informações como :

As entradas mais comuns que você pode encontrar e um arquivo assembly são as seguintes :

Entrada
.assembly
.assembly extern
.class extern
.exeloc
.hash algorithm
.manifestres
.module
.module extern
.publickey
.publickey token
.subsystem
.ver

Para acessar o conteúdo de qualquer assembly você pode usar o namespace System.Reflection.

Nota: Para saber mais sobre Reflection leia o artigo : VB.NET 2005 -  Refatoração (Refactoring)

Vamos criar uma aplicação bem simples que permitirá a leitura de um assembly. Abra o VB 2005 Express Edition e crie um novo projeto chamado leAssembly.

Nota: Este exemplo foi adaptado de um programa encontrado no plante-source-code.

No formulário padrão inclua duas caixas de textos , uma label e um botão de comando conforme o leiaute abaixo:

A seguir defina os seguintes imports no projeto:

Imports System.Reflection
Imports
System.text

O System.Reflection será usado para obter informações do assembly e o System.text para usar o StringBuilder.

Nota: Para saber mais sobre a classe StringBuilder leia o artigo : VB .NET - StringBuilder : tratando Strings de modo mais eficiente.

 Agora no evento Click do botão de comando inclua o seguinte código:

Private Sub btnExibeAssembly_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExibeAssembly.Click


' ----- Dado um assembly, exiba os detalhes a partir do seu manifest.

Dim usaAssembly As Assembly

Dim exibirConteudo As New StringBuilder


' ----- carrega o assembly.

If (My.Computer.FileSystem.FileExists(txtCaminhoAssembly.Text) = False) Then

    MsgBox("Informe um nome de assembly válido " & " com um caminho válido.")

    Return

End If

 

Try

   usaAssembly = Reflection.Assembly.LoadFile(txtCaminhoAssembly.Text)

Catch ex As System.Exception

    MsgBox("Não foi possível acessar o assembly: " & ex.Message)

Return

 

End Try

' ----- limpa o conteúdo existente

txtAssemblyDetalhes.Clear()

' ----- Exibe o nome completo

exibirConteudo.AppendLine("Nome Completo: " & usaAssembly.FullName)

' ----- Lista todos so recursos

exibirConteudo.AppendLine()

exibirConteudo.AppendLine("Resources")

For Each umNome As String In usaAssembly.GetManifestResourceNames()

    exibirConteudo.AppendLine(" - " & umNome)

Next umNome

 

' ----- Lista todos os tipos exportados

exibirConteudo.AppendLine()

exibirConteudo.AppendLine("Exported Types")

For Each umTipo As System.Type In usaAssembly.GetExportedTypes()

   exibirConteudo.AppendLine(" - " & umTipo.Name)

Next umTipo

 

' ----- Processa cada modulo, e cada tipo no modulo

exibirConteudo.AppendLine()

exibirConteudo.AppendLine("Modules")

For Each umModulo As Reflection.Module In usaAssembly.GetLoadedModules()

  exibirConteudo.AppendLine(" - " & umModulo.Name)

 

  For Each umTipo As System.Type In umModulo.GetTypes()

    exibirConteudo.AppendLine(" Type: " & umTipo.Name)

 

        ' ----- MOstra os campos incluidos em cada tipo

     For Each umCampo As Reflection.FieldInfo In umTipo.GetFields()

           exibirConteudo.AppendLine(" Field: " & umCampo.ToString())

        Next umCampo

        ' ----- Mostra os métodos incluidos em cada tipo

            For Each umMétodo As Reflection.MethodInfo In umTipo.GetMethods()

             exibirConteudo.AppendLine(" Method: " & umMétodo.ToString())

            Next umMétodo

    Next umTipo

Next umModulo


' ----- mmostra o resultado

txtAssemblyDetalhes.Text = exibirConteudo.ToString()

End Sub

No código acima note a utilização da estrutura For each/next para percorrer uma coleção. Os valores obtidos são agregados ao StringBuilder e ao final exibido na caixa de texto.

Para obter o resultado esperado informe o nome e o caminho completo  do assembly que deseja acessar. No exemplo abaixo eu estou exibindo informações de um assembly chamado fotoDB.exe localizado na pasta d:\vbnet\fotoDB\bin:

Pegue o projeto completo aqui:  leAssembly.zip

Leia mais sobre o assunto em meu artigo  : VB.NET - O que é um Assembly ?

Até mais ver...


José Carlos Macoratti