Exécuter du code vb.net à partir d'un programme en cours d'exécution

Soyez le premier à donner votre avis sur cette source.

Snippet vu 11 072 fois - Téléchargée 21 fois

Contenu du snippet

Ce programme à pour but de montrer comment on peut exécuter du code vb.net (ou c#) pendant l'exécution.

Ce n'est qu'une façon de procéder parmi d'autres.

Pour pouvoir tester ce code il faut :
  • Créer un formulaire sur lequel on place 2 objets :

- un bouton appelé cmdExec
- un RichTextBox appelé RTB
  • Créer une class appelée DynamicCode


Si vous souhaitez ajouter une référence à votre code qui est en cours d'exécution il faut l'ajouter au paramètre CP comme suit :
CP.ReferencedAssemblies.Add(System.Reflection.Assembly.GetExecutingAssembly.Location)
Dans ce cas, il ne faut pas oublié d'ajouter les références liées à votre projet. Exemple :
CP.ReferencedAssemblies.Add("System.Windows.Forms.dll")

Pour intégrer une gestion d'erreur il faut stocker les messages car il peut y en avoir plusieur à suivre dans la procedure de compilation. On pourrait la retravailler comme suit :
Dim CR As CodeDom.Compiler.CompilerResults = CDP.CompileAssemblyFromSource(CP, sCodeSource)
Try
Return CR.CompiledAssembly
Catch ex As Exception
For i As Integer = 0 To CR.Errors.Count - 1
'procedure contenant un RichTextBox sur lequel on ajoute les messages d'erreur
addMessage(CR.Errors.Item(i).ErrorText)
Next
Return Nothing
End Try

Source / Exemple :


Public Class DynamicCode
    ''' <summary>
    ''' Compilation de code vb.net
    ''' </summary>
    ''' <param name="sCodeSource">code source</param>
    ''' <returns>assembly</returns>
    ''' <remarks>nécessite le chargement de l'assembly pour l'exécution</remarks>
    Public Shared Function compile(ByVal sCodeSource As String) As System.Reflection.Assembly
        Dim CP As CodeDom.Compiler.CompilerParameters = New CodeDom.Compiler.CompilerParameters()
        CP.ReferencedAssemblies.Add("System.dll")
        CP.GenerateExecutable = False
        Return compile(CP, sCodeSource)
    End Function

    ''' <summary>
    ''' Compilation de code vb.net
    ''' </summary>
    ''' <param name="CP">imports, génération d'exe ...etc</param>
    ''' <param name="sCodeSource">code source</param>
    ''' <returns>assembly</returns>
    ''' <remarks>nécessite le chargement de l'assembly pour l'exécution</remarks>
    Public Shared Function compile(ByVal CP As CodeDom.Compiler.CompilerParameters, ByVal sCodeSource As String) As System.Reflection.Assembly
        Dim CDP As CodeDom.Compiler.CodeDomProvider = New VBCodeProvider()
        Return compile(CDP, CP, sCodeSource)
    End Function

    ''' <summary>
    ''' compilation de code
    ''' </summary>
    ''' <param name="CDP">vb.net, c# ou autre</param>
    ''' <param name="CP">imports, génération d'exe ...etc</param>
    ''' <param name="sCodeSource">code source</param>
    ''' <returns>assembly</returns>
    ''' <remarks>nécessite le chargement de l'assembly pour l'exécution</remarks>
    Public Shared Function compile(ByVal CDP As CodeDom.Compiler.CodeDomProvider, ByVal CP As CodeDom.Compiler.CompilerParameters, _
            ByVal sCodeSource As String) As System.Reflection.Assembly
        Dim CR As CodeDom.Compiler.CompilerResults = CDP.CompileAssemblyFromSource(CP, sCodeSource)
        Return CR.CompiledAssembly
    End Function
End Class

'----------------------------------------
'Code à mettre dans le formulaire
Private Sub cmdExec_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdExec.Click
            execCode()
        End Sub

        Private Sub execCode()
            Me.cmdExec.Enabled = False
            Dim TH As New Threading.Thread(AddressOf execCodeTH)
            TH.Start()
        End Sub

        Private Sub execCodeTH()
            Try
                Threading.Thread.Sleep(1)
                Dim S As String = "Imports System" & vbCrLf & "Class TestClass" & vbCrLf & "Public Shared Sub testSub()" & vbCrLf
                S &= RTB.Text
                S &= vbCrLf & "End Sub" & vbCrLf & "End Class"
                Dim A As System.Reflection.Assembly = DynamicCode.compile(S)
                If Not A Is Nothing Then
                    Dim T As Type = A.GetType("TestClass")
                    Dim M As System.Reflection.MethodInfo = T.GetMethod("testSub")
                    M.Invoke(Nothing, Nothing)
                End If
            Catch ex As Exception
                'Gestion d'erreur à faire en fonction de votre programme
                msgbox(ex.Message)
            End Try
            Me.cmdExec.Enabled = True
        End Sub
'----------------------------------------

Conclusion :


Le choix est ici porté sur l'exécution directe du code
Mais on peut très bien choisir de tout rendre paramétrable (Namespace, Class, Sub etc...)

Pour tester on peut exécuter la commande suivante (en ayant un fichier C:\A.txt) :
System.IO.File.Copy("C:\A.txt","C:\B.txt")

A voir également

Ajouter un commentaire Commentaires
Kristof10 Messages postés 15 Date d'inscription jeudi 21 août 2003 Statut Membre Dernière intervention 4 mars 2011
4 mars 2011 à 15:15
Bonjour,

j'essaye de faire fonctionner cette source, mais je n'y arrive pas. J'ai les même problème ci-dessus.

Quelqu'un a t'il un lien vers une source à télécharger dans le même esprit ?

Est-il possible de l'avoir au format zip ?

Merci de votre aide.

Kristof
cs_eldim Messages postés 956 Date d'inscription lundi 30 mai 2005 Statut Membre Dernière intervention 21 août 2014 1
23 sept. 2010 à 14:00
oui mais j'ai pas le temps de chercher la syntaxe désolé
je l'ai déja vu mais je ne la connais pas par coeur
magicabdou Messages postés 8 Date d'inscription lundi 9 mars 2009 Statut Membre Dernière intervention 23 septembre 2010
23 sept. 2010 à 12:07
Bonjour, Bon travail :)

est ce que c est possible d'exporter la result sous format d'un fichier Executable (.exe) ?
cs_eldim Messages postés 956 Date d'inscription lundi 30 mai 2005 Statut Membre Dernière intervention 21 août 2014 1
16 févr. 2009 à 08:01
je viens de relire ta question... logiquement ce n'est pas comme ça qu'il faut utiliser le source... :
tu dois créer ton formulaire dynamiquement dans le RTB et créer le label associé. Pas mettre ton label sur le même form que la où tu déclare ton code... C'est comme si tu essayais de créer un formulaire dans l'éditeur VB et que tu ne comprenais pas pourquoi il ne marchait pas pendant que tu édite le code... Bref :
dim FRM as new system.windows.forms.form
dim L1 as new system.windows.forms.label
frm.controls.add L1
L1.Text = "toi"
haitham101 Messages postés 6 Date d'inscription jeudi 14 décembre 2000 Statut Membre Dernière intervention 15 février 2009
15 févr. 2009 à 10:10
SLT eldim
je suis toujours coincé tu peut m'aider
merci.........................

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.