Faire un pont COM-> .NET pr un Shell Namespace Extension

Bonjour =)

Voila, je me suis lancé dans un projet qui a pour but de créer un lecteur virtuel. Je pensais au départ faire un driver, mais vu les problèmes que pose le développement d’un driver, j’ai préféré chercher un autre moyen, et j’ai découvert les Shell Namespace Extension.

Alors je pourrais tout coder en C++, mais j’ai pas vraiment envie(ni le temps) de lire toute la doc sur les objets COM… Et j’aimerais profiter des bibliotheques .NET pour l’autre coté de mon lecteur virtuel (les librairies wsdl, web services quoi .)

Et j’avoue que l’article sur msdn* est pas vraiment complet, ni ce que j’ai pu trouver chez google, ca n’explique pas tout ce dont j’ai besoin pour comprendre.

Y’a t’il quelqu’un que je pourrais embêter un peu afin d’avoir qqes précisions ?

*: (article msdn) http://msdn.microsoft.com/msdnmag/issues/0…ll/default.aspx
(article codeproject) http://www.codeproject.com/csharp/datepars…0&select=424772

Ben pose tes questions :stuck_out_tongue:

L’article de MSDN est une bonne intro, ca plus la doc sur le reste de MSDN sur les classes COM en question, t’as pas mal d’infos deja.

En ce qui me concerne, je me suis contenté de modifier la bdr pour créer un répertoire virtuel dans le poste de travail pointant de manière “discrète” vers un autre répertoire du PC.

Cela se fait simplement en rajoutant une clé au bon endroit, et j’ai regardé d’un peu plus près ce que faisait cet outil Shell Object Editor (regmon is your friend) pour piger quelles clés modifier (en l’occurence c’est un bête redirect vers une dll avec les bons paramètre.

Je ne pense pas que ce soit utile pour ton cas, mais j’avais lu les articles que tu as pointé à l’époque, donc je me suis aussi penché sur la structure des namespaces shell (et créé un ou deux projets exemples) et serais peut-être en mesure de t’aider

styx merci pr le lien, je jetterai un coup d’oeil
Glop : j’ai pas mal avancé sur mes problemes, je suis en train d’etudier une version “améliorée” *(un peu) du pont, et y’a une ligne dans les exemples que je ne comprends pas:

(dans mainclass.cs du projet 1

a quoi sert le Base() ?

*:http://www.dcooney.com/wiki/?NamespaceExtension
(source dispo)

A priori, appeller le constructeur de la classe parente qui prend un root.

merci bcp =)

Je me penche maintenant un peu plus sur le code du pont lui meme.
Je voulais juste savoir si j’avais bien compris le code:

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214FB-0000-0000-C000-000000000046")] public interface IShellExecuteHook { [PreserveSig()] int Execute(SHELLEXECUTEINFO sei); }

Ici, l’interface COM IShellExecuteHook est implémentée, et on donne le proto de la (seule) fonction Execute (ce qui implique qu’elle sera redefinie ensuite.)

Ce que je comprends mal, c’est pourquoi le GUID est présent, d’où il vient… et pourquoi il y a un type IUnknown.

[EDIT] J’ai compris pour le type.

[EDIT2]

[StructLayout(LayoutKind.Sequential)] public class SHELLEXECUTEINFO { public int cbSize; public int fMask; public int hwnd; [MarshalAs(UnmanagedType.LPWStr)] public string lpVerb; [MarshalAs(UnmanagedType.LPWStr)] public string lpFile; [MarshalAs(UnmanagedType.LPWStr)] public string lpParameters; [MarshalAs(UnmanagedType.LPWStr)] public string lpDirectory; public int nShow; public int hInstApp; public int lpIDList; public string lpClass; public int hkeyClass; public int dwHotKey; public int hIcon; public int hProcess; }

Dans ce code, j’ai pas compris comment je devais prévoir quel type est déja managed. En fait, SHELLEXECUTEINFO est une structure de la lib COM envoyée par un serveur COM, right? Donc rien ne devrait etre managed. Or, on ne marshallise qu’une partie des elements de la structure quand on redefinit ce layout… Pourquoi ?

J’ai pas super compri ta question, ca c’est une classe managed, tu as pas besoin de redefinir comment marshaller un int, c’est evident, par contre une string, il faut l’aider ca en natif, il y abeaucoup de manieres de definir une string et sa representatif memoire. Ce que tu definit ici c’est ce vers quoi va etre « casté » l’objet natif lorsqu’il arrivera dans le monde managed. L’ordre des elements, leur taille respective, et la taille totalle doivent s’aligner avec la representation memoire native de l’objet, on marshalle tous les elements de la classe. Normalement si tu utilise des objets com depuis .Net, et que ces objets/types ont leur typelib de dispo (ce qui est standard) tu as pas besoin de redefinir ces structures a la main, elles peuvent etre generees automatiquement sous forme de code gen de cs ou vb. C’est possible car COM specifie un « standard » d’export de fonction et de marshalling permettant justement une reutilisation des fonctionalitees entre logiciels. Bon apres si tu veux creer un objet COM (en implementant une interface) il faut declarer certaines structures, ce qui est plutot ce que tu fois faire ici pour faire du shell extension. M’enfin il est tard et je suis pas bien reveille donc je dis ptet des betises :stuck_out_tongue:

Je pense qu’il te faut lire quelques articles sur comment fonctionne l’interop et des articles plus generaux sur comment fonctionne COM (sans etre managed) :P. Pas de liens sous la main mais les bouquins sont nombreux.

Je vais essayer de reformuler.

mon extension est codée en .NET, et elle émule des interfaces COM pour pouvoir dialoguer avec le Shell.

SHELLEXECUTEINFO est une structure que le serveur COM envoie a la fonction Execute(SHELLEXECUTEINFO) mon interface IShellExecuteHook (qui est une interface COM simulée par un objet .NET).

Donc, si j’ai bien suivi ce que tu viens de m’expliquer, les ints ne sont pas marshalisés parce que y’a pas besoin, un int est un int, point barre.
Par contre les strings sont représentées de facon différentes dans le monde com et le monde Net. ok.
Mais prquoi alors une string de la classe n’est pas marshalisée, et les autres, oui?

Je vais essayer de relire les articles sur l’interop, mais ils sont assez obscurs.

Et encore remerci :stuck_out_tongue:

Non non, tout est marshalise, pourun int c’est juste une copie, y a besoin de rien de special. Pour une string, ca peut etre plus complique c’est tout et il faut lui dire ce qu’il doit faire pour pouvoir le mapper dans le monde managed. De COM tu recois un blob de memoire (c’est pas un serveur COM, c’est autre chose ca, c’est juste un autre objet COM) et tu dois le mapper sur une structure managee, c’est ca le marshalling.