IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Faire interagir du code VBCodeProvider avec le code qui y fait recours


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 002
    Par défaut 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 : 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 : 161
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

  2. #2
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 202
    Par défaut
    le mieux est que ca soit toi qui donnes à dispo à cette méthode des objets ayant tout ce qui pourrait être nécessaire dedans
    et donc que cette méthode prennent des paramètres
    tu pourras donc l'appeler en lui passant en paramètres la ou les instances nécessaires

    dans l'autre sens c'est faisable aussi
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 202
    Par défaut
    j'oubliais, en referencedassemblies il faut aussi ajouter la ou les dll/exe qui contiennent les choses qui vont être passées
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  4. #4
    Membre chevronné Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 002
    Par défaut
    Si je comprends bien ce que tu dis, il faut que je compile le code à exécuter en incluant une DLL avec mes fonctions à moi

    Le soucis, c'est que le code compilé sera "autonome", c'est à dire qu'il n'aura pas accès aux variables ni aux fonctions du code du programme qui lance la compilation

    Ou alors, en plus d'inclure une DLL avec mes fonctions à moi, il faut que je passe tout ce qui est nécessaire en paramètres et que je récupère tous les résultats avec une valeur de retour (qui peut être un objet contenant plein de choses) - même si c'est possible ça va être très lourd, car les données en questions peuvent êtres très lourdes - genre données "3D", j'arrive à consommer toute la RAM disponible

    Y a-t-il quelque chose de plus "subtil", je pense à faire une classe qui permettrait à mon programme de communiquer avec celui compilé ?

    Bien sûr il reste la solution de refaire moi-même un langage de script mais c'est réinventer la roue

    A bientôt

  5. #5
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 202
    Par défaut
    non ce n'est pas ca que je dis
    le code que tu compiles est intégré à ton code, quand tu fais invoke c'est ton programme qui l'appelle, comme si c'était une méthode que tu avais déjà écrite dans ton projet

    donc si cette méthode prend quelque chose en paramètre elle peut y accéder
    si cette méthode appelle quelque chose de shared dans ton code elle peut y avoir accès (enfin si dans referencesassemblies tu ajoutes tes assemblies avant la compilation, comme tu ajoutes system.dll)

    et il n'y a pas de problème de mémoire, si tu passe un objet seule la référence est passée à la méthode, donc 4 ou 8 octets peu importe la taille réelle de l'objet
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  6. #6
    Membre chevronné Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 002
    Par défaut
    Merci pour ta réponse, qui montrent qu'une solution est possible

    Mais j'avoue que je n'ai pas tout compris

    Il faudrait donc :
    - que dans le code de mon application :je déclare 'shared' toutes les fonctions que je veux appeler dans le code invoké
    - et qu'en plus, j'ajoute dans 'referencesassemblies' les 'assemblies' correspondant aux fonctions 'shared'

    Je vais chercher de ce côté...

    S'il existe un exemple ou un tuto je suis preneur, car je vais y aller en mode bourrin

    A bientôt

Discussions similaires

  1. Faire interagir son téléphone portable avec son site web
    Par kmdkaci dans le forum Développement Mobile en Java
    Réponses: 3
    Dernier message: 23/07/2014, 19h43
  2. Réponses: 0
    Dernier message: 07/04/2009, 21h08
  3. Compréhention pour faire marcher un code qui génere une torche
    Par malicia_bm dans le forum ActionScript 3
    Réponses: 7
    Dernier message: 12/11/2008, 16h02
  4. Réponses: 4
    Dernier message: 28/07/2006, 13h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo