Comment appeler un objet COM via l'interface automation (IDispatch) en C# ? Voici un exemple en Vb (qui compile et s'exécute en vb.net) : Dim o = CreateObject("WScript.Shell") MessageBox.Show(o.CurrentDirectory) La variable o n'est pas typée et l'appel à la propriété CurrentDirectory est un appel "late binding". La question qui se pose légitimement est comment faire la même chose en C# ?
La fonction CreateObject créé un objet COM dont le ProgID est "WScript.Shell". Cette fonction renvoie un pointeur sur un objet non typé (Variant). L'appel à la property CurrentDirectory sera résolu à l'exécution et non à la compilation. Pour preuve, modifiez l'orthographe de cette property, et vous vous apercevrez que ce code continue à compiler, mais vous aurez une erreur d'exécution. Ma question est donc comment faire la même chose en C# qui est un langugage fortement typé ? Il faut savoir que le compilateur traduit l'appel à la property CurrentDirectory par un appel à la méthode Invoke de l'interface automation IDispatch. Après quelques recherches sur le net, j'ai trouvé ceci : Type typ = Type.GetTypeFromProgID("WScript.Shell"); object myShell = Activator.CreateInstance(typ); object s=typ.InvokeMember("CurrentDirectory", BindingFlags.GetProperty, null, myShell,null); MessageBox.Show(s.ToString()); Je ne sais pas si vous partagez la même opinion que moi, mais je trouve ce code moins lisible. Mon analyse m'a amené ensuite à regarder sous Reflector le code vb du premier exemple: MessageBox.Show( Conversions.ToString( NewLateBinding.LateGet( RuntimeHelpers.GetObjectValue( Interaction.CreateObject( "WScript.Shell", "")), Nothing, "CurrentDirectory", New Object( 0 - 1) {}, Nothing, Nothing, Nothing))) Le même code sous reflector en C# : MessageBox.Show( Conversions.ToString( NewLateBinding.LateGet( RuntimeHelpers.GetObjectValue( Interaction.CreateObject( "WScript.Shell", "")), null, "CurrentDirectory", new object[0], null, null, null))); En conclusion : Malgré mes recherches, je n'ai pas pû trouver de code plus simple en C# pour faire l'appel à IDispatch. Le C# est un language fortement typé, et je n'ai pas trouvé d'équivalent au type variant qui est un type "fourre-tout". J'en déduis que Microsoft a volontairement fait exprès de ne pas proposer dans le language C# la possibilité d'appeler implicitement l'interface automation, contrairement à vb.net (qui a été obligé, ne serait ce que par compatibilité à cela). J'y vois essentiellement 2 raisons : Le fait ne ne pas introduire dans le language un type "fourre-tout" comme le variant, et de conserver l'aspect "tout-objet" de ce language. Le fait aussi d'obliger les développeurs à passer par une référence aux objets COM, ce qui permet de faire des appels plus rapide et d'avoir une vérification à la compilation (à la fois de syntaxe et de type). |