Cette source vous permettra d'exécuter une chaîne contenant du code source en VB.Net.
J'utilise CodeDom et la Reflection pour générer un assembly en mémoire, à la demande, et récupérer le résultat du code exécuté.
Comme exemple, j'ai monté une mini mini application de dessin, permettant de générer un menu Transformation avec des fichiers textes contenant le nom de la commande puis le code.
Source / Exemple :
''' <summary>
''' Cette fonction permet l'exécution d'une commande passée sous forme de chaîne.
''' </summary>
''' <param name="cmd">La commande à exécuter sur l'image.</param>
''' <param name="img">L'image d'origne.</param>
''' <returns>L'image transformée selon le code de "cmd".</returns>
''' <remarks></remarks>
Private Function ExecuteCommand(ByVal cmd As String, ByVal img As Image) As Image
Dim vbCodeProv As VBCodeProvider = New VBCodeProvider
Dim cParam As CodeDom.Compiler.CompilerParameters = New CodeDom.Compiler.CompilerParameters
' Ajout des références
cParam.ReferencedAssemblies.Add("System.dll")
cParam.ReferencedAssemblies.Add("System.Drawing.dll")
' Options du compilateur
cParam.CompilerOptions = "/t:library" 'L'assembly est une bibliothèque de classe,
cParam.GenerateInMemory = True 'générée uniquement en mémoire.
' Génération du code source
Dim sCode As System.Text.StringBuilder = New System.Text.StringBuilder("")
sCode.AppendLine("Imports System")
sCode.AppendLine("Imports System.Drawing")
sCode.AppendLine("Imports System.Diagnostics")
sCode.AppendLine()
sCode.AppendLine("Namespace Divad")
sCode.AppendLine(vbTab & "Class EvalVbCode")
sCode.AppendLine(vbTab & vbTab & "Public Function EvalTransformation(ByVal img As Image) as Image")
sCode.AppendLine(vbTab & vbTab & vbTab & "Try")
sCode.AppendLine()
sCode.AppendLine(cmd)
sCode.AppendLine()
sCode.AppendLine(vbTab & vbTab & vbTab & "Catch ex As Exception")
' En cas d'erreur : console de debug ET renvoie Nothing
sCode.AppendLine(vbTab & vbTab & vbTab & vbTab & "Debug.WriteLine(ex.Message)")
sCode.AppendLine(vbTab & vbTab & vbTab & vbTab & "Return Nothing")
sCode.AppendLine(vbTab & vbTab & vbTab & "End Try")
sCode.AppendLine(vbTab & vbTab & "End Function")
sCode.AppendLine(vbTab & "End Class")
sCode.AppendLine("End Namespace")
' Code de la classe dans la console de debug
Debug.WriteLine(sCode.ToString())
' Résultat de la compilation
Dim cResult As CodeDom.Compiler.CompilerResults = vbCodeProv.CompileAssemblyFromSource(cParam, sCode.ToString())
If cResult.Errors.Count > 0 Then
Dim Errors As String = "Erreur(s) : "
For Each ce As CodeDom.Compiler.CompilerError In cResult.Errors
Errors &= vbCrLf & ce.ErrorText
Next ce
MsgBox(Errors)
Return Nothing
Else
' Récupération de l'assembly généré
Dim myAssembly As System.Reflection.Assembly = cResult.CompiledAssembly
' Instanciation de EvalVbCode
Dim oEvalVbCode As Object = myAssembly.CreateInstance("Divad.EvalVbCode")
' Récupération du type de EvalVbCode
Dim tEvalVbCode As Type = oEvalVbCode.GetType()
' Récupération de la méthode EvalTransformation
Dim methodEvalTrans As Reflection.MethodInfo = tEvalVbCode.GetMethod("EvalTransformation")
' Invocation de la méthode EvalTransformation
Dim myImage As Image = methodEvalTrans.Invoke(oEvalVbCode, New Object() {img})
Return myImage
End If
End Function
Conclusion :
Cette technique, au final assez simple à mettre en place, peut être utilisée pour beacoup de choses... Je vous laisse faire courir votre imagination !
Vous trouverez une explication plus détaillée à cette adresse :
http://www.laumaille.net/2007/12/19/evaluationexecution-dune-chaine/
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.