1 pièce(s) jointe(s)
Faire interagir du code VBCodeProvider avec le code qui y fait recours
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:
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 :
Pièce jointe 623949
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