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:
NTLogEvent.cs :
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97 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; } }
Program.cs:
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 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace EventViewerCLI { class NTLogEvent : WMI { NTLogEvent() { } } }
En passant "NTLogEvent" comme dernier argument à la ligne de commande, aucun problème, l'objet de type NTLogEvent est bien instancié.
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 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(); } } }
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