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 :

Appel interface COM enregistrée depuis un service


Sujet :

C#

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 5
    Points : 5
    Points
    5
    Par défaut Appel interface COM enregistrée depuis un service
    Bonjour,

    J'ai créé un service Windows qui enregistre une interface COM. L'interface est correctement enregistrée et visible dans dcomcnfg.exe.

    Lorsque j'appel l'interface COM depuis VB, cela fonctionne.
    Lorsque j'appel l'interface com en C# en utilisant le bout de code ci-dessous, cela fonctionne.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Type type = Type.GetTypeFromProgID("bkopapi.CBkopapiServerClass");
    Object obj = Activator.CreateInstance(type);
    object[] funcargs = new object[1];
    funcargs[0] = "test";
    String Ret = (String)type.InvokeMember("GetDateTime",
                     System.Reflection.BindingFlags.InvokeMethod,
                     null,
                     obj,
                     funcargs);
    Par contre, lorsque j'utilise le code suivant, cela ne fonctionne pas. J'ai une erreur lorsque je cast l'objet en interface. L'erreur indique la la fonction QueryInterface à retournée l'erreur E_NOINTERFACE. Il me semble pourtant que c'est lma meilleure méthode pour appeler un objet COM en c#.

    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
        [ComVisible(true),
         ComImport,
         Guid("F649AE66-53F2-4080-B942-3693EE0ADF71"),
         InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        interface IBkopapiServer
        {
            string GetDateTime(string prefix);
            string listall(string user, string search, ref string response);
        }
        [ComImport, Guid("FF637577-6057-4807-95B3-4A6C69575656")]
        public class CBkopapiServer
        {
        }
     
        class Program
        {
            static void Main(string[] args)
            {
                // Test non OK
                CBkopapiServer c = new CBkopapiServer();
                IBkopapiServer _apiserver = (IBkopapiServer)c; // Erreur E_NOINTERFACE ici
                String Result = _apiserver.GetDateTime("Test");
            }
        }
    Quelqu'un peut-il m'aider ?

    Merci

  2. #2
    Membre éclairé
    Profil pro
    Ingénieur sécurité
    Inscrit en
    Février 2007
    Messages
    574
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Etats-Unis

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

    Informations forums :
    Inscription : Février 2007
    Messages : 574
    Points : 751
    Points
    751
    Par défaut
    Ta classe CBkopapiServer implémente pas ton interface...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public class CBkopapiServer
    plutôt ça, si tu veux en suite caster ta classe en type interface?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public class CBkopapiServer : IBkopapiServer
    ensuite tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    IBkopapiServer test = new CBkopapiServer();
    Dans tous les cas ta classe implantant IBkopapiServer (ici CBkopapiServer) doit définir les méthodes contenues dans IBkopapiServer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    string GetDateTime(string prefix);
    string listall(string user, string search, ref string response);
    Je sais pas si je suis clair?

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 5
    Points : 5
    Points
    5
    Par défaut
    Merci mais,

    D'après le tutorial de Microsoft trouvé à l'adresse http://msdn2.microsoft.com/en-us/lib...12(VS.71).aspx
    lorsque l'on utilise un objet COM il suffit de déclarer l'interface avec les méthodes de la classe à utiliser, dans l'ordre de définition de la classe. Ensuite, dotnet fait tout le travail pour nous.
    La classe ne doit contenir aucune méthode.

    D'ailleurs, cela fonctionne pour la création de la classe. Avec cette définition, je passe bien par ma class factory du server Com dans mon service lorsque je fait un new de la classe.
    L'erreur vient du fait que la fonction QueryInterface ne trouve pas l'interface demandée. Comme dotnet fait tout pour nous, je ne comprend pas où se trouve cette fonction QueryInterface. Cette fonction doit être appelée par dotnet au moment du cast.

    Est-ce que mon explication précise mon problème ?

  4. #4
    Membre éclairé
    Profil pro
    Ingénieur sécurité
    Inscrit en
    Février 2007
    Messages
    574
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Etats-Unis

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

    Informations forums :
    Inscription : Février 2007
    Messages : 574
    Points : 751
    Points
    751
    Par défaut
    Excuse-moi, j'ai répondu à côté. J'ai regardé ton lien, ce que tu fais à l'air de coller à la lettre...
    Mais regarde par peut-être... et
    Ca à l'air d'être un problème de thread safe.
    Essai de rajouter [STAThread] au dessus de ton main.
    J'espère que je me plante pas encore. Bonne chance.

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 5
    Points : 5
    Points
    5
    Par défaut
    J'ai regardé les pages référencées avec attention.

    J'ai testé avec les différents modèles MTAThread et STAThread sans succès. En mode STAThread, la création de la classe ne fonctionne pas. La classe factory n'est pas appelée.

    L'un des liens fait référence à un bug (vieux bug sur NT, donc j'espère corrigé) sur le nombre d'interface dans le registre. En regardant de plus près je ne trouve pas de référence sur mon interface dans le registre. Je ne trouve pas non plus de référence dans MSDN indiquant qu'il faut ajouter cette entrée dans le registre.

    Faut-il le faire ?

  6. #6
    Membre éclairé
    Profil pro
    Ingénieur sécurité
    Inscrit en
    Février 2007
    Messages
    574
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Etats-Unis

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

    Informations forums :
    Inscription : Février 2007
    Messages : 574
    Points : 751
    Points
    751
    Par défaut
    ça à plus l'air d'être un problème de thread...
    peut-être ça peu t'aider?
    Je peut plus trop t'aider. Si tu trouve, post ta réponse ici, ce serait sympa.
    Bonne chance.

Discussions similaires

  1. Appel d'une servlet depuis un Web Service JAX-WS
    Par gabybag dans le forum Services Web
    Réponses: 0
    Dernier message: 10/10/2011, 15h37
  2. appelé objet COM depuis c++
    Par wislam2007 dans le forum Langage
    Réponses: 1
    Dernier message: 03/08/2009, 17h19
  3. [AC-2000] Appeler requête enregistrée depuis vba
    Par Flo90 dans le forum VBA Access
    Réponses: 2
    Dernier message: 22/04/2009, 14h16
  4. Réponses: 3
    Dernier message: 21/11/2006, 22h05
  5. Réponses: 1
    Dernier message: 24/07/2006, 14h15

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