Bonjour,

Je souhaite que l'utilisateur puisse taper un script que mon programme va exécuter
Plutôt que de tout créer de A à Z, il est assez facile d’exécuter un code VB tapé dans une zone de texte :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
    Private Function RunVbCode(ByVal CodeSource As String) As String
        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")
 
        ' 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("Namespace StringAsCode")
        sCode.AppendLine(vbTab & "Class VbCodeInString")
        sCode.AppendLine(vbTab & vbTab & "Public Function Main() as string")
        sCode.AppendLine(vbTab & vbTab & vbTab & "Try")
        sCode.AppendLine(CodeSource) 'Là on insère le code tapé par l'utilisateur dans la zone de texte
        sCode.AppendLine(vbTab & vbTab & vbTab & "Return ""OK""")
        sCode.AppendLine(vbTab & vbTab & vbTab & "Catch ex As Exception")
        sCode.AppendLine(vbTab & vbTab & vbTab & vbTab & "Return ex.Message")
        sCode.AppendLine(vbTab & vbTab & vbTab & "End Try")
        sCode.AppendLine(vbTab & vbTab & "End Function")
        sCode.AppendLine(vbTab & "End Class")
        sCode.AppendLine("End Namespace")
 
        ' 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
            Return Errors
        Else
            ' Récupération de l'assembly généré
            Dim myAssembly As System.Reflection.Assembly = cResult.CompiledAssembly
            ' Instanciation de EvalVbCode
            Dim oVbCode As Object = myAssembly.CreateInstance("StringAsCode.VbCodeInString")
            ' Récupération du type de Main()
            Dim tVbCode As Type = oVbCode.GetType()
            ' Récupération de la function Main()
            Dim functionVbCode As Reflection.MethodInfo = tVbCode.GetMethod("Main")
            ' Invocation de la function Main()
            Return CType(functionVbCode.Invoke(oVbCode, Nothing), String) 'Remarque : si la fonction Main() a des paramètres, on les passe à la place de Nothing
        End If
    End Function
 
    Private Sub ButRun_Click(sender As Object, e As EventArgs) Handles ButRun.Click
        'Debug.Print("RUN : " & ExecuteCommand(Txt.Text))
        MsgBox("RUN : " & RunVbCode(Txt.Text))
 
    End Sub
Voici le résultat :

Nom : 2022_08_17_RunCodeAsString.jpg
Affichages : 163
Taille : 26,3 Ko

Mais ce code est presque totalement "déconnecté" de mon application...
C'est comme si je lançait un .exe indépendant.
On peut juste passer des paramètres à la fonction Main() et récupérer le résultat de la fonction Main()
Paramètres et résultat dont les types et le nombre ne sont pas modifiables au moment de l'exectution.

Ce que je voudrais, c'est que le code tapé dans la zone de texte puisse utiliser des fonctions et des variables publiques de mon application
Savez-vous comment faire ?

A bientôt