如何用C#来做Shell Extenstion

testcitiz 2007-01-04 09:08:30
下面给出个例子,欢迎大家来讨论,它们到底能干什么?

using System;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
//using System.Windows.Forms;
using Microsoft.Win32;
using ShellExt;
using System.Text;
using System.IO;


//[assembly:AssemblyKeyFile("..\\..\\CleanVS.snk")] // Strong name keyfile for this assembly
[assembly:ComVisible(false)] // Make sure that no interfaces are registered with COM


namespace CleanVS
{

[Guid("2AA8DDCB-0540-4cd3-BD31-D91DADD81ED3"), ComVisible(true)]
public class CleanVS : IContextMenu, IShellExtInit
{
public CleanVS() {}

const string clsid = "{2AA8DDCB-0540-4cd3-BD31-D91DADD81ED3}";

IDataObject m_dataObject = null;
uint m_hDrop = 0;

#region Registration

[System.Runtime.InteropServices.ComRegisterFunctionAttribute()]
static void RegisterServer(String zRegKey)
{
try
{
RegistryKey root;
RegistryKey rk;

root = Registry.CurrentUser;
rk = root.OpenSubKey("Software\\Microsoft\\Windows\\" +
"CurrentVersion\\Explorer", true);
rk.SetValue("DesktopProcess", 1);
rk.Close();

// For Winnt set me as an approved shellex
root = Registry.LocalMachine;
rk = root.OpenSubKey("Software\\Microsoft\\Windows\\" +
"CurrentVersion\\Shell Extensions\\" +
"Approved", true);
rk.SetValue(clsid, "CleanVS Shell Extension");
rk.Close();

root = Registry.ClassesRoot;
rk = root.CreateSubKey("Folder\\shellex\\" +
"ContextMenuHandlers\\CleanVS");
rk.SetValue("", clsid);
rk.Close();


}
catch(Exception e)
{
System.Console.Error.WriteLine(e.ToString());
}
}

[System.Runtime.InteropServices.ComUnregisterFunctionAttribute()]
static void UnregisterServer(String zRegKey)
{
try
{
RegistryKey root;
RegistryKey rk;

// Remove ShellExtenstions registration
root = Registry.LocalMachine;
rk = root.OpenSubKey("Software\\Microsoft\\Windows\\" +
"CurrentVersion\\Shell Extensions\\" +
"Approved", true);
rk.DeleteValue(clsid);
rk.Close();

// Delete ShellCmd regkey
root = Registry.ClassesRoot;
root.DeleteSubKey("Folder\\shellex\\ContextMenuHandlers\\" +
"CleanVS");

}
catch(Exception e)
{
System.Console.Error.WriteLine(e.ToString());
}
}

...全文
351 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
Fibona 2008-12-20
  • 打赏
  • 举报
回复
代码太多了
testcitiz 2007-01-04
  • 打赏
  • 举报
回复
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;

namespace ShellExt
{
#region Consts/Enum

public enum MIIM : uint
{
STATE = 0x00000001,
ID = 0x00000002,
SUBMENU = 0x00000004,
CHECKMARKS = 0x00000008,
TYPE = 0x00000010,
DATA = 0x00000020,
STRING = 0x00000040,
BITMAP = 0x00000080,
FTYPE = 0x00000100
}

public enum MF : uint
{
INSERT = 0x00000000,
CHANGE = 0x00000080,
APPEND = 0x00000100,
DELETE = 0x00000200,
REMOVE = 0x00001000,
BYCOMMAND = 0x00000000,
BYPOSITION = 0x00000400,
SEPARATOR = 0x00000800,
ENABLED = 0x00000000,
GRAYED = 0x00000001,
DISABLED = 0x00000002,
UNCHECKED = 0x00000000,
CHECKED = 0x00000008,
USECHECKBITMAPS=0x00000200,
STRING = 0x00000000,
BITMAP = 0x00000004,
OWNERDRAW = 0x00000100,
POPUP = 0x00000010,
MENUBARBREAK = 0x00000020,
MENUBREAK = 0x00000040,
UNHILITE = 0x00000000,
HILITE = 0x00000080,
DEFAULT = 0x00001000,
SYSMENU = 0x00002000,
HELP = 0x00004000,
RIGHTJUSTIFY = 0x00004000,
MOUSESELECT = 0x00008000
}

public enum CLIPFORMAT : uint
{
CF_TEXT = 1,
CF_BITMAP = 2,
CF_METAFILEPICT= 3,
CF_SYLK = 4,
CF_DIF = 5,
CF_TIFF = 6,
CF_OEMTEXT = 7,
CF_DIB = 8,
CF_PALETTE = 9,
CF_PENDATA = 10,
CF_RIFF = 11,
CF_WAVE = 12,
CF_UNICODETEXT= 13,
CF_ENHMETAFILE= 14,
CF_HDROP = 15,
CF_LOCALE = 16,
CF_MAX = 17,

CF_OWNERDISPLAY=0x0080,
CF_DSPTEXT = 0x0081,
CF_DSPBITMAP = 0x0082,
CF_DSPMETAFILEPICT= 0x0083,
CF_DSPENHMETAFILE = 0x008E,

CF_PRIVATEFIRST=0x0200,
CF_PRIVATELAST= 0x02FF,

CF_GDIOBJFIRST =0x0300,
CF_GDIOBJLAST = 0x03FF
}

public enum DVASPECT: uint
{
DVASPECT_CONTENT = 1,
DVASPECT_THUMBNAIL = 2,
DVASPECT_ICON = 4,
DVASPECT_DOCPRINT = 8
}

public enum TYMED: uint
{
TYMED_HGLOBAL = 1,
TYMED_FILE = 2,
TYMED_ISTREAM = 4,
TYMED_ISTORAGE= 8,
TYMED_GDI = 16,
TYMED_MFPICT = 32,
TYMED_ENHMF = 64,
TYMED_NULL= 0
}

public enum CMF: uint
{
CMF_NORMAL = 0x00000000,
CMF_DEFAULTONLY = 0x00000001,
CMF_VERBSONLY = 0x00000002,
CMF_EXPLORE = 0x00000004,
CMF_NOVERBS = 0x00000008,
CMF_CANRENAME = 0x00000010,
CMF_NODEFAULT = 0x00000020,
CMF_INCLUDESTATIC= 0x00000040,
CMF_RESERVED = 0xffff0000 // View specific
}

// GetCommandString uFlags
public enum GCS: uint
{
VERBA = 0x00000000, // canonical verb
HELPTEXTA = 0x00000001, // help text (for status bar)
VALIDATEA = 0x00000002, // validate command exists
VERBW = 0x00000004, // canonical verb (unicode)
HELPTEXTW = 0x00000005, // help text (unicode version)
VALIDATEW = 0x00000006, // validate command exists (unicode)
UNICODE = 0x00000004, // for bit testing - Unicode string
VERB = GCS.VERBA,
HELPTEXT = GCS.HELPTEXTA,
VALIDATE = GCS.VALIDATEA
}

#endregion
testcitiz 2007-01-04
  • 打赏
  • 举报
回复
public void ChangeStatus(string msg)
{
statusDlg.status.Text = msg;
if (statusDlg.progress.Value < statusDlg.progress.Maximum)
{
statusDlg.progress.Increment(1);
}
else
{
statusDlg.progress.Value = 1;
}
}

#endregion

#region IContextMenu Members

int IContextMenu.QueryContextMenu(uint hmenu,
uint iMenu,
int idCmdFirst,
int idCmdLast,
uint uFlags)
{
// The first id to use (should be 1)
int id = 1;

// If its a directory we can show the menu item
if (IsDirectorySelected(uFlags))
{
// Create a new Menu Item to add to the popup menu
MENUITEMINFO mii = new MENUITEMINFO();
mii.cbSize = 48;
mii.fMask = (uint)MIIM.ID | (uint)MIIM.TYPE | (uint)MIIM.STATE;
mii.wID = idCmdFirst + id;
mii.fType = (uint)MF.STRING;
mii.dwTypeData = "Clean VS.NET Temp Files";
mii.fState = (uint)MF.ENABLED;

// Add it to the item
DllImports.InsertMenuItem(hmenu, (uint)2, 1, ref mii);

// Since we only added a single item,
// just increment the id by 1
id++;
}

// Return the new id number if we actually added an item
return id;
}

void IContextMenu.InvokeCommand(IntPtr pici)
{
try
{
StringBuilder sb = new StringBuilder(1024);

// Get the Directory Information
DllImports.DragQueryFile(m_hDrop, 0, sb, sb.Capacity + 1);
string directory = sb.ToString();

// Show Status Form
statusDlg.Show();

CleanDirectory(directory);

}
catch(Exception e)
{
System.Windows.Forms.MessageBox.Show("Error : " + e.ToString(),
"Error in CleanVS");
}
finally
{
// Hide the status window
statusDlg.Hide();
}
}

void IContextMenu.GetCommandString(int idcmd,
uint uflags,
int reserved,
StringBuilder commandstring,
int cch)
{
switch(uflags)
{
case (uint)GCS.VERB:
commandstring = new StringBuilder("CleanVS".Substring(1, cch-1));
break;
case (uint)GCS.HELPTEXT:
{
commandstring = new StringBuilder("Removes all temporary files " +
"from a directory (and sub directories) from Visual " +
"Studio Builds".Substring(1, cch-1));
break;
}
case (uint)GCS.VALIDATE:
break;
}
}

#endregion

#region IShellExtInit Members

int IShellExtInit.Initialize(IntPtr pidlFolder,
IntPtr lpdobj,
uint hKeyProgID)
{
try
{
m_dataObject = null;
if (lpdobj != (IntPtr)0)
{
// Get info about the directory
m_dataObject =
(ShellExt.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();
m_dataObject.GetData(ref fmt, ref medium);
m_hDrop = medium.hGlobal;

}
}
catch(Exception)
{
}
return 0;
}

#endregion
}
}
testcitiz 2007-01-04
  • 打赏
  • 举报
回复
static void Usage()
{
System.Console.WriteLine("Syntax: CleanVS [Options]\nOptions:\n /u Uninstall the shell extension\n /? or /help Display this usage message");
}

public static int Main(string[] args)
{
bool unregister = false;

try
{
Console.WriteLine("CleanVS.exe - Windows explorer " +
"namespace extension for cleaning up " +
"of temporary files from Visual Studio " +
"Project Directories\n" +
"Copyright (C) Shawn Wildermuth 2003. " +
"All rights reserved.");

if(args.Length == 1)
{
string a = args[0].Replace('-', '/').ToLower(CultureInfo.InvariantCulture);
if (a == "/?" || args[0] == "/help")
{
Usage();
return 0;
}
else if (a == "/u")
{
unregister = true;
}
else
{
Console.WriteLine("Invalid option: " + args[0]);
Usage();
return 1;
}
}

// (Un)Register if necessary
Assembly asm = Assembly.GetExecutingAssembly();
RegistrationServices reg = new RegistrationServices();
if(unregister)
{
reg.UnregisterAssembly(asm);
CleanVS.UnregisterServer("");
}
else
{
reg.RegisterAssembly(asm,
AssemblyRegistrationFlags.SetCodeBase);
CleanVS.RegisterServer("");
}
return 0;
}
catch(Exception e)
{
Console.WriteLine("An exception was thrown : " + e);
return 1;
}
}
#endregion

#region Functional Implementation
bool IsDirectorySelected(uint uFlags)
{
if ( (uFlags & (uint)CMF.CMF_DEFAULTONLY) == 0)
{
uint nselected = DllImports.DragQueryFile(m_hDrop,
0xffffffff,
null,
0);
if (nselected == 1)
{
StringBuilder sb = new StringBuilder(1024);
DllImports.DragQueryFile(m_hDrop, 0, sb, sb.Capacity + 1);
string directory = sb.ToString();
uint attr = DllImports.GetFileAttributes(directory);
if ((attr & DllImports.FILE_ATTRIBUTE_DIRECTORY) != 0)
{
// Is a Directory
return true;
}
}
}

// No Directory
return false;
}

string[] patterns = new string[] { "*.obj", "*.pdb", "*.projdata", "*.resources", "*.user", "*.suo" };
CleanStatus statusDlg = new CleanStatus();

void CleanDirectory(string path)
{
// See if it is an obj directory
if (path.ToLower().EndsWith("\\obj"))
{
// Show Statuss
ChangeStatus(string.Format("Deleting {0} directory", path));

// If the parent directory ahs a project file or a solution file, then delete the obj directory completely
if (Directory.GetFiles(path.Substring(0, path.Length -3), "*.??proj").Length > 0 ||
Directory.GetFiles(path.Substring(0, path.Length -3), "*.sln").Length > 0)
{
try
{
Directory.Delete(path, true);
}
catch
{
}
}
}
else
{
// Delete Specific Files
foreach (string pattern in patterns)
{
// Get the files of that pattern
string[] files = Directory.GetFiles(path, pattern);

// Go through each found file
foreach (string file in files)
{
// If it exists
if (File.Exists(file))
{
// Show Statuss
ChangeStatus(string.Format("Deleting file: {0}", file));
try
{

// Kill it
File.Delete(file);
}
catch
{
}
}
}
}

// Call recursively
string[] dirs = Directory.GetDirectories(path);
foreach (string dir in dirs)
{
CleanDirectory(dir);
}
}
}

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧