Partage
  • Partager sur Facebook
  • Partager sur Twitter

C# : fractionnement d'une application

    15 juin 2011 à 20:38:07

    Bonsoir, je suis en train de développer une application en ligne de commandes qui a pour but d'exploiter la WMI d'un serveur afin d'automatiser des scripts de gestion.
    Vu la richesse de WMI un des buts principaux est de faire évoluer facilement le programme en développement des portions de code sous forme de librairies dynamiques (DLL) qui pourraient ensuite être liées à l'exécutable principal. J'ai donc programmé dans mon exécutable une portion de code qui me permet d'instancier une classe générique, aucun soucis pour le moment pour instancier des objets situé dans le même projet et le même namespace:

    WMI.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    //
    using System.Management;
    using System.Reflection;
    
    namespace EventViewerCLI
    {
        public class WMI
        {
            protected WMI()
            {
            }
    
            public static WMI getInstance()
            {
                if (instance == null)
                {
                    instance = new WMI();
                }
                return instance;
            }
    
            public bool connectToProvider(string host, string username, string passwd)
            {
                this.options = new ConnectionOptions();
                this.options.Username = username;
                this.options.Password = passwd;
                try
                {
                    this.scope = new ManagementScope("\\\\" + host + "\\root\\cimv2", this.options);
                    return true;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return false;
                }
            }
    
            public object CreateInstance(string typeName, params object[] args)
            {
                return Activator.CreateInstance(StringToType(typeName), args);
            }
    
            public Type StringToType(string typeName)
            {
                if (String.IsNullOrEmpty(typeName))
                    throw new ArgumentException("typeName is null or empty", "typeName");
    
                typeName = typeName.Replace(" ", "");
                int indexOf = typeName.IndexOf("<");
    
                if (indexOf < 0)
                {
                    foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
                        foreach (Type type in assembly.GetTypes())
                            if ((type.Name == typeName) || (type.FullName == typeName))
                                return type;
                    throw new ArgumentException(String.Format("Type '{0}' unknown !", typeName), "typeName");
                }
                else
                {
                    string typeBaseName = typeName.Substring(0, indexOf);
                    string[] argumentsGeneric = typeName.Substring(indexOf + 1).Remove(typeName.Length - indexOf - 2).Split(',');
                    List<Type> typeGenerics = new List<Type>();
                    string currentArgument = "";
                    int countLevelGeneric = 0;
                    foreach (string argument in argumentsGeneric)
                    {
                        foreach (char car in argument)
                            switch (car)
                            {
                                case '<': countLevelGeneric++; break;
                                case '>': countLevelGeneric--; break;
                            }
                        currentArgument += argument;
                        if (countLevelGeneric == 0)
                        {
                            typeGenerics.Add(StringToType(currentArgument));
                            currentArgument = "";
                        }
                    }
                    Type typeBase = StringToType(String.Format("{0}`{1}", typeBaseName, typeGenerics.Count));
                    return typeBase.MakeGenericType(typeGenerics.ToArray());
                }
            }
    
            private ConnectionOptions options;
            private ManagementScope scope;
            private static WMI instance;
        }
    }
    


    NTLogEvent.cs :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace EventViewerCLI
    {
        class NTLogEvent : WMI
        {
            NTLogEvent()
            {
            }
        }
    }
    


    Program.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace EventViewerCLI
    {
        class Program
        {
            static void Main(string[] args)
            {
                try
                {
                    string host = args[0];
                    string username = args[1];
                    string passwd = args[2];
                    string type = args[3];
    
                    WMI wmi = WMI.getInstance();
                    if (wmi.connectToProvider(host, username, passwd))
                    {
                        Console.WriteLine("Connecté à " + host);
                    }
                    else
                    {
                        Console.WriteLine("Echec de connexion à " + host);
                    }
    
                    wmi.CreateInstance(type);
                    Console.WriteLine(type.ToString());
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    Console.WriteLine(ex.StackTrace);
                }
    
                Console.WriteLine("\nappuyez sur une touche pour continuer");
                Console.ReadKey();
            }
        }
    }
    


    En passant "NTLogEvent" comme dernier argument à la ligne de commande, aucun problème, l'objet de type NTLogEvent est bien instancié.
    Mais en exportant la classe NTLogEvent dans une DLL liée au programme principal, erreur: type non trouvé lors de l’instanciation.
    J'ai mis l'assembly principal (EventViewerCLI) en référence dans l'assembly secondaire de la librairie, utilisé la directive "using", fait hérité sans problème la classe NTLogEvent exportée avec la classe WMI. J'ai essayé aussi de mettre la nouvelle classe NTLogEvent dans le même namespace (EventViewerCLI) mais sans aucun succès.
    Où pourrait être situé le problème ?
    • Partager sur Facebook
    • Partager sur Twitter
      15 juin 2011 à 22:22:30

      Tu décides d'un endroit où tu vas mettre tes DLL par rapport au programme principal.

      Dans le programme principal, tu scannes l'endroit pour trouver les fichiers DLL.

      Pour chaque DLL, tu
      Assembly al = Assembly.LoadFrom(file.FullName);
      

      Et tu parcours les types de cette assembly là, pas de ton ExecutingAssembly.

      Et tu ne touches plus à ton programme principal ;)
      • Partager sur Facebook
      • Partager sur Twitter

      C# : fractionnement d'une application

      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
      • Editeur
      • Markdown