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

C# Discussion :

Appeler une WinForm c# à partir d'une application VB6


Sujet :

C#

  1. #1
    Membre expert


    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 970
    Points : 3 304
    Points
    3 304
    Par défaut Appeler une WinForm c# à partir d'une application VB6
    Bonjour,

    Je travaille actuellement sur la possibilité de faire appel à des classes ou des form provenant de .net à partir de vb6. Pour ce faire j'ai donc créé à partir d'un exemple trouvé sur le net en c# une dll qui référence "System.EnterpriseServices" et qui me permet d'avoir une classe de laquelle j'ai extrais une interface et effectuer une signature "forte" de l'assembly.

    le code de ma classe :

    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
     
     [ClassInterface(ClassInterfaceType.None)]
        public class Person : System.EnterpriseServices.ServicedComponent, com.IPerson
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public bool IsMale { get; set; }
     
            public void Persist(string FilePath)
            {
                StreamWriter oFile = new StreamWriter(FilePath);
                XmlSerializer oXmlSerializer = new XmlSerializer(typeof(Person));
                oXmlSerializer.Serialize(oFile, this);
                oFile.Flush();
                oFile.Close();
            }
     
            public void showForm()
            {
                Form1 dial = new Form1() ;
     
                if(dial.ShowDialog () == System.Windows.Forms.DialogResult.Yes ) 
                {
     
                }
            }
        }
    L'interface générée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
        public interface IPerson
        {
            string FirstName { get; set; }
            bool IsMale { get; set; }
            string LastName { get; set; }
            void Persist(string FilePath);
            void showForm();
        }
    Après compilation j'utilise la ligne suivante pour enregistrer ma dll com :

    regsvcs /appname:com D:\Dropbox\Developpements\com\com\bin\Debug\com.dll

    En Vb6 j'appelle mes fonctions (après référencement de mon objet com) comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Private Sub Command1_Click()
        Dim proxy As Person
     
        Set proxy = New Person
        proxy.FirstName = "Bejaoui"
        proxy.LastName = "Bechir"
        proxy.Persist ("d:\\myFile.xml")
     
        Call proxy.showForm
    End Sub
    Tout fonctionne bien mais je me pose quelques questions :

    - Comment debbuger ce genre de chose (seule solution que j'ai trouvé pour le moment c'est de debbuger la partie dll avec une application de test en .net. Dommage de ne pas pouvoir le faire à partir du code vd6 (et d'un autre coté tout à fait logique)

    - Comment savoir ou est le fichier regsvcs.exe et lequel utiliser. Je l'ai dans plusieurs dossiers en fonction des différents framework installé. Et comment déployer tout cela sur un autre poste ? (j'avais pensé à un fichier .bat pour enregistrer mon composant mais le répertoire regsvcs n'est pas dans la variable PATH.

    - Je suppose que le retour de paramètre de la fonction C# vers le programme vb6 se fait de manière habituel, mais comment créer des événements consommables dans l'application vb6 ?

  2. #2
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 442
    Points
    4 442
    Par défaut
    bonjour infosam76
    Comment debbuger ce genre de chose (seule solution que j'ai trouvé pour le moment c'est de debbuger la partie dll avec une application de test en .net. Dommage de ne pas pouvoir le faire à partir du code vd6 (et d'un autre coté tout à fait logique)
    Tu peux toujours par le biais des "custom .net exceptions" qui sont mappees aux "com error" , pister et localiser l'emetteur d'erreur .net en vb6 ou vba...
    citation de :
    COM and .NET Interoperability by Andrew Troelsen
    This brings up the obvious question of how a .NET object is able to return error information to the COM caller....
    COM error objects allow COM parties to send and receive rich error information using a small set of COM interfaces (ISupportErrorInfo, IcreateErrorInfo, and IErrorInfo). Under .NET of course, these interfaces are seen as legacies, and in their place you have strongly typed exception objects.
    1er exemple avec un class Car et sa Collection qui utilise le system de mappage standard des exceptions .net vers com:
    code class Car.cs Com
    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
    55
    56
    57
    58
    59
    60
    61
     
     
     
    using System;
    using System.Runtime.InteropServices;
    using System.Collections;
     
    namespace LibCarCollectionCSharp
    {
        //class Car
        [ClassInterface(ClassInterfaceType.AutoDual)]
        [Guid("38416586-61A8-4A98-9F1F-1DF25B086B06")]
        public class Car
        {
            private string make;
            private string color;
     
     
            public Car() { }
            public Car(string m, string c)
            { make = m; color = c;  }
            public void SetCarState(string m, string c)
            { make = m; color = c;}
     
            public string GetCarState()
            {
                return string.Format("Make: {0} Color: {1} ",
                make, color);
            }
        }
     
     
     
     
        //  class CarCollection implements IEnumerable.
        [ClassInterface(ClassInterfaceType.AutoDual)]
        [Guid("3DEEBE3C-90E0-4570-8829-F335FAE73F47")]
        public class CarCollection : IEnumerable
        {
            public CarCollection()
            {
                ar.Add(new Car("Ford", "Red"));
                ar.Add(new Car("BMW", "Silver"));
                ar.Add(new Car("Yugo", "Rust"));
            }
     
            // List of items.
            private ArrayList ar = new ArrayList();
     
            public IEnumerator GetEnumerator()
            { return ar.GetEnumerator(); }
            public void AddCar(Car c)
            { ar.Add(c); }
            public void RemoveCar(int index)
            { ar.RemoveAt(index); }
            public void ClearCars()
            { ar.Clear(); }
        }
     
     
    }
    code vb6 utilisateur avec un Form1:
    -si on remove le car 777 on recoit le message .Net classique "IndexOutOfBounds" du ArrayList traduit à Com en vb6 dans Err.Description.....mais quid du Class CarCollection emetteur?
    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
     
    Option Explicit
    Private coll As LibCarCollectionCSharp.CarCollection
     
    Private Sub Form_Load()
        Set coll = New CarCollection
    End Sub
     
    Private Sub btnListCars_Click()
        Dim s As String
        Dim temp As Car
        For Each temp In coll
            s = s + temp.GetCarState() & vbLf
        Next
        MsgBox s, , "The Cars"
    End Sub
     
    ' Insert a Car into the collection.
    Private Sub btnAddCar_Click()
        Dim c As New Car
        c.SetCarState txtMake.Text, txtColor.Text
        coll.AddCar c
    End Sub
     
    ' Clear out all cars.
    Private Sub btnClearCars_Click()
        coll.ClearCars
    End Sub
     
    ' Remove a specific Car.
    ' handler error vb6  on ...error goto
    ' mappage standard des exceptions .net et com
    Private Sub btnRemoveCar_Click()
    On Error GoTo OOPS
        coll.RemoveCar CInt(txtCarToRemove.Text)
        Exit Sub
    OOPS:
        MsgBox Err.Description, , Err.Source
    End Sub
    Le 2e exemple est le Class CarBis et sa collection revus avec un custom exception et localisatio du siege (emetteur)....
    code class CarBis.cs Com
    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
     
    using System;
    using System.Runtime.InteropServices;
    using System.Collections;
     
    namespace LibCarCollectionCSharp
    {
        //class CarBis
        [ClassInterface(ClassInterfaceType.AutoDual)]
        [Guid("BAF562C6-BB07-4C40-B8D1-5A5453B31EB6")]
        public class CarBis
        {
            private string make;
            private string color;
     
     
            public CarBis() { }
            public CarBis(string m, string c)
            { make = m; color = c; }
            public void SetCarState(string m, string c)
            { make = m; color = c; }
     
            public string GetCarState()
            {
                return string.Format("Make: {0} Color: {1} ",
                make, color);
            }
        }
     
        //custom exception 
        //evite la publication du custom exception dans .tlb...
        [ComVisible(false)]
        public class CustomUserException
            : System.Exception
        {
            public override string Message
            {
                get { return "Hey CustomUserException, count your cars first!"; }
            }
        }
     
     
     
        //  class CarCollection implements IEnumerable.
        [ClassInterface(ClassInterfaceType.AutoDual)]
        [Guid("E2AA02E0-0D9D-463C-8D87-2FB956BF2FC5")]
        public class CarBisCollection : IEnumerable
        {
            public CarBisCollection()
            {
                ar.Add(new CarBis("Ford", "Red"));
                ar.Add(new CarBis("BMW", "Silver"));
                ar.Add(new CarBis("Yugo", "Rust"));
            }
     
            // List of items.
            private ArrayList ar = new ArrayList();
     
            public IEnumerator GetEnumerator()
            { return ar.GetEnumerator(); }
     
            public void AddCar(CarBis c)
            { ar.Add(c); }
     
            //code de remove revu 
            public void RemoveCar(int index)
            {
                try
                {
                    ar.RemoveAt(index);
                }
                catch
                {
                    throw new CustomUserException();
                }
            }
     
            public void ClearCars()
            { ar.Clear(); }
        }
     
     
    }
    code vb6 utilisateur avec un Form2:

    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
     
    Option Explicit
    Private coll As LibCarCollectionCSharp.CarBisCollection
     
    Private Sub Form_Load()
        Set coll = New CarBisCollection
    End Sub
     
    Private Sub btnListCars_Click()
        Dim s As String
        Dim temp As CarBis
        For Each temp In coll
            s = s + temp.GetCarState() & vbLf
        Next
        MsgBox s, , "The Cars"
    End Sub
     
    ' Insert a Car into the collection.
    Private Sub btnAddCar_Click()
        Dim c As New CarBis
        c.SetCarState txtMake.Text, txtColor.Text
        coll.AddCar c
    End Sub
     
    ' Clear out all cars.
    Private Sub btnClearCars_Click()
        coll.ClearCars
    End Sub
     
    ' Remove a specific Car.
    ' HANDLER ERROR VB6  ON ...ERROR GOTO
    ' SANS CHANGEMENT
    Private Sub btnRemoveCar_Click()
    On Error GoTo OOPS
        coll.RemoveCar CInt(txtCarToRemove.Text)
        Exit Sub
    OOPS:
        MsgBox Err.Description, , Err.Source
    End Sub
    mais comment créer des événements consommables dans l'application vb6 ?
    Referes -toi à ce lien MSDN Library pour creer un class(pas un control) emetteur d'events vers un client com:
    http://www.google.fr/url?sa=t&rct=j&...LlKf4Q4LQTbQXw

    bon code...................

  3. #3
    Membre expert


    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 970
    Points : 3 304
    Points
    3 304
    Par défaut
    Merci bien je vais étudier tout cela ;-)

  4. #4
    Membre expert


    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 970
    Points : 3 304
    Points
    3 304
    Par défaut
    Voici ma solution sous forme d'article: http://ericmetz.developpez.com/csharp/vb6/interop/

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 10/10/2010, 11h46
  2. Réponses: 2
    Dernier message: 05/03/2010, 14h15
  3. Ouvrir une page web à partir d'une winform
    Par DranDane dans le forum C#
    Réponses: 4
    Dernier message: 15/08/2009, 15h03
  4. [Interop] appeler une winform C++ à partir de C#
    Par Axiome dans le forum Windows Forms
    Réponses: 1
    Dernier message: 17/01/2009, 23h57
  5. [SERVLET]Appel d'un fichier à partir d'une servlet
    Par fchafia dans le forum Servlets/JSP
    Réponses: 5
    Dernier message: 17/03/2005, 12h21

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