积极答复者
Se Puede Cargar Codigo de un Texto | VB.NET

问题
-
>Hello, World!_
Tengo la Siguiente Pregunta:
¿Puedo Agregar una Linea de Codigo desde un Archivo de Texto?
Me Explico:
En un Archivo de Texto se encuentre el siguiente Codigo
If TextBox1.Text = "ST.Debug=AppName" Then RichTextBox1.AppendText(vbCrLf & "[ST]New Command: " & TextBox1.Text) AppName.Show() TextBox1.Clear() End If
y que el Programa de VB.NET ejecute este Codigo del Archivo
¿Se Puede?
y si es asi ¿Hay Alguna Forma?
y si no ¿Que es lo mas Parecido?
- 已编辑 Urfenox 2017年4月12日 1:04 Faltaban Datos del Titulo
2017年4月12日 1:01
答案
-
Después de meses de búsqueda, resulto ser MUY FÁCIL. Tanto que me da risa la respuesta de Alberto jksjks.
Primero los imports
Imports System.CodeDom Imports System.Reflection
Luego, un Sub o Function con el siguiente codigo:
Dim myProcessor As Assembly Dim mySupplier As New VBCodeProvider Dim myCompilador = mySupplier.CreateCompiler Dim myParam As New CodeDom.Compiler.CompilerParameters myParam.GenerateExecutable = False 'No quiero ejecutable myParam.GenerateInMemory = True 'Lo quiero en memoria 'myParam.OutputAssembly = "" 'Por si quiero generar un simbolo 'myParam.ReferencedAssemblies.Add("") 'No quiero referencias a a DLLs o librerias. Dim contenidoProcesador As String = My.Computer.FileSystem.ReadAllText("C:\archivoConCodigoEnTextoPlano.txt") Dim myResult As Compiler.CompilerResults = myCompilador.CompileAssemblyFromSource(myParam, contenidoProcesador) myProcessor = myResult.CompiledAssembly 'Creo la instancia de la clase Dim procesadorComandos = myProcessor.CreateInstance("nombreClase") 'Uso la clase y llamo al metodo, luego devuelvo lo devuelto Dim valorDevuelto = procesadorComandos.FuncionGenerica("parametro") If valorDevuelto <> Nothing Then Return valorDevuelto Else Return "La funcion de la clase no ha devuelto ningun valor." End If
Y la clase en cuestión tiene un aspecto:
Public Class nombreClase Public Sub New() End Sub Public Function FuncionGenerica(ByVal parametro As String) As String If parametro = "" Then 'Do something Return "" ElseIf parametro = "" Then 'Do something else Return "" Else Return "No procesado." End If End Function End Class
Y así de simple.
El código hace un compilado que ejecuta en memoria. Un código que toma desde un archivo de texto plano. Luego crea una instancia de la clase y llama a una función dentro de esta. Al final, una variable guarda el retorno de la función. Y ya está. (Muy tarde)
--- Cristopher Cáceres | Hola! | Worcome Studios ---
- 已标记为答案 Urfenox 2022年6月1日 17:40
2022年6月1日 17:40
全部回复
-
Sí, se puede pero no es muy sencillo. Puedes invocar al compilador de VB.NET, que se expone como clase dentro del Framework, y entre los varios parámetros que se le pueden pasar hay uno que se llama CompileInMemory, que te devuelve un objeto con el código que ha compilado. Ese objeto después puedes invocarlo por reflexión. El efecto neto es que lo que había en el archivo se ejecuta en memoria después de tomar los pasos anteriores.
Se complicará un poco porque es necesario que lo que tomas del archivo sea algo que compile correctamente, por lo que no pueden ser unas líneas de código "sueltas", sino que hay que meterlas dentro de un método dentro de una clase. Esto puedes hacerlo concatenando esas "piezas" alrededor de las líneas leídas del fichero. Y si en el código cargado necesitas acceder a algo externo, como por ejemplo el textBox1 que hay en el fragmento que pegaste, entonces esos datos hay que pasárselo como argumento al encapsulado que añadiste, en el momento de invocarlo por reflexión.
Si eso lo tienes que hacer repetidamente cargando sobre la marcha muchos fragmentos de muchos archivos que van cambiando, se presenta otro problema adicional: cada vez que compilas uno y lo cargas en memoria, se genera un nuevo ensamblado, que nunca se descarga de la memoria salvo que se descargue el AppDomain que lo contiene. Por eso, si vas a cargar muchos, conviene que los cargues en un AppDomain separado, para poderlo descargar. Esto complica la llamada por Reflexión, que tiene que hacer un salto entre AppDomains y requiere encapsular los argumentos en una clase que admita al Marshalling entre AppDomains.
Todas estas cosas funcionan muy bien una vez que las tienes escritas, pero como ves son varios temas de una complejidad considerable y que tendrías que estudiar, no es un tema trivial que se resuelva con dos líneas de código.
2017年4月12日 5:52 -
Después de meses de búsqueda, resulto ser MUY FÁCIL. Tanto que me da risa la respuesta de Alberto jksjks.
Primero los imports
Imports System.CodeDom Imports System.Reflection
Luego, un Sub o Function con el siguiente codigo:
Dim myProcessor As Assembly Dim mySupplier As New VBCodeProvider Dim myCompilador = mySupplier.CreateCompiler Dim myParam As New CodeDom.Compiler.CompilerParameters myParam.GenerateExecutable = False 'No quiero ejecutable myParam.GenerateInMemory = True 'Lo quiero en memoria 'myParam.OutputAssembly = "" 'Por si quiero generar un simbolo 'myParam.ReferencedAssemblies.Add("") 'No quiero referencias a a DLLs o librerias. Dim contenidoProcesador As String = My.Computer.FileSystem.ReadAllText("C:\archivoConCodigoEnTextoPlano.txt") Dim myResult As Compiler.CompilerResults = myCompilador.CompileAssemblyFromSource(myParam, contenidoProcesador) myProcessor = myResult.CompiledAssembly 'Creo la instancia de la clase Dim procesadorComandos = myProcessor.CreateInstance("nombreClase") 'Uso la clase y llamo al metodo, luego devuelvo lo devuelto Dim valorDevuelto = procesadorComandos.FuncionGenerica("parametro") If valorDevuelto <> Nothing Then Return valorDevuelto Else Return "La funcion de la clase no ha devuelto ningun valor." End If
Y la clase en cuestión tiene un aspecto:
Public Class nombreClase Public Sub New() End Sub Public Function FuncionGenerica(ByVal parametro As String) As String If parametro = "" Then 'Do something Return "" ElseIf parametro = "" Then 'Do something else Return "" Else Return "No procesado." End If End Function End Class
Y así de simple.
El código hace un compilado que ejecuta en memoria. Un código que toma desde un archivo de texto plano. Luego crea una instancia de la clase y llama a una función dentro de esta. Al final, una variable guarda el retorno de la función. Y ya está. (Muy tarde)
--- Cristopher Cáceres | Hola! | Worcome Studios ---
- 已标记为答案 Urfenox 2022年6月1日 17:40
2022年6月1日 17:40