c # - Call windows explorer shell extension

Indlæg af Hanne Mølgaard Plasc

Problem



Er der nogen måde at kalde en DLL, der er en shell-udvidelse programmatisk? Vi bruger en software, der registrerer en shell-udvidelse på Windows Explorer, og jeg skal ringe til en af ​​de tilgængelige emner på dens kontekstmenu. Jeg har ikke kildekoden til software, som jeg vil ringe til.


EDIT


Denne kontekstmenu vises kun, når jeg vælger en PDF-fil på Windows Explorer. Så jeg skal kalde det forbi en dll-fil.


EDIT


Registreringsoplysninger:


[[HKEY\_CLASSES\_ROOT \ CLSID {2DC8E5F2-C89C-4730-82C9-19120DEE5B0A}]]
@='PDFTransformer3.PDFTContextMenu.1'


[[HKEY\_CLASSES\_ROOT \ CLSID {2DC8E5F2-C89C-4730-82C9-19120DEE5B0A} \ InprocServer32]]
@='C: \ Programmer \ ABBYY PDF Transformer 3.0 \ PDFTContextMenu.dll'
'ThreadingModel'='Apartment'


[[HKEY\_CLASSES\_ROOT \ CLSID {2DC8E5F2-C89C-4730-82C9-19120DEE5B0A} \ ProgID]]
@='PDFTransformer3.PDFTContextMenu.1'


[[HKEY\_CLASSES\_ROOT \ CLSID {2DC8E5F2-C89C-4730-82C9-19120DEE5B0A} \ Programmerbar]]


[[HKEY\_CLASSES\_ROOT \ CLSID {2DC8E5F2-C89C-4730-82C9-19120DEE5B0A} \ VersionIndependentProgID]]
@='PDFTransformer3.PDFTContextMenu'


EDIT


Er det muligt at ringe ShellExecuteEx med verbet, jeg vil have (ikke standardværdien)? Hvis ja, hvordan kalder jeg det verb jeg vil have (som bruger DLL'en)?


Det er verben jeg vil ringe til en PDF-fil:


Indtast billedbeskrivelse her

Bedste reference


DLL'en er åbenbart en kontekstmenuudvidelse. Hvis du vil kalde det på samme måde som skalen, så vil du vært den IContextMenu-grænseflade, som DLL'en implementerer. For flere år siden skrev Raymond Chen en omfattende serie om dette emne: [14]


Sådan hoster du en IContextMenu




  1. Begyndende foray

  2. Viser kontekstmenuen

  3. Invokationssted

  4. Nøgle kontekst

  5. Håndtering af menupunkter

  6. Viser menuhjælp

  7. Angiv standardværdien

  8. Optimering til standardkommandoen

  9. Tilføjelse af brugerdefinerede kommandoer

  10. Sammensatte udvidelser - grundarbejde

  11. Kompositudvidelser - sammensætning



De to første artikler er de vigtigste. De introducerer hvordan man får IContextMenu-grænsefladen af ​​en fil i første omgang, og hvordan man påberåber en eller flere af de kommandoer, der tilbydes af den menu. I det væsentlige skal du få IContextMenu-grænsefladen, udfylde en CMINVOKECOMMANDINFOEX-struktur og derefter sende den til grænsefladens InvokeCommand metode. Artiklerne kalder TrackPopupMenu for at vise en menu til brugeren og derefter bruge valget til Fyld strukturen, men hvis du allerede ved præcis, hvilken kommando du vil køre, kan du afstå fra at vise menuen. (Du kan muligvis stadig oprette menuen, da IContextMenu-objektet formentlig forventer at have QueryContextMenu opfordret det først.) [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29]

Andre referencer 1


Rafael, du kan bruge IContextMenu Interface. herfra kan du opregne de poster, der returneres af grænsefladen og derefter udføre den valgmulighed, du vil bruge ved hjælp af InvokeCommand [30] [31]

Andre referencer 2


Det er et COM-objekt. Du skal bare oprette det og sende det grænseflader (med tilstrækkelig implementering bag det), det gør det til at fungere.


Explorer (dvs. dig) vil bede shell-udvidelsen for at tilføje elementer til en anden HMENU. Så påberåber Explorer (dvs. dig) et menupunkt som svar på brugeren.


Heldigvis er alt i skallen en grænseflade - så du kan lade ud for at være hvad du vil. Du skal bare læse SDK-kontrakten fra den anden side. [32]


Husk : En shell-udvidelse har ikke em til at være vært i Explorer. Mange er ikke. En masse er vært i dialogboksen 'Gem som' fra CommCtrl. [33]





I dit tilfælde er det endnu enklere. [34]



  • Opret COM-objektet

  • forespørgsel efter dets grænseflade IShellExtInit og ring til .Initialize.

  • forespørgsel efter dets grænseflade IContextMenu

  • ring til IContextMenu.QueryContextMenu, så det kan tilføjes elementer til en HMENU

  • ring til IContextMenu.Invoke



Igen er der tale om at læse kontrakten fra den anden side.





Nogle pseudokode:


var
   ClassID: TGUID;
   unk: IUnknown;
   shellext: IShellExtInit;
   dataObject: IDataObject;
   hkeyProgID: HKEY;
   contextMenu: IContextMenu;
   commandInfo: CMINVOKECOMMANDINFO;
begin
   ClassID := ProgIDToClassID('PDFTransformer3.PDFTContextMenu'); 
   unk := CreateComObject(ClassID);

   shellExt := unk as IShellExtInit;

    {
       For shortcut menu extensions, 
          pdtobj identifies the selected file objects,
          hkeyProgID identifies the file type of the object with focus, and 
          pidlFolder is either NULL (for file objects) or specifies the folder 
             for which the shortcut menu is being requested 
             (for folder background shortcut menus).
   }
   shellExt.Initialize(
         nil, //pidlFolder, null for file objects
         dataObject, //IDataObject of the selected file
         hkeyProgID); //HKEY of the file type of the object with focus    

   contextMenu := unk as IContextMenu;
   contextMenu.QueryContextMenu(
         menuHandle, //HMENU, A handle to the shortcut menu. The handler should specify this handle when adding menu items.
         0, //integer, The zero-based position at which to insert the first new menu item.
         100, //The minimum value that the handler can specify for a menu item identifier.
         200, //The maximum value that the handler can specify for a menu item identifier.
         CMF\_NORMAL); //optional flags

   contextMenu.InvokeCommand(commandInfo);


Det er så vidt jeg får fra at læse dokumentation og gætte hvad jeg skal gøre. Nu skal jeg tisse og gå hjem for at spille Portal 2