// Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(true)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("345F4DC2-A9BF-11E2-AA47-CC986188709B")]
[DllImport("shell32")] internal static extern uint DragQueryFile(uint hDrop,uint iFile, StringBuilder buffer, int cch); [DllImport("user32")] internal static extern uint CreatePopupMenu(); [DllImport("user32")] internal static extern int InsertMenuItem(uint hmenu, uint uposition, uint uflags, ref MENUITEMINFO mii); [DllImport("user32.dll")] internal static extern bool SetMenuItemBitmaps(IntPtr hMenu, uint uPosition, uint uFlags, IntPtr hBitmapUnchecked, IntPtr hBitmapChecked); [DllImport("Shell32.dll")] internal static extern void SHChangeNotify(int wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2); const int SHCNE_ASSOCCHANGED = 0x08000000; [DllImport("user32.dll", SetLastError = true)] internal static extern bool PostMessage(IntPtr hWnd, [MarshalAs(UnmanagedType.U4)] uint Msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll", SetLastError = true)] internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), GuidAttribute("000214e8-0000-0000-c000-000000000046")] public interface IShellExtInit { [PreserveSig()] int Initialize (IntPtr pidlFolder, IntPtr lpdobj, uint /*HKEY*/ hKeyProgID); }
[ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), GuidAttribute("000214e4-0000-0000-c000-000000000046")] public interface IContextMenu { // IContextMenu methods [PreserveSig()] int QueryContextMenu(uint hmenu, uint iMenu, int idCmdFirst, int idCmdLast, uint uFlags); [PreserveSig()] void InvokeCommand (IntPtr pici); [PreserveSig()] void GetCommandString(int idCmd, uint uFlags, int pwReserved, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] byte[] pszName, uint cchMax); }
[System.Runtime.InteropServices.ComRegisterFunctionAttribute()] static void RegisterServer(System.Type type) { try { string approved = string.Empty; string contextMenu = string.Empty; RegistryKey root; RegistryKey rk; root = Registry.LocalMachine; rk = root.OpenSubKey(Resources.ApprovedReg, true); rk.SetValue(type.GUID.ToString("B"), Resources.Extension); approved = rk.ToString(); rk.Flush(); rk.Close(); root = Registry.ClassesRoot; rk = root.CreateSubKey(Resources.ExShellReg); rk.Flush(); rk.SetValue(null, type.GUID.ToString("B")); contextMenu = rk.ToString(); rk.Flush(); rk.Close(); EventLog.WriteEntry("Application", "Example ShellExt Registration Complete.\r\n" + approved + "\r\n" + contextMenu, EventLogEntryType.Information); RestartExplorer(); } catch(Exception e) { EventLog.WriteEntry("Application", "Example ShellExt Registration error.\r\n" + e.ToString(), EventLogEntryType.Error); } }
[System.Runtime.InteropServices.ComUnregisterFunctionAttribute()] static void UnregisterServer(System.Type type) { try { string approved = string.Empty; string contextMenu = string.Empty; RegistryKey root; RegistryKey rk; // Remove ShellExtenstions registration root = Registry.LocalMachine; rk = root.OpenSubKey(Resources.ApprovedReg, true); approved = rk.ToString(); rk.DeleteValue(type.GUID.ToString("B")); rk.Close(); // Delete regkey root = Registry.ClassesRoot; contextMenu = Resources.ExShellReg; root.DeleteSubKey(Resources.ExShellReg); EventLog.WriteEntry("Application", "Example ShellExt Unregister Complete.\r\n" + approved + "\r\n" + contextMenu, EventLogEntryType.Information); Helpers.SHChangeNotify(0x08000000, 0, IntPtr.Zero, IntPtr.Zero); } catch(Exception e) { EventLog.WriteEntry("Application", "Example ShellExt Unregister error.\r\n" + e.ToString(), EventLogEntryType.Error); } }
int IShellExtInit.Initialize (IntPtr pidlFolder, IntPtr lpdobj, uint hKeyProgID) { try { if (lpdobj != (IntPtr)0) { // Get info about the directory IDataObject dataObject = (IDataObject)Marshal.GetObjectForIUnknown(lpdobj); FORMATETC fmt = new FORMATETC(); fmt.cfFormat = CLIPFORMAT.CF_HDROP; fmt.ptd = 0; fmt.dwAspect = DVASPECT.DVASPECT_CONTENT; fmt.lindex = -1; fmt.tymed = TYMED.TYMED_HGLOBAL; STGMEDIUM medium = new STGMEDIUM(); dataObject.GetData(ref fmt, ref medium); m_hDrop = medium.hGlobal; } } catch(Exception) { } return 0; }
int IContextMenu.QueryContextMenu(uint hMenu, uint iMenu, int idCmdFirst, int idCmdLast, uint uFlags) { if ( (uFlags & 0xf) == 0 || (uFlags & (uint)CMF.CMF_EXPLORE) != 0) { uint nselected = Helpers.DragQueryFile(m_hDrop, 0xffffffff, null, 0); if (nselected > 0) { for (uint i = 0; i < nselected; i++) { StringBuilder sb = new StringBuilder(1024); Helpers.DragQueryFile(m_hDrop, i, sb, sb.Capacity + 1); fileNames.Add(sb.ToString()); } } else return 0;
// Add the popup to the context menu MENUITEMINFO mii = new MENUITEMINFO(); mii.cbSize = 48; mii.fMask = (uint) MIIM.ID | (uint)MIIM.TYPE | (uint) MIIM.STATE; mii.wID = idCmdFirst; mii.fType = (uint) MF.STRING; mii.dwTypeData = Resources.MenuItem; mii.fState = (uint) MF.ENABLED; Helpers.InsertMenuItem(hMenu, (uint)iMenu, (uint)MF.BYPOSITION | (uint)MF.STRING, ref mii); commands.Add(idCmdFirst); System.Reflection.Assembly myAssembly = System.Reflection.Assembly.GetExecutingAssembly(); Stream myStream = myAssembly.GetManifestResourceStream(Resources.BitmapName); Bitmap image = new Bitmap(myStream); Color backColor = image.GetPixel(1, 1); image.MakeTransparent(backColor); Helpers.SetMenuItemBitmaps((IntPtr)hMenu, (uint)iMenu, (uint)MF.BYPOSITION, image.GetHbitmap(), image.GetHbitmap()); // Add a separator MENUITEMINFO sep = new MENUITEMINFO(); sep.cbSize = 48; sep.fMask = (uint )MIIM.TYPE; sep.fType = (uint) MF.SEPARATOR; Helpers.InsertMenuItem(hMenu, iMenu + 1, 1, ref sep); } return 1; }
void IContextMenu.GetCommandString(int idCmd, uint uFlags, int pwReserved, byte[] pszName, uint cchMax) { string commandString = String.Empty; switch(uFlags) { case (uint)GCS.VERB: commandString = "test"; break; case (uint)GCS.HELPTEXTW: commandString = "test"; break; } var buf = Encoding.Unicode.GetBytes(commandString); int cch = Math.Min(buf.Length, pszName.Length - 1); if (cch > 0) { Array.Copy(buf, 0, pszName, 0, cch); } else { // null terminate the buffer pszName[0] = 0; } }
void IContextMenu.InvokeCommand (IntPtr pici) { try { System.Windows.Forms.MessageBox.Show("Test code"); } catch(Exception exe) { EventLog.WriteEntry("Application", exe.ToString()); } }
Source: https://habr.com/ru/post/177469/
All Articles