一、前言
.NET平台是微软公司推出的作为未来软件运行和开发的环境,C#是微软力荐的在.NET平台下开发应用软件的首选语言。本文将讨论在.NET环境下如何使用C#语言开发Windows Shell扩展问题。如今Windows家族已发展到XP世代了,想必每个程序员都对Shell Extension不会感到陌生吧,在这里我不想花太多的时间介绍Shell Extension的原理知识,本文中将通过一个实例介绍用C#创建一个Shell Extension,在此过程中也会简单介绍一些Shell Extension的原理知识(如果想详细了解Shell扩展原理知识,请参阅MSDN)。
二、开发环境
(1)、Windows2000 专业版。
(2)、Visual Studio.NET Beta 2.0或正式版1.0。
三、原理介绍
本实例实现一个ShellExecuteEx Win32调用的钩子操作,Windows Explorer常常会用到这个调用,如打开、编辑、打印等等Shell操作都要用到这个调用。在Windows注册表HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks项下安装了所有实现Shell扩展的组件信息。当Windows Explorer执行Shell操作前,先在注册中查找到已注册的Shell扩展组件,并将其实例化,每个Shell扩展组件必须至少实现了IShellExecuteHook接口,此接口提供了一个Execute()函数,Explorer将通过组件实例对象调用Execute()函数,如此函数返回为S_FALSE继续后面的操作,如返回S_OK则停止后面的所有操作。根据以上原理,本实例要实现Shell扩展就必须要实现一个支持IShellExecuteHook接口的COM组件。
接口声明
因C#不能像C++那样用一句#include "shlguid.h"语句就可以完成IShellExecuteHook接口声明,它必须要求在程序中声明接口的具体信息,声明如下:
[ComImpor,InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214FB-0000-0000-C000-000000000046")]
/* Guid("000214FB-0000-0000-C000-000000000046") 相当于shlguid.h中的DEFINE_SHLGUID(IID_IShellExecuteHookW, 0x000214FBL, 0, 0); */
public interface IShellExecuteHook{
[PreserveSig()] /* 允许返回值为COM HRESULT */
int Execute(SHELLEXECUTEINFO sei);
}
结构声明
在Execute()方法中有一个SHELLEXECUTEINFO结构体参数sei,接下来要声明结构体:
[StructLayout(LayoutKind.Sequential)]
public class SHELLEXECUTEINFO {
public int cbSize;
public int fMask;
public int hwnd;
[MarshalAs(UnmanagedType.LPWStr)]
public string lpVerb; /* 动作,如edit,open,print... */
[MarshalAs(UnmanagedType.LPWStr)]
public string lpFile; /* 根据lpVerb的值而定,常为文件名 */
[MarshalAs(UnmanagedType.LPWStr)]
public string lpParameters; /* 参数字符串 */
[MarshalAs(UnmanagedType.LPWStr)]
public string lpDirectory; /* 路径名 */
public int nShow;
public int hInstApp;
public int lpIDList;
public string lpClass;
public int hkeyClass;
public int dwHotKey;
public int hIcon;
public int hProcess;
}
SHELLEXECUTEINFO结构体的元素是不是够多的,它们的具体说明就不一一介绍了,如果你有空的话可以看看MSDN。
四、实现步骤
介绍了ISellExecuteHook接口的声明以及SHELLEXECUTEINFO结构体的声明后,我们就着手实现这个应用实例,这个实例很简单,每当Explorer对一个Shell对象执行某动作前将会弹出一个对话框,在其上显示执行的动作内容、对象名以及参数内容。
打开VS.NET,按下面步骤工作:
1.新建一个空项目(项目名:ExtenShell)。
2.添加一个新类(类名:ExtenShell.cs)。
3.将下面代码作为ExtenShell.cs的内容。
/* ExtenShell.cs */
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
[assembly: AssemblyKeyFile(@"..\..\ESKey.snk")] /*密钥文件*/
namespace ShellExtension
{
//接口声明。
[ComImport,InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214FB-0000-0000-C000-000000000046")]
/* Guid("000214FB-0000-0000-C00