VB .NET - Lendo, compilando e executando um arquivo texto
Você já
precisou ler , compilar e executar um arquivo texto ?? Como assim ??? |
Deixa eu explicar melhor...
Vamos supor que você tenha um arquivo texto e esse arquivo contém um código VB .NET válido.
Vamos supor também que você tem que ler o arquivo compilar e executar o código e exibir o resultado em uma aplicação VB .NET.
Como você poderia resolver este problema ?
Isto eu vou mostrar neste artigo...
Para fazer isso vamos ter que usar a classe VBCodeProvider.
Esta classe fornece acesso às instâncias do gerador de código de Visual Basic e do compilador de código.
Vamos então ao projeto
Criando o projeto no VB .NET
Abra o Visual Basic 2010 Express Edition e crie um novo projeto do tipo (menu File-> New Project) Windows Forms com o nome CompiladorVB;
No formulário padrão vamos incluir os seguintes controles:
O leiaute do formulário deverá ter o seguinte aspecto:
Como exemplo vamos usar um código VB .NET bem simples em um arquivo texto.
Vamos incluir um arquivo texto no projeto.
Clique com o botão direito do mouse sobre o projeto e selecione Add New Item;
A seguir selecione o template Text File e informe o nome Codigo1.txt e clique em Add;
Feito isso clique duas vezes com o mouse sobre o arquivo Codigo1.txt na janela Solution Explorer para abrí-lo no Editor e digite o código conforme mostra a figura a seguir:
O código VB .NET do arquivo vai realizar uma interação usando um laço For/Next e calcular a soma retornando o valor para o controle TextBox txtResultado.txt;
Vamos agora declarar os namespaces que iremos precisar no formulário para realizar a tarefa:
Imports System.IO
Imports System.Reflection
Imports System.CodeDom
Imports System.CodeDom.Compiler
Imports Microsoft.VisualBasic
Imports System.Globalization
O namespace System.CodeDom contém classes que podem ser usadas para representar os elementos e a estrutura de um documento de código-fonte.
As classes neste namespace podem ser usadas para modelar a estrutura de um documento código-fonte que pode ser a saída como código-fonte em uma linguagem suportada usando a funcionalidade fornecida pelo namespace System.CodeDom.Compiler.
Vamos agora definir o código do evento Click do botão de comando conforme abaixo:
Private Sub btnLerExecutar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLerExecutar.Click Dim entrada As String Try ' Lê o codigo do arquivo texto entrada = My.Computer.FileSystem.ReadAllText("Codigo1.txt") Catch ex As Exception MessageBox.Show(" Erro : " + ex.Message) Return End Try ' Cria o 'codigo' literal para passar para o compilar ' ' Note que usamos o codigo <% = entrada % > onde o código lido ' é inserido no fragmento de código Dim codigo = <code> Imports System Imports System.Windows.Forms Public Class TempClass Public Sub ResultadoTexto(ByVal txtOutput As TextBox) <%= entrada %> End Sub End Class </code> Try ' Cria o compilador VB.NET Dim vbProv = New VBCodeProvider() ' Cria os parametros apra passar para o compilador Dim vbParams = New CompilerParameters() ' Inclui as referencias aso assemblies. vbParams.ReferencedAssemblies.Add("mscorlib.dll") vbParams.ReferencedAssemblies.Add("System.dll") vbParams.ReferencedAssemblies.Add("System.Windows.Forms.dll") vbParams.GenerateExecutable = False ' Garante que vamos gerar um assembly em memoria e não um arquivo fisico vbParams.GenerateInMemory = True ' Compila o código e obtem do compilador os resultados (incluindo erros, etc...) Dim resultadoCompilacao = vbProv.CompileAssemblyFromSource(vbParams, codigo.Value) ' verifica os erros do compilador If resultadoCompilacao.Errors.Count > 0 Then ' exibe cada erro For Each er In resultadoCompilacao.Errors MessageBox.Show(er.ToString()) Next Else ' Cria uma instância da classe compilada Dim obj As Object = resultadoCompilacao.CompiledAssembly.CreateInstance("TempClass") ' Um array de objetos que representa os argumentos a serem passados para o nosso método (txtOutPut) Dim args() As Object = {Me.txtOutPut} ' Executa o método passando o nome do método e os argumentos Dim t As Type = obj.GetType().InvokeMember("ResultadoTexto", BindingFlags.InvokeMethod, Nothing, obj, args) End If Catch ex As Exception MessageBox.Show("Erro : " + ex.Message) End Try End Sub |
Como exemplo estamos usando o nome do arquivo texto fixo no código ( o arquio codigo1.txt esta na basta bin\Debug);
Executando o projeto iremos obter o resultado da compilação do código vb. net do arquivo texto Codigo1.txt:
Gerando um arquivo executável físico
Agora vamos continuar usar os recursos da classe VBCodeProvider para criar um arquivo .EXE a partir de um arquivo de código CSharp;
Inclua mais um controle Button no projeto com o nome igual a btnGerarExe e a seguir inclua o seguinte código no seu evento Click:
Private Sub btnGerarExe_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGerarExe.Click CompilarExecutavel("Codigo1.cs") MessageBox.Show("Gerado com sucesso.") End Sub |
A seguir vamos definir o código da função CompilarExecutavel:
Public Shared Function CompilarExecutavel(ByVal nomeFonte As String) As Boolean Dim arquivoFonte As FileInfo = New FileInfo(nomeFonte) Dim provider As CodeDomProvider = Nothing Dim compileOk As Boolean = False ' Selecione o código baseado na extensão do arquivo If arquivoFonte.Extension.ToUpper(CultureInfo.InvariantCulture) = ".CS" Then provider = CodeDomProvider.CreateProvider("CSharp") ElseIf arquivoFonte.Extension.ToUpper(CultureInfo.InvariantCulture) = ".VB" Then provider = CodeDomProvider.CreateProvider("VisualBasic") Else MessageBox.Show("Arquivo de codigo deve ter uma extensão .cs ou .vb") End If If Not provider Is Nothing Then ' Formata o nome do arquivo executavel ' Construindo o caminho do assembly de saida no diretorio atual ' e <source>_cs.exe ou <source>_vb.exe. Dim exeName As String = String.Format("{0}\{1}.exe", _ System.Environment.CurrentDirectory, _ arquivoFonte.Name.Replace(".", "_")) Dim cp As CompilerParameters = New CompilerParameters() ' Gera um executavael ao inves de um class library. cp.GenerateExecutable = True ' Especifica o nome do arquivo assembly a gerar cp.OutputAssembly = exeName ' Salva o ssembly como um arquivo fisico cp.GenerateInMemory = False ' Trata os erros e avisos cp.TreatWarningsAsErrors = False ' Invoca a compilação do arquivo fonte Dim cr As CompilerResults = provider.CompileAssemblyFromFile(cp, nomeFonte) If cr.Errors.Count > 0 Then ' exibe as mensagens de erro MessageBox.Show("Erros Construindo " + nomeFonte + " em " + cr.PathToAssembly) Dim ce As CompilerError For Each ce In cr.Errors MessageBox.Show(" {0}", ce.ToString()) Next ce Else ' Exibe a mensagem de compilação com sucesso MessageBox.Show("Fonte " + nomeFonte + " foi construido com sucesso em " + cr.PathToAssembly) End If ' Retorna os resultadaos da compilação If cr.Errors.Count > 0 Then compileOk = False Else compileOk = True End If End If Return compileOk End Function |
Agora vamos incluir um arquivo texto com o nome Codigo1.cs no projeto, na basta bin/Debug;
No menu Project-> Add New Item e selecione Text File informando o nome Codigo1.cs;
A seguir inclua o código abaixo neste arquivo:
using System; namespace ConsoleTeste { class Program { static void Main(string[] args) { int soma = 0; for (int i = 0; i == 20; i++) { soma += i; } Console.WriteLine(" Valor Soma : " + soma); } } } |
Agora só resta testar o código.
Executando o projeto teremos a mensagem sucesso na operação e
Abrindo a pasta indicada veremos o arquivo exe gerado:
Pegue o projeto completo aqui: CompiladorVB.zip
Rom 13:1
Toda alma esteja sujeita às autoridades superiores; porque não há autoridade que não venha de Deus; e as que existem foram ordenadas por Deus.Referências: