Evaluer/executer une chaine en tant que code

Description

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/

Codes Sources

A voir également

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.