我希望编写一个简单的Windows shell扩展程序,将其添加到上下文菜单中,而C#是我最近使用最多的语言。它是否适合用于shell扩展程序?它是否易于访问接口?是否存在额外的开销导致菜单弹出速度变慢?
有没有好的入门指南可以提供?
我希望编写一个简单的Windows shell扩展程序,将其添加到上下文菜单中,而C#是我最近使用最多的语言。它是否适合用于shell扩展程序?它是否易于访问接口?是否存在额外的开销导致菜单弹出速度变慢?
有没有好的入门指南可以提供?
实现进程内扩展的指南已经修订,并且继续建议不要使用托管代码编写shell扩展、Internet Explorer扩展(以及其他类型的进程内扩展),即使您正在使用第4版或更高版本。
版本冲突
版本冲突可能是由于运行时不支持在单个进程中加载多个运行时版本而引起的。 CLR 4.0 版本之前的版本属于此类。如果加载一个运行时版本会排除其他相同运行时版本的加载,当主机应用程序或另一个进程内扩展使用冲突版本时,这可能会创建冲突。在与另一个进程内扩展存在版本冲突的情况下,冲突可能难以重现,因为故障需要正确的冲突扩展,并且故障模式取决于加载冲突扩展的顺序。性能问题
运行时的性能问题可能会在加载到进程中时导致显著的性能损失。性能损失可以表现为内存使用、CPU使用、经过时间甚至是地址空间消耗。已知CLR、JavaScript/ECMAScript和Java是高影响力的运行时。由于内部扩展可以加载到许多进程中,并且通常在性能敏感的时刻(例如准备将菜单显示给用户时)进行,高影响力的运行时可能会对整体响应性产生负面影响。
消耗大量资源的高影响力运行时可能会导致主机进程或其他内部扩展失败。例如,一个消耗数百兆字节地址空间用于其堆的高影响力运行时可能导致主机应用程序无法加载大型数据集。此外,由于内部扩展可以加载到多个进程中,因此单个扩展中的高资源消耗可以迅速扩散到整个系统中的高资源消耗。
如果运行时即使在卸载使用该运行时的扩展后仍保持加载或以其他方式继续消耗资源,则该运行时不适合用于扩展。
特定于.NET Framework的问题
以下部分讨论了使用托管代码作为扩展时遇到的问题示例。这些并不是您可能遇到的所有可能问题的完整列表。这里讨论的问题既是托管代码不支持扩展的原因,也是在评估使用其他运行时时要考虑的问题。托管代码和其他运行时的可接受用途
使用托管代码和其他运行时来实现进程外扩展是可以接受的。进程外 Shell 扩展的示例包括以下内容:
- 预览处理程序
- 基于命令行的操作,例如在 shell\verb\command 子键下注册的操作。
- 在本地服务器中实现的 COM 对象,用于允许进程外激活的 Shell 扩展点。
某些扩展可以作为进程内或进程外扩展来实现。如果它们不符合进程内扩展的要求,则可以将这些扩展实现为进程外扩展。以下列表显示了可以作为进程内或进程外扩展实现的示例:
- 与在 shell\verb\command 子键下注册的 DelegateExecute 条目相关联的 IExecuteCommand。
- 与在 shell\verb\DropTarget 子键下注册的 CLSID 相关联的 IDropTarget。
- 与在 shell\verb 子键下注册的 CommandStateHandler 条目相关联的 IExplorerCommandState。
SharpShell使用.NET Framework轻松创建Windows Shell扩展。
源代码托管在https://github.com/dwmkerr/sharpshell上,您可以在此处或那里发布问题和功能请求。 支持的扩展
您可以使用SharpShell构建以下任何扩展:
使用SharpShell的项目
1. Trello上下文菜单
2. REAL Shuffle Player 2.0
CodeProject上的文章系列
[Guid("00000000-0000-0000-0000-000000000000"), ComVisible(true)]
[TargetExtension(".txt", true)]
public class SampleExtension : ContextMenuExtension
{
protected override void OnGetMenuItems(GetMenuitemsEventArgs e)
{
e.Menu.AddItem("Sample Extension", "sampleverb", "Status/help text");
}
protected override bool OnExecuteMenuItem(ExecuteItemEventArgs e)
{
if (e.MenuItem.Verb == "sampleverb")
; // logic
return true;
}
[ComRegisterFunction]
public static void Register(Type t)
{
ContextMenuExtension.RegisterExtension(typeof(SampleExtension));
}
[ComUnregisterFunction]
public static void UnRegister(Type t)
{
ContextMenuExtension.UnRegisterExtension(typeof(SampleExtension));
}
}