home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2005 June (DVD) / DPPRO0605DVD.iso / dotNETSDK / SETUP.EXE / netfxsd1.cab / FL_shellcmd_cs________.3643236F_FC70_11D3_A536_0090278A1BB8 < prev    next >
Encoding:
Text File  |  2002-05-06  |  9.9 KB  |  346 lines

  1. /*************************************************************************************************************
  2. *    Title:            ShellCmd.cs
  3. *    Description:    ShellExtension implementation
  4. **************************************************************************************************************
  5. */
  6.  
  7. using System;
  8. using System.Globalization;
  9. using System.IO;
  10. using System.Reflection;
  11. using System.Runtime.CompilerServices;
  12. using System.Runtime.InteropServices;
  13. using System.Text;
  14. using Microsoft.Win32;
  15. using System.Security.Permissions;
  16.  
  17.  
  18. [assembly:AssemblyKeyFile("shellcmd.snk")]            // Strong name keyfile for this assembly
  19. [assembly:ComVisible(false)]                        // Make sure that no interfaces are registered with COM
  20.  
  21. namespace ShellExt
  22. {
  23.     struct MenuItem
  24.     {
  25.         public    string    text;
  26.         public    string    command;
  27.     }
  28.  
  29.     [Guid("82C62DC5-1A4B-43AC-92C8-571410996B45"), ComVisible(true)]
  30.     public    class    Implementation: IShellExtInit, IContextMenu
  31.     {
  32.         const    string guid = "{82C62DC5-1A4B-43ac-92C8-571410996B45}";
  33.  
  34.         [DllImport("kernel32.dll")]
  35.         static extern Boolean SetCurrentDirectory([MarshalAs(UnmanagedType.LPTStr)]string lpPathName);
  36.  
  37.         [DllImport("kernel32.dll")]
  38.         static extern uint GetFileAttributes([MarshalAs(UnmanagedType.LPTStr)]string lpPathName);
  39.         const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
  40.  
  41.         [DllImport("kernel32.dll")]
  42.         static extern Boolean CreateProcess(
  43.                                             string    lpApplicationName,
  44.                                             string    lpCommandLine,
  45.                                             uint    lpProcessAttributes,
  46.                                             uint    lpThreadAttributes,
  47.                                             Boolean bInheritHandles,
  48.                                             uint    dwCreationFlags,
  49.                                             uint    lpEnvironment,
  50.                                             string    lpCurrentDirectory,
  51.                                             StartupInfo lpStartupInfo,
  52.                                             ProcessInformation lpProcessInformation);
  53.  
  54.         [DllImport("shell32")]
  55.         static extern uint DragQueryFile(uint hDrop,uint iFile, StringBuilder buffer, int cch);
  56.  
  57.         [DllImport("user32")]
  58.         static extern int MessageBox(int hWnd, string text, string caption, int type);
  59.  
  60.         [DllImport("user32")]
  61.         static extern int InsertMenuItem(uint hmenu, uint uposition, uint uflags, ref MENUITEMINFO mii);
  62.  
  63.         IDataObject    m_dataObject = null;
  64.         uint    m_hDrop = 0;
  65.  
  66.         MenuItem[] m_items;
  67.  
  68.         int    IContextMenu.QueryContextMenu(uint hMenu, uint iMenu, int idCmdFirst, int idCmdLast, uint uFlags)
  69.         {
  70.             int id = 1;
  71.             if ( (uFlags & 0xf) == 0 || (uFlags & (uint)CMF.CMF_EXPLORE) != 0)
  72.             {
  73.                 uint nselected = DragQueryFile(m_hDrop, 0xffffffff, null, 0);
  74.                 if (nselected == 1)
  75.                 {
  76.                     StringBuilder sb = new StringBuilder(1024);
  77.                     DragQueryFile(m_hDrop, 0, sb, sb.Capacity + 1);
  78.                     string directory = sb.ToString();
  79.                     uint attr = GetFileAttributes(directory);
  80.                     if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0)
  81.                     {
  82.                         // I have selected a bona-fide directory add to the menus.
  83.                         MENUITEMINFO mii = new MENUITEMINFO();
  84.                         mii.cbSize        = 48;
  85.                         mii.fMask        = (uint)MIIM.ID | (uint)MIIM.TYPE | (uint)MIIM.STATE;
  86.  
  87.                         foreach(MenuItem item in m_items)
  88.                         {
  89.                             mii.wID            = idCmdFirst + id;
  90.                             mii.fType        = (uint)MF.STRING;
  91.                             mii.dwTypeData    = item.text;
  92.                             mii.fState        = (uint)MF.ENABLED;
  93.                             InsertMenuItem(hMenu, (uint)2, 1, ref mii);
  94.                             id++;
  95.                         }
  96.                         // Go and get the menus from the registry
  97.                         if (m_items.Length > 0)
  98.                         {
  99.                             mii.fType        = (uint)MF.SEPARATOR;
  100.                             mii.fState        = (uint)MF.ENABLED;
  101.                             InsertMenuItem(hMenu, (uint)2, 1, ref mii);
  102.                         }
  103.                     }
  104.                 }
  105.             }
  106.             return id;
  107.         }
  108.  
  109.         void    IContextMenu.GetCommandString(int idCmd, uint uFlags, int pwReserved, StringBuilder commandString, int cchMax)
  110.         {
  111.             switch(uFlags)
  112.             {
  113.             case (uint)GCS.VERB:
  114.                 commandString = new StringBuilder(m_items[idCmd - 1].command.Substring(1, cchMax-1));
  115.                 break;
  116.             case (uint)GCS.HELPTEXT:
  117.                 commandString = new StringBuilder(m_items[idCmd - 1].command.Substring(1, cchMax));
  118.                 break;
  119.             case (uint)GCS.VALIDATE:
  120.                 break;
  121.             }
  122.         }
  123.  
  124.         void    IContextMenu.InvokeCommand (IntPtr pici)
  125.         {
  126.             try
  127.             {
  128.                 Type typINVOKECOMMANDINFO = Type.GetType("ShellExt.INVOKECOMMANDINFO");
  129.                 INVOKECOMMANDINFO ici = (INVOKECOMMANDINFO)Marshal.PtrToStructure(pici, typINVOKECOMMANDINFO);
  130.                 if (ici.verb - 1 <= m_items.Length)
  131.                 {
  132.                     ExecuteCommand(m_items[ici.verb - 1].command);
  133.                 }
  134.             }
  135.             catch(Exception e)
  136.             {
  137.                 MessageBox(0, "Error : " + e.ToString(), "Error in ShellCmd.exe", 0);
  138.             }
  139.         }
  140.  
  141.  
  142.         int    IShellExtInit.Initialize (IntPtr /*LPCITEMIDLIST*/ pidlFolder, IntPtr /*LPDATAOBJECT*/ lpdobj, uint /*HKEY*/ hKeyProgID)
  143.         {
  144.             try
  145.             {
  146.                 m_dataObject = null;
  147.                 if (lpdobj != (IntPtr)0)
  148.                 {
  149.                     // Get info about the directory
  150.                     m_dataObject = (IDataObject)Marshal.GetObjectForIUnknown(lpdobj);
  151.                     FORMATETC fmt = new FORMATETC();
  152.                     fmt.cfFormat = CLIPFORMAT.CF_HDROP;
  153.                     fmt.ptd         = 0;
  154.                     fmt.dwAspect = DVASPECT.DVASPECT_CONTENT;
  155.                     fmt.lindex     = -1;
  156.                     fmt.tymed     = TYMED.TYMED_HGLOBAL;
  157.                     STGMEDIUM medium = new STGMEDIUM();
  158.                     m_dataObject.GetData(ref fmt, ref medium);
  159.                     m_hDrop = medium.hGlobal;
  160.  
  161.                     /*
  162.                      * Now retrieve the menu information from the registry
  163.                     */
  164.                     RegistryKey sc = Registry.LocalMachine;
  165.                     sc = sc.OpenSubKey("Software\\Microsoft\\ShellCmd", true);
  166.                     if (sc.SubKeyCount > 0)
  167.                     {
  168.                         m_items = new MenuItem[sc.SubKeyCount];
  169.                         int    i=0;
  170.                         foreach(string name in sc.GetSubKeyNames())
  171.                         {
  172.                             try
  173.                             {
  174.                                 RegistryKey item = sc.OpenSubKey(name, true);
  175.                                 string command = (string)item.GetValue("");
  176.                                 MenuItem m = new MenuItem();
  177.                                 m.text = name;
  178.                                 m.command = command;
  179.                                 m_items[i] = m;
  180.                                 ++i;
  181.                             }
  182.                             catch(Exception)
  183.                             {
  184.                             }
  185.                         }
  186.                     }
  187.                     else
  188.                     {
  189.                         m_items = new MenuItem[0];
  190.                     }
  191.                 }
  192.             }
  193.             catch(Exception)
  194.             {
  195.             }
  196.             return 0;
  197.         }
  198.  
  199.         private    void ExecuteCommand(string command)
  200.         {
  201.             StartupInfo si = new StartupInfo();
  202.             ProcessInformation pi = new ProcessInformation();
  203.             si.cb = 68; //sizeof(si);
  204.             try
  205.             {
  206.                 // Get the directory name
  207.                 StringBuilder sb = new StringBuilder(1024);
  208.                 DragQueryFile(m_hDrop, 0, sb, sb.Capacity + 1);
  209.                 string directory = sb.ToString();
  210.  
  211.                 if (!CreateProcess (null, command, 0, 0, false, 0, 0, directory, si, pi))
  212.                 {
  213.                     MessageBox(0, "Unable to execute : " + command, "Error in ShellCmd.exe", 0);
  214.                 }
  215.             }
  216.             catch (Exception e)
  217.             {
  218.                 Console.WriteLine(e);
  219.             }
  220.         }
  221.  
  222.         [System.Runtime.InteropServices.ComRegisterFunctionAttribute()]
  223.         static void RegisterServer(String str1)
  224.         {
  225.             try
  226.             {
  227.                 RegistryKey root;
  228.                 RegistryKey rk;
  229.                 root = Registry.CurrentUser;
  230.                 rk = root.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer", true);
  231.                 rk.SetValue("DesktopProcess", 1);
  232.                 rk.Close();
  233.  
  234.                 // For Winnt set me as an approved shellex
  235.                 root = Registry.LocalMachine;
  236.                 rk = root.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", true);
  237.                 rk.SetValue(guid.ToString(), "ShellCmd shell extension");
  238.                 rk.Close();
  239.  
  240.                 // Set "Folder\\shellex\\ContextMenuHandlers\\ShellCmd" regkey to my guid
  241.                 root = Registry.ClassesRoot;
  242.                 rk = root.CreateSubKey("Folder\\shellex\\ContextMenuHandlers\\ShellCmd");
  243.                 rk.SetValue("", guid.ToString());
  244.                 rk.Close();
  245.  
  246.                 // Add setting for Command.com
  247.                 root = Registry.LocalMachine;
  248.                 rk = root.CreateSubKey("Software\\Microsoft\\ShellCmd");
  249.                 rk = root.CreateSubKey("Software\\Microsoft\\ShellCmd\\Command");
  250.                 if (Environment.OSVersion.Platform == PlatformID.Win32NT)
  251.                     rk.SetValue("", "cmd.exe");
  252.                 else
  253.                     rk.SetValue("", "command.com");
  254.  
  255.                 rk.Close();
  256.             }
  257.             catch(Exception e)
  258.             {
  259.                 System.Console.WriteLine(e.ToString());
  260.             }
  261.         }
  262.  
  263.         [System.Runtime.InteropServices.ComUnregisterFunctionAttribute()]
  264.         static void UnregisterServer(String str1)
  265.         {
  266.             try
  267.             {
  268.                 RegistryKey root;
  269.                 RegistryKey rk;
  270.  
  271.                 // Remove ShellExtenstions registration
  272.                 root = Registry.LocalMachine;
  273.                 rk = root.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", true);
  274.                 rk.DeleteValue(guid);
  275.                 rk.Close();
  276.  
  277.                 // Delete ShellCmd regkey
  278.                 root = Registry.ClassesRoot;
  279.                 root.DeleteSubKey("Folder\\shellex\\ContextMenuHandlers\\ShellCmd");
  280.  
  281.                 // Delete Command.com setting
  282.                 root = Registry.LocalMachine;
  283.                 root.DeleteSubKey("Software\\Microsoft\\ShellCmd\\Command");
  284.                 root.DeleteSubKey("Software\\Microsoft\\ShellCmd");
  285.             }
  286.             catch(Exception e)
  287.             {
  288.                 System.Console.WriteLine(e.ToString());
  289.             }
  290.         }
  291.  
  292.         private static void    Usage()
  293.         {
  294.             System.Console.WriteLine("Syntax: shellcmd [Options]\nOptions:\n    /u             Uninstall the shell extension\n    /? or /help    Display this usage message");
  295.         }
  296.  
  297.         public static int    Main(string[] args)
  298.         {
  299.             bool unregister = false;
  300.  
  301.             try
  302.             {
  303.                 Console.WriteLine("ShellCmd - Windows explorer namespace extension sample for .NET\nCopyright (C) Microsoft Corp. 2000-2002.  All rights reserved.");
  304.  
  305.                 if(args.Length == 1)
  306.                 {
  307.                     string a = args[0].Replace('-', '/').ToLower(CultureInfo.InvariantCulture);
  308.                     if (a == "/?" || args[0] == "/help")
  309.                     {
  310.                         Usage();
  311.                         return 0;
  312.                     }
  313.                     else if (a == "/u")
  314.                     {
  315.                         unregister = true;
  316.                     }
  317.                     else
  318.                     {
  319.                         Console.WriteLine("Invalid option: " + args[0]);
  320.                         Usage();
  321.                         return 1;
  322.                     }
  323.                 }
  324.  
  325.                 // Do my registration / alink etc.
  326.                 Assembly asm = Assembly.GetExecutingAssembly();    // Get the assembly in which I can be found
  327.                 RegistrationServices reg = new RegistrationServices();
  328.                 if(unregister)
  329.                 {
  330.                     reg.UnregisterAssembly(asm);
  331.                 }
  332.                 else
  333.                 {
  334.                     reg.RegisterAssembly(asm, AssemblyRegistrationFlags.SetCodeBase);
  335.                 }
  336.                 return 0;
  337.             }
  338.             catch(Exception e)
  339.             {
  340.                 Console.WriteLine("An exception was thrown : " + e);
  341.                 return 1;
  342.             }
  343.         }
  344.     }
  345. }
  346.