注册ShellExecuteHook
要想使COM对象被外壳加载,需要在注册表中注册一些信息。在下面这个子键中添加COM类的GUID及描述字符串后就可以了(描述字符串可以不赋值,但不妨给一个以便于识别)。
HKEY_LOCAL_MACHINE SOFTWARE Microsoft Windows CurrentVersion Explorer ShellExecuteHooks {CLSID}= '描述字符串' |
修改注册表可以通过重载COM的类工厂的UpdateRegistry方法来实现。代码示意如下:
implementation uses ComServ, SysUtils; resourcestring sCreateRegKeyError = '创建注册表项失败'; type TShellExComObjectFactory = class(TComObjectFactory) public procedure UpdateRegistry(Register: Boolean); override; end; { TShellExComObjectFactory } procedure TShellExComObjectFactory.UpdateRegistry(Register: Boolean); const hellExecuteHooksKey='SOFTWARE/Microsoft/Windows/CurrentVersion/Explorer/ShellExecuteHooks'; var Handle: HKey; Status, Disposition: Integer; ClassID: String; begin ClassID := GUIDToString(Class_TShellExecuteHook); if Register then begin Status := RegCreateKeyEx(HKEY_LOCAL_MACHINE, PChar( ShellExecuteHooksKey), 0, '',REG_OPTION_NON_VOLATILE, KEY_READ or KEY_WRITE, nil, Handle, @Disposition); if Status = 0 then begin Status := RegSetValueEx(Handle, PChar(ClassID), 0, REG_SZ, PChar(Description), Length(Description) + 1); RegCloseKey(Handle); end; end else begin Status := RegOpenKeyEx(HKEY_LOCAL_MACHINE, PChar(ShellExecuteHooksKey), 0, KEY_READ or KEY_WRITE, Handle); if Status = 0 then begin Status := RegDeleteValue(Handle, PChar(ClassID)); RegCloseKey(Handle); end; end; if Status <> 0 then raise EOleError.Create(sCreateRegKeyError); inherited UpdateRegistry(Register); end; initialization TShellExComObjectFactory.Create( ComServer, TTShellExecuteHook, Class_TShellExecuteHook,'TShellExecuteHook', 'ShellExecute hook sample', ciMultiInstance, tmApartment); end. |
如果系统中有多个ShellExecuteHook的话,外壳会按照ShellExecuteHook的安装顺序进行调用,如果要想使某个外壳扩展优先运行,可先删除其他扩展然后添加优先扩展,原来的扩展依次放在后面,不过这样做也可能意义不大,因为别人也会这么干。最后,程序运行的结果。
记住ShellExecuteHook并不是一个完善的用于监视系统运行的扩展。它只能监视ShellExecute和ShellExecuteEx的运行,它不能保证记录系统所有的行为。特别是很多情况下外壳并不使用ShellExecute来进行一些常用的操作,比如我们在资源管理器中选择一个文件,然后调用右键菜单的属性命令后,记录器没有记录这个动作,但如果直接调用ShellExecute(如下示)的话,ShellExecuteHook却会正确执行。
ShellExecute(nil, 'properties', 'foo.txt',nil,nil,SW_SHOW); |
这说明外壳并不使用ShellExecute函数显示属性对话框。总之一定要谨慎使用这项技术,确保它确实符合工作的需求。 
2/2 首页 上一页 1 2 |