热门文章 | 热门软件| 热门源码 | 热门电影 | 知识库 | 联系我们
软件 源码 教程 影视 健康 招聘
  HTML | JavaScript | ASP | PHP | JSP | NET | VB | VC | VF | Windows | Linux | Mysql | Mssql | Oracle | Struts 
当前位置: 创世纪计算机资源网 -> 文章频道 ->dephi 
站内搜索:
Delphi深度探索之外壳执行操作记录器(2)
作者:哈巴狗的小窝 来源:希赛网 整理日期:2007-4-18

  Windows外壳大量调用ShellExecute和ShellExecuteEx函数来执行几乎是所有的资源管理器的操作,比如双击目录、浏览文件夹内容、打印编辑文档、查看文件属性、选择文档的上下文相关菜单等等。此外,开始菜单的运行对话框和DOS方式下的Start.exe也使用ShellExecuteEx函数来执行程序。简单地说几乎用户的所有外壳操作都可以被扩展截获,包括其他应用程序对ShellExecute和ShellExecteEx的调用。

  注册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\CurrentVersi
on\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(Shell
ExecuteHooksKey), 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页。
[1]  [2]  
相关文章
暂无