分享
 
 
 

用C#创建SHELL扩展

王朝c#·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

安徽省民航局周毅(longsoft@ah163.com)

一、前言

.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-C000-000000000046") 相当于shlguid.h中的DEFINE_SHLGUID(IID_IShellExecuteHookW, 0x000214FBL, 0, 0); */

public interface IShellExecuteHook

{

[PreserveSig()] /* 允许返回值为COM HRESULT */

int Execute(SHELLEXECUTEINFO sei);

}

//结构声明。

[StructLayout(LayoutKind.Sequential)]

public class SHELLEXECUTEINFO

{

public int cbSize;

public int fMask;

public int hwnd;

[MarshalAs(UnmanagedType.LPWStr)]

public string lpVerb;

[MarshalAs(UnmanagedType.LPWStr)]

public string lpFile;

[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;

}

[Guid("027F9368-A83E-42cc-85B2-1DC5E23C4608"), ComVisible(true)]

/* 用Guid生成工具创建一个新的GUID作为类对象的GUID标识。 */

public class ExtenShell : IShellExecuteHook

{

private int S_OK=0;

private int S_FALSE=1;

public int Execute(SHELLEXECUTEINFO sei)

{

try

{

MessageBox.Show(null, "[ Verb ]: " + sei.lpVerb + "\n[ File ]: " + sei.lpFile + "\n[ Parameters ]:" + sei.lpParameters + "\n[ Directory ]:" + sei.lpDirectory , "ShellExtensionHook",MessageBoxButtons.OK, MessageBoxIcon.Information);

}

catch(Exception e)

{

Console.Error.WriteLine("Unknown exception : " + e.ToString());

}

return S_FALSE;

//如果返回值为S_OK则SHELL将停止对Shell对象的以后的所有动作。

}

}

}

4. 在命令行上运行:sn -k ESKey.snk ( sn.exe在 C:\Programe Files\Microsoft.NET\FrameworkSDK\Bin下可以找到 ),将ESKey.snk添加到项目中。

5. 打开<项目> --> <属性>,将输出类型改成类库。

6. 编译完成。

7. 因.NET可控代码生成的COM组件注册后要到assembly目录中寻找实体执行,故应将编译好的ExtenShell.dll文件拷贝到c:\Winnt\assembly目录中。

8. 注册组件。在命令行上运行:regasm {项目路径}\Bin\Debug\ExtenShell.dll。( regasm.exe在c:\Winnt\Microsoft.NET\Framework\v1.0.2914下可以找到)

9.最后,在HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks项下新建一个字符串值,其名为{027F9368-A83E-42cc-85B2-1DC5E23C4608},值可以为空也可以加入一串描述性文字。

五、结 束

这是一个简单的Shell扩展的例子,虽然不是一个完整的应用,但是作者想通过此实例向读者介绍Shell扩展和.NET平台下的COM组件开发技术,希望它能起抛砖引玉的作用。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有