21 个解决方案
#1
MARK
#2
使用RegNotifyChangeKeyValue函数,具体使用说明看一看msdn吧。
#3
waiting for other answers……
#4
读写注册表时应该有相应消息的,截获一下
#5
RegNotifyChangeKeyValue?查找……………………
#6
学习学习……
#7
关注
#8
提前一下
#9
关于“RegNotifyChangeKeyValue”到底是什麽?
和如何用???
和如何用???
#10
监视程序的编制
(哈尔滨 赵晓辉)
监视程序,这个名字听起来似乎很陌生。它的用途主要是在后台监视系统中
关键信息的改变,比如注册表
的改变及硬盘上由于文件操作引起的改变等等。也许有人会问了,编制这样的程
序有什么价值呢?硬盘上文件
改变了,我只要在资源管理器里点一点不就全都清楚了吗?问题当然不会这样简
单,如今大家的硬盘都已经用
G来做单位了,一块4.3G的硬盘中,大大小小的文件全都加起来也会有若干万(
相信新购机的朋友会考虑IBM10
.1G的大硬盘,那文件数量将更加不可想象),更何况那些看不见的系统文件和
隐藏文件了。再加上注册表,那
其中的条条款款,数量也丝毫不逊于硬盘上的文件。要想随时知道自己机器是否
有所变动,绝对不是一件很轻
松的事。而监视程序就可以随时检测到这些变化,帮助我们了解这些情况。
当然这只是监视程序的一部分作用,它最大的作用就是可以记录下某个软件
安装前后系统的改变,从而为
卸载这个软件提供重要的依据。虽然Windows自带了一个Uninstall Shield,但
是它似乎并不能很干净地把原来的软件卸掉,每次卸载总会留下一些讨厌的残渣
,致使系统中的垃圾信息不断增长,我们的硬盘空间也总是莫名其妙地越用越少
。因此,一些号称能够完全卸载软件的专用卸载工具应运而生。在这其中,有一
些就运用了监视系统的技术,比如Uninstaller Manager和RegMonitor。
下面我们开始讨论如何编程实现这一监视功能。首先介绍几个重要的api函
数:
FindFirstChangeNotification( );
FindNextChangeNotification( );
WaitForSingleObject( );
其中FindFirstChangeNotification(lpzpath,fwatchsubtree,
fdwfilter)中的lpzpath表示要监视的路径名,fwatchsubtree判断是否查看子
目录,fdwfilter为要监视的事件,函数执行成功后返回一个句柄。
参数fdwfilter取值及其含义如下:
FILE_NOTIFY_CHANGE_FILE_NAME
查看指定目录下任何文件名的改变
FILE_NOTIFY_CHANGE_DIR_NAME
查看指定目录下任何目录名的改变
FILE_NOTIFY_CHANGE_SIZE
查看指定目录下文件大小的改变
FILE_NOTIFY_CHANGE_ATTRIBUTES
查看指定目录下文件属性的改变
FindNextChangeNotification(hchange),hchan
ge为FindFirstChangenNotification返回的句柄,其作用是请求系统在下次
检测到相应改变时发出改变通
知消息句柄。当函数成功返回后,应用程序可通过WaitForMultipleObjects或
WaitfForSingleObject来等待发
生改变的通知。WaitForSingleObject(hchange,dwmilliseconds)中hchange
为FindFirstChangeNotificati
on 返回的句柄,dwmilliseconds为等待时间值,指定等待完成需要的时间,单
位为毫秒。该值为-1时表示时间无限长。最好在结束监视程序之前先用
FindCloseChangeNotification(hchange)
来关闭句柄。
下面给出一个简单的实例,其功能就是监视c:\pwin98目录下是否有文件发
生变化。一旦有重命名、创建
或删除情况发生时,通过Edit控件给出提示。
//
----------------
。nclude
。ragma hdrstop
。nclude “Unit1.h”
FILE_NOTIFY_CHANGE_ATTRIBUTES
查看指定目录下文件属性的改变
FindNextChangeNotification(hchange),hchan
ge为FindFirstChangenNotification返回的句柄,其作用是请求系统在下次
检测到相应改变时发出改变通
知消息句柄。当函数成功返回后,应用程序可通过WaitForMultipleObjects或
WaitfForSingleObject来等待发
生改变的通知。WaitForSingleObject(hchange,dwmilliseconds)中hchange
为FindFirstChangeNotificati
on 返回的句柄,dwmilliseconds为等待时间值,指定等待完成需要的时间,单
位为毫秒。该值为-1时表示时间无限长。最好在结束监视程序之前先用
FindCloseChangeNotification(hchange)
来关闭句柄。
下面给出一个简单的实例,其功能就是监视c:\pwin98目录下是否有文件发
生变化。一旦有重命名、创建
或删除情况发生时,通过Edit控件给出提示。
//
----------------
。nclude
。ragma hdrstop
。nclude “Unit1.h”
//----------------
。ragma package(smart_init)
。ragma resource “*.dfm”
TForm1 *Form1;
//-----------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//-------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
DWORD dwWaitStatus;
HANDLE dwChangeHandle; //返回通知的句柄
dwChangeHandle=FindFirstChangeNotification(
“C:\\PWIN98”,false,FILE_NOTIFY_CHANGE_FILE_NAME); //设置返回通知
的句柄
if(dwChangeHandle==INVALID_HANDLE_VALUE)
//判断是否设置成功
ExitProcess(GetLastError( ));
while(true){ //设置循环,监视是否有
dwWaitStatus=WaitForSingleObject(dwChangeHandle,-1); //通知返回
switch(dwWaitStatus){
case 0:
Edit1->Text=“Something Changed”; //给出提示
FindCloseChangeNotification(dwcChangeHandle); //关闭句柄
exit(EXIT_SUCCESS); //退出程序
default:
ExitProcess(GetLastError( ));
}
}
}
程序在C++Builder4/PWin98下通过,由于C++Builder语言很标准,所
以很容易扩展到其他编程语言
环境中去。
此例说明如何监视硬盘中文件变化,对于注册表,则有函数
RegNotifyChangeKeyValue( )可以实现类似
功能,这里暂省略之。
怎么样,看过本文,是否对Uninstaller Manager和Reg Monitor这样的软
件有了更深入的了解。在Wind
ows编程中,有些API函数起到了重要的作用,可以让程序实现很多高级的功能。
因为API函数是按照C语言语法
给出的,所以C++Builder有着得天独厚的优势,对API函数和宏支持得非常好
。不好,怎么跑题了?
』广 着干吗,难道你还不想赶快动?编制一个自己的Uninstaller Manager
吗?
(哈尔滨 赵晓辉)
监视程序,这个名字听起来似乎很陌生。它的用途主要是在后台监视系统中
关键信息的改变,比如注册表
的改变及硬盘上由于文件操作引起的改变等等。也许有人会问了,编制这样的程
序有什么价值呢?硬盘上文件
改变了,我只要在资源管理器里点一点不就全都清楚了吗?问题当然不会这样简
单,如今大家的硬盘都已经用
G来做单位了,一块4.3G的硬盘中,大大小小的文件全都加起来也会有若干万(
相信新购机的朋友会考虑IBM10
.1G的大硬盘,那文件数量将更加不可想象),更何况那些看不见的系统文件和
隐藏文件了。再加上注册表,那
其中的条条款款,数量也丝毫不逊于硬盘上的文件。要想随时知道自己机器是否
有所变动,绝对不是一件很轻
松的事。而监视程序就可以随时检测到这些变化,帮助我们了解这些情况。
当然这只是监视程序的一部分作用,它最大的作用就是可以记录下某个软件
安装前后系统的改变,从而为
卸载这个软件提供重要的依据。虽然Windows自带了一个Uninstall Shield,但
是它似乎并不能很干净地把原来的软件卸掉,每次卸载总会留下一些讨厌的残渣
,致使系统中的垃圾信息不断增长,我们的硬盘空间也总是莫名其妙地越用越少
。因此,一些号称能够完全卸载软件的专用卸载工具应运而生。在这其中,有一
些就运用了监视系统的技术,比如Uninstaller Manager和RegMonitor。
下面我们开始讨论如何编程实现这一监视功能。首先介绍几个重要的api函
数:
FindFirstChangeNotification( );
FindNextChangeNotification( );
WaitForSingleObject( );
其中FindFirstChangeNotification(lpzpath,fwatchsubtree,
fdwfilter)中的lpzpath表示要监视的路径名,fwatchsubtree判断是否查看子
目录,fdwfilter为要监视的事件,函数执行成功后返回一个句柄。
参数fdwfilter取值及其含义如下:
FILE_NOTIFY_CHANGE_FILE_NAME
查看指定目录下任何文件名的改变
FILE_NOTIFY_CHANGE_DIR_NAME
查看指定目录下任何目录名的改变
FILE_NOTIFY_CHANGE_SIZE
查看指定目录下文件大小的改变
FILE_NOTIFY_CHANGE_ATTRIBUTES
查看指定目录下文件属性的改变
FindNextChangeNotification(hchange),hchan
ge为FindFirstChangenNotification返回的句柄,其作用是请求系统在下次
检测到相应改变时发出改变通
知消息句柄。当函数成功返回后,应用程序可通过WaitForMultipleObjects或
WaitfForSingleObject来等待发
生改变的通知。WaitForSingleObject(hchange,dwmilliseconds)中hchange
为FindFirstChangeNotificati
on 返回的句柄,dwmilliseconds为等待时间值,指定等待完成需要的时间,单
位为毫秒。该值为-1时表示时间无限长。最好在结束监视程序之前先用
FindCloseChangeNotification(hchange)
来关闭句柄。
下面给出一个简单的实例,其功能就是监视c:\pwin98目录下是否有文件发
生变化。一旦有重命名、创建
或删除情况发生时,通过Edit控件给出提示。
//
----------------
。nclude
。ragma hdrstop
。nclude “Unit1.h”
FILE_NOTIFY_CHANGE_ATTRIBUTES
查看指定目录下文件属性的改变
FindNextChangeNotification(hchange),hchan
ge为FindFirstChangenNotification返回的句柄,其作用是请求系统在下次
检测到相应改变时发出改变通
知消息句柄。当函数成功返回后,应用程序可通过WaitForMultipleObjects或
WaitfForSingleObject来等待发
生改变的通知。WaitForSingleObject(hchange,dwmilliseconds)中hchange
为FindFirstChangeNotificati
on 返回的句柄,dwmilliseconds为等待时间值,指定等待完成需要的时间,单
位为毫秒。该值为-1时表示时间无限长。最好在结束监视程序之前先用
FindCloseChangeNotification(hchange)
来关闭句柄。
下面给出一个简单的实例,其功能就是监视c:\pwin98目录下是否有文件发
生变化。一旦有重命名、创建
或删除情况发生时,通过Edit控件给出提示。
//
----------------
。nclude
。ragma hdrstop
。nclude “Unit1.h”
//----------------
。ragma package(smart_init)
。ragma resource “*.dfm”
TForm1 *Form1;
//-----------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//-------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
DWORD dwWaitStatus;
HANDLE dwChangeHandle; //返回通知的句柄
dwChangeHandle=FindFirstChangeNotification(
“C:\\PWIN98”,false,FILE_NOTIFY_CHANGE_FILE_NAME); //设置返回通知
的句柄
if(dwChangeHandle==INVALID_HANDLE_VALUE)
//判断是否设置成功
ExitProcess(GetLastError( ));
while(true){ //设置循环,监视是否有
dwWaitStatus=WaitForSingleObject(dwChangeHandle,-1); //通知返回
switch(dwWaitStatus){
case 0:
Edit1->Text=“Something Changed”; //给出提示
FindCloseChangeNotification(dwcChangeHandle); //关闭句柄
exit(EXIT_SUCCESS); //退出程序
default:
ExitProcess(GetLastError( ));
}
}
}
程序在C++Builder4/PWin98下通过,由于C++Builder语言很标准,所
以很容易扩展到其他编程语言
环境中去。
此例说明如何监视硬盘中文件变化,对于注册表,则有函数
RegNotifyChangeKeyValue( )可以实现类似
功能,这里暂省略之。
怎么样,看过本文,是否对Uninstaller Manager和Reg Monitor这样的软
件有了更深入的了解。在Wind
ows编程中,有些API函数起到了重要的作用,可以让程序实现很多高级的功能。
因为API函数是按照C语言语法
给出的,所以C++Builder有着得天独厚的优势,对API函数和宏支持得非常好
。不好,怎么跑题了?
』广 着干吗,难道你还不想赶快动?编制一个自己的Uninstaller Manager
吗?
#11
我记得有消息可以捕获吧
#12
那个什么RegNotify什么的函数是不行的,她只能告诉你有改动,但不会告诉你具体的改动地方。我试过的。
#13
呵呵,也是啊。我这几天正在想着呢……
只是说有改动的话仅仅是编程目的中的方向性指标,但是我要的是具体的改动。不知道NowCan(能量、激情、雨水、彩虹——雷雨云)兄能否解决这个问题呢?
只是说有改动的话仅仅是编程目的中的方向性指标,但是我要的是具体的改动。不知道NowCan(能量、激情、雨水、彩虹——雷雨云)兄能否解决这个问题呢?
#14
再次关注
#15
我的收藏:
unit UMesApi;
interface
uses SysUtils, Classes;
function ToUnicode(str:string;dest:PWideChar):integer;
function SendMsg(Toh,From,Msg:string):integer;
function NetMessageBufferSend(servername:PWideChar;
MsgName:PWideChar;
FromName:PWideChar;
Buf: PWideChar;
var BufLen:integer):integer;cdecl;
implementation
function ToUnicode(str:string;dest:PWideChar):integer;
var
len:integer;
begin
len:=Length(str)*2;
//len:=length(dest^);
StringToWideChar(str,dest,len);
Result:=len;
end;
function NetMessageBufferSend; external 'netapi32.dll' name 'NetMessageBufferSend';
function SendMsg(Toh,From,Msg:string):integer;
var
ToName :array [0..64] of WideChar;
WMsgText:array [0..1000] of WideChar;
MsgLen,i:integer;
begin
for i := 0 to 64 do ToName[i] := #0;
ToUnicode(Toh,ToName);
for i := 0 to 1000 do WMsgText[i] := #0;
MsgLen:=ToUnicode(Msg,WMsgText);
Result:=NetMessageBufferSend(nil,ToName,nil,@WMsgText,MsgLen);
end;
end.
unit UMesApi;
interface
uses SysUtils, Classes;
function ToUnicode(str:string;dest:PWideChar):integer;
function SendMsg(Toh,From,Msg:string):integer;
function NetMessageBufferSend(servername:PWideChar;
MsgName:PWideChar;
FromName:PWideChar;
Buf: PWideChar;
var BufLen:integer):integer;cdecl;
implementation
function ToUnicode(str:string;dest:PWideChar):integer;
var
len:integer;
begin
len:=Length(str)*2;
//len:=length(dest^);
StringToWideChar(str,dest,len);
Result:=len;
end;
function NetMessageBufferSend; external 'netapi32.dll' name 'NetMessageBufferSend';
function SendMsg(Toh,From,Msg:string):integer;
var
ToName :array [0..64] of WideChar;
WMsgText:array [0..1000] of WideChar;
MsgLen,i:integer;
begin
for i := 0 to 64 do ToName[i] := #0;
ToUnicode(Toh,ToName);
for i := 0 to 1000 do WMsgText[i] := #0;
MsgLen:=ToUnicode(Msg,WMsgText);
Result:=NetMessageBufferSend(nil,ToName,nil,@WMsgText,MsgLen);
end;
end.
#16
unit UMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Registry,IniFiles, ExtCtrls;
type
TFormMain = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
published
procedure LogMsg(msg:string);
private
{ Private declarations }
Reg:TRegistry;
IniFile:TIniFile;
LogFile:TStringList;
LogFileName:String;
RegKeys:TStringList;
CurrUser,HostName:String;
public
{ Public declarations }
end;
var
FormMain: TFormMain;
implementation
uses UMesApi;
{$R *.DFM}
procedure TFormMain.FormCreate(Sender: TObject);
var IniName,value:string;
i:integer;
pstr:pchar;
n:Cardinal;
begin
try
n:=64;
pstr:=StrAlloc(n);
GetUserName(pstr,n);
CurrUser:=StrPas(pstr);
GetComputerName(pstr,n);
HostName:=StrPas(pstr);
StrDispose(pstr);
self.Reg:=TRegistry.Create;
with self.Reg do
begin
RootKey:=HKEY_Local_Machine;
Access:=KEY_EXECUTE;
if OpenKey('Software\Microsoft\Windows\CurrentVersion\Run',false) then
begin
RegKeys:=TStringList.Create;
GetValueNames(RegKeys);
for i:=0 to Regkeys.Count-1 do
if (GetDataType(RegKeys.Strings[i])=rdString)
or (GetDataType(RegKeys.Strings[i])=rdExpandString)
then begin
value:=ReadString(RegKeys.Strings[i]);
if value=Application.ExeName then Break;
end;
if value<>Application.ExeName then
begin //if not set run with widows ,then set it
WriteString('PiRegWatch',Application.ExeName);
end;
end
else
begin
Messagebox(0,'Can"t Open RegKey','error',mb_ok);
Application.Terminate;
end;
end ;
IniName:=Application.ExeName;
IniName:=Copy(IniName,1,Length(IniName)-4)+'.ini';
self.IniFile:=TIniFile.Create(IniName);
self.LogFile:=TStringList.Create;
self.LogFileName:=Copy(IniName,1,Length(IniName)-4)+'.log';
if FileExists(LogFileName) then self.LogFile.LoadFromFile(self.LogFileName);
if not self.IniFile.SectionExists('RunList') then
begin
for i:=0 to Regkeys.Count-1 do
if (self.Reg.GetDataType(RegKeys.Strings[i])=rdString)
or (self.Reg.GetDataType(RegKeys.Strings[i])=rdExpandString)
then begin
value:=self.Reg.ReadString(RegKeys.Strings[i]);
self.IniFile.WriteString('RunList',RegKeys.Strings[i],value);
end;
self.IniFile.Free; //Force INI file save
self.IniFile:=TIniFile.Create(IniName);
end;
except
Messagebox(0,'App Terminate','error',mb_ok);
Application.Terminate;
end;
end;
procedure TFormMain.Timer1Timer(Sender: TObject);
var i:integer;
RegVal,IniVal:string;
begin
self.Timer1.Enabled:=False;
self.Reg.GetValueNames(RegKeys);
for i:=0 to RegKeys.Count-1 do //Check to New Added items
if (self.Reg.GetDataType(RegKeys.Strings[i])=rdString)
or (self.Reg.GetDataType(RegKeys.Strings[i])=rdExpandString)
then begin
RegVal:=self.Reg.ReadString(RegKeys.Strings[i]);
IniVal:=self.IniFile.ReadString('RunList',RegKeys.Strings[i],'');
if RegVal<>IniVal then
begin
self.LogMsg('Item Add:'+RegKeys.Strings[i]+'='+RegVal);
self.IniFile.WriteString('RunList',RegKeys.Strings[i],RegVal);
try
SendMsg('ABC','','注册表被改变:新增项目'+RegKeys.Strings[i]+'='+RegVal);
finally
end;
end;
end;
self.IniFile.ReadSection('RunList',RegKeys);
for i:=0 to RegKeys.Count-1 do //Check to Deleted Items
begin
IniVal:=self.IniFile.ReadString('RunList',RegKeys.Strings[i],'');
if self.Reg.ValueExists(RegKeys.Strings[i]) and
((self.Reg.GetDataType(RegKeys.Strings[i])=rdString)
or (self.Reg.GetDataType(RegKeys.Strings[i])=rdExpandString) )
then
RegVal:=self.Reg.ReadString(RegKeys.Strings[i])
else
RegVal:='';
if (IniVal<>'') and (RegVal='') then
begin
self.LogMsg('Item Del:'+RegKeys.Strings[i]+'='+IniVal);
self.IniFile.DeleteKey('RunList',RegKeys.Strings[i]);
try
SendMsg('ABC','','注册表被改变:项目删除'+RegKeys.Strings[i]+'='+IniVal);
finally
end;
end;
end;
self.IniFile.UpdateFile;
self.Timer1.Enabled:=True;
end;
procedure TFormMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if Assigned(self.Reg) then self.Reg.Free;
if Assigned(self.IniFile) then self.IniFile.Free;
if Assigned(self.LogFile) then self.LogFile.Free;
if Assigned(self.RegKeys) then self.RegKeys.Free;
end;
procedure TFormMain.LogMsg(msg:string);
var str:string;
y,m,d:word;
begin
str:=Format('[%s] %s on %s ,%s',[DatetimeToStr(Now),self.CurrUser,self.HostName,msg]);
self.LogFile.Add(str);
if self.LogFile.Count<=100 then
self.LogFile.SaveToFile(self.LogFileName)
else begin
DecodeDate(Now,y,m,d);
str:=ExtractFilePath(self.LogFileName)+Format('%2d%2d%2d',[y,m,d])+'.log';
self.LogFile.SaveToFile(str);
self.LogFile.Clear;
self.LogFile.SaveToFile(self.LogFileName);
end;
end;
end.
有谁把他改成BCB,我看见Begin End就麻.
我下大家满足了吧!
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Registry,IniFiles, ExtCtrls;
type
TFormMain = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
published
procedure LogMsg(msg:string);
private
{ Private declarations }
Reg:TRegistry;
IniFile:TIniFile;
LogFile:TStringList;
LogFileName:String;
RegKeys:TStringList;
CurrUser,HostName:String;
public
{ Public declarations }
end;
var
FormMain: TFormMain;
implementation
uses UMesApi;
{$R *.DFM}
procedure TFormMain.FormCreate(Sender: TObject);
var IniName,value:string;
i:integer;
pstr:pchar;
n:Cardinal;
begin
try
n:=64;
pstr:=StrAlloc(n);
GetUserName(pstr,n);
CurrUser:=StrPas(pstr);
GetComputerName(pstr,n);
HostName:=StrPas(pstr);
StrDispose(pstr);
self.Reg:=TRegistry.Create;
with self.Reg do
begin
RootKey:=HKEY_Local_Machine;
Access:=KEY_EXECUTE;
if OpenKey('Software\Microsoft\Windows\CurrentVersion\Run',false) then
begin
RegKeys:=TStringList.Create;
GetValueNames(RegKeys);
for i:=0 to Regkeys.Count-1 do
if (GetDataType(RegKeys.Strings[i])=rdString)
or (GetDataType(RegKeys.Strings[i])=rdExpandString)
then begin
value:=ReadString(RegKeys.Strings[i]);
if value=Application.ExeName then Break;
end;
if value<>Application.ExeName then
begin //if not set run with widows ,then set it
WriteString('PiRegWatch',Application.ExeName);
end;
end
else
begin
Messagebox(0,'Can"t Open RegKey','error',mb_ok);
Application.Terminate;
end;
end ;
IniName:=Application.ExeName;
IniName:=Copy(IniName,1,Length(IniName)-4)+'.ini';
self.IniFile:=TIniFile.Create(IniName);
self.LogFile:=TStringList.Create;
self.LogFileName:=Copy(IniName,1,Length(IniName)-4)+'.log';
if FileExists(LogFileName) then self.LogFile.LoadFromFile(self.LogFileName);
if not self.IniFile.SectionExists('RunList') then
begin
for i:=0 to Regkeys.Count-1 do
if (self.Reg.GetDataType(RegKeys.Strings[i])=rdString)
or (self.Reg.GetDataType(RegKeys.Strings[i])=rdExpandString)
then begin
value:=self.Reg.ReadString(RegKeys.Strings[i]);
self.IniFile.WriteString('RunList',RegKeys.Strings[i],value);
end;
self.IniFile.Free; //Force INI file save
self.IniFile:=TIniFile.Create(IniName);
end;
except
Messagebox(0,'App Terminate','error',mb_ok);
Application.Terminate;
end;
end;
procedure TFormMain.Timer1Timer(Sender: TObject);
var i:integer;
RegVal,IniVal:string;
begin
self.Timer1.Enabled:=False;
self.Reg.GetValueNames(RegKeys);
for i:=0 to RegKeys.Count-1 do //Check to New Added items
if (self.Reg.GetDataType(RegKeys.Strings[i])=rdString)
or (self.Reg.GetDataType(RegKeys.Strings[i])=rdExpandString)
then begin
RegVal:=self.Reg.ReadString(RegKeys.Strings[i]);
IniVal:=self.IniFile.ReadString('RunList',RegKeys.Strings[i],'');
if RegVal<>IniVal then
begin
self.LogMsg('Item Add:'+RegKeys.Strings[i]+'='+RegVal);
self.IniFile.WriteString('RunList',RegKeys.Strings[i],RegVal);
try
SendMsg('ABC','','注册表被改变:新增项目'+RegKeys.Strings[i]+'='+RegVal);
finally
end;
end;
end;
self.IniFile.ReadSection('RunList',RegKeys);
for i:=0 to RegKeys.Count-1 do //Check to Deleted Items
begin
IniVal:=self.IniFile.ReadString('RunList',RegKeys.Strings[i],'');
if self.Reg.ValueExists(RegKeys.Strings[i]) and
((self.Reg.GetDataType(RegKeys.Strings[i])=rdString)
or (self.Reg.GetDataType(RegKeys.Strings[i])=rdExpandString) )
then
RegVal:=self.Reg.ReadString(RegKeys.Strings[i])
else
RegVal:='';
if (IniVal<>'') and (RegVal='') then
begin
self.LogMsg('Item Del:'+RegKeys.Strings[i]+'='+IniVal);
self.IniFile.DeleteKey('RunList',RegKeys.Strings[i]);
try
SendMsg('ABC','','注册表被改变:项目删除'+RegKeys.Strings[i]+'='+IniVal);
finally
end;
end;
end;
self.IniFile.UpdateFile;
self.Timer1.Enabled:=True;
end;
procedure TFormMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if Assigned(self.Reg) then self.Reg.Free;
if Assigned(self.IniFile) then self.IniFile.Free;
if Assigned(self.LogFile) then self.LogFile.Free;
if Assigned(self.RegKeys) then self.RegKeys.Free;
end;
procedure TFormMain.LogMsg(msg:string);
var str:string;
y,m,d:word;
begin
str:=Format('[%s] %s on %s ,%s',[DatetimeToStr(Now),self.CurrUser,self.HostName,msg]);
self.LogFile.Add(str);
if self.LogFile.Count<=100 then
self.LogFile.SaveToFile(self.LogFileName)
else begin
DecodeDate(Now,y,m,d);
str:=ExtractFilePath(self.LogFileName)+Format('%2d%2d%2d',[y,m,d])+'.log';
self.LogFile.SaveToFile(str);
self.LogFile.Clear;
self.LogFile.SaveToFile(self.LogFileName);
end;
end;
end.
有谁把他改成BCB,我看见Begin End就麻.
我下大家满足了吧!
#17
这个问题?
禁止注册表的改动,就可以!
禁止注册表的改动,就可以!
#18
感谢Bird1945(老唬是女人!),呵呵。去试试看先……
To dycdyc123(重出江湖),我没有说要禁止他阿,我只要看他改动哪里就可以了。哦,还有,恕我肤浅,怎样禁止注册表的改动?我不知道阿。
To dycdyc123(重出江湖),我没有说要禁止他阿,我只要看他改动哪里就可以了。哦,还有,恕我肤浅,怎样禁止注册表的改动?我不知道阿。
#19
就是让在local maching的什么里面加一个disabled
你可以去查一下
一般的黑客网站都有
你可以去查一下
一般的黑客网站都有
#20
Bird1945的代码好像有点问题
因为在formcreate时候一直监测文件夹]的变动
是不是会造成form显示不出来阿
我只是猜测阿
因为在formcreate时候一直监测文件夹]的变动
是不是会造成form显示不出来阿
我只是猜测阿
#21
没错,Bird1945的代码大有问题!
不知他自己有无调试过?
直接从网上拷过来的吧?
不知他自己有无调试过?
直接从网上拷过来的吧?
#1
MARK
#2
使用RegNotifyChangeKeyValue函数,具体使用说明看一看msdn吧。
#3
waiting for other answers……
#4
读写注册表时应该有相应消息的,截获一下
#5
RegNotifyChangeKeyValue?查找……………………
#6
学习学习……
#7
关注
#8
提前一下
#9
关于“RegNotifyChangeKeyValue”到底是什麽?
和如何用???
和如何用???
#10
监视程序的编制
(哈尔滨 赵晓辉)
监视程序,这个名字听起来似乎很陌生。它的用途主要是在后台监视系统中
关键信息的改变,比如注册表
的改变及硬盘上由于文件操作引起的改变等等。也许有人会问了,编制这样的程
序有什么价值呢?硬盘上文件
改变了,我只要在资源管理器里点一点不就全都清楚了吗?问题当然不会这样简
单,如今大家的硬盘都已经用
G来做单位了,一块4.3G的硬盘中,大大小小的文件全都加起来也会有若干万(
相信新购机的朋友会考虑IBM10
.1G的大硬盘,那文件数量将更加不可想象),更何况那些看不见的系统文件和
隐藏文件了。再加上注册表,那
其中的条条款款,数量也丝毫不逊于硬盘上的文件。要想随时知道自己机器是否
有所变动,绝对不是一件很轻
松的事。而监视程序就可以随时检测到这些变化,帮助我们了解这些情况。
当然这只是监视程序的一部分作用,它最大的作用就是可以记录下某个软件
安装前后系统的改变,从而为
卸载这个软件提供重要的依据。虽然Windows自带了一个Uninstall Shield,但
是它似乎并不能很干净地把原来的软件卸掉,每次卸载总会留下一些讨厌的残渣
,致使系统中的垃圾信息不断增长,我们的硬盘空间也总是莫名其妙地越用越少
。因此,一些号称能够完全卸载软件的专用卸载工具应运而生。在这其中,有一
些就运用了监视系统的技术,比如Uninstaller Manager和RegMonitor。
下面我们开始讨论如何编程实现这一监视功能。首先介绍几个重要的api函
数:
FindFirstChangeNotification( );
FindNextChangeNotification( );
WaitForSingleObject( );
其中FindFirstChangeNotification(lpzpath,fwatchsubtree,
fdwfilter)中的lpzpath表示要监视的路径名,fwatchsubtree判断是否查看子
目录,fdwfilter为要监视的事件,函数执行成功后返回一个句柄。
参数fdwfilter取值及其含义如下:
FILE_NOTIFY_CHANGE_FILE_NAME
查看指定目录下任何文件名的改变
FILE_NOTIFY_CHANGE_DIR_NAME
查看指定目录下任何目录名的改变
FILE_NOTIFY_CHANGE_SIZE
查看指定目录下文件大小的改变
FILE_NOTIFY_CHANGE_ATTRIBUTES
查看指定目录下文件属性的改变
FindNextChangeNotification(hchange),hchan
ge为FindFirstChangenNotification返回的句柄,其作用是请求系统在下次
检测到相应改变时发出改变通
知消息句柄。当函数成功返回后,应用程序可通过WaitForMultipleObjects或
WaitfForSingleObject来等待发
生改变的通知。WaitForSingleObject(hchange,dwmilliseconds)中hchange
为FindFirstChangeNotificati
on 返回的句柄,dwmilliseconds为等待时间值,指定等待完成需要的时间,单
位为毫秒。该值为-1时表示时间无限长。最好在结束监视程序之前先用
FindCloseChangeNotification(hchange)
来关闭句柄。
下面给出一个简单的实例,其功能就是监视c:\pwin98目录下是否有文件发
生变化。一旦有重命名、创建
或删除情况发生时,通过Edit控件给出提示。
//
----------------
。nclude
。ragma hdrstop
。nclude “Unit1.h”
FILE_NOTIFY_CHANGE_ATTRIBUTES
查看指定目录下文件属性的改变
FindNextChangeNotification(hchange),hchan
ge为FindFirstChangenNotification返回的句柄,其作用是请求系统在下次
检测到相应改变时发出改变通
知消息句柄。当函数成功返回后,应用程序可通过WaitForMultipleObjects或
WaitfForSingleObject来等待发
生改变的通知。WaitForSingleObject(hchange,dwmilliseconds)中hchange
为FindFirstChangeNotificati
on 返回的句柄,dwmilliseconds为等待时间值,指定等待完成需要的时间,单
位为毫秒。该值为-1时表示时间无限长。最好在结束监视程序之前先用
FindCloseChangeNotification(hchange)
来关闭句柄。
下面给出一个简单的实例,其功能就是监视c:\pwin98目录下是否有文件发
生变化。一旦有重命名、创建
或删除情况发生时,通过Edit控件给出提示。
//
----------------
。nclude
。ragma hdrstop
。nclude “Unit1.h”
//----------------
。ragma package(smart_init)
。ragma resource “*.dfm”
TForm1 *Form1;
//-----------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//-------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
DWORD dwWaitStatus;
HANDLE dwChangeHandle; //返回通知的句柄
dwChangeHandle=FindFirstChangeNotification(
“C:\\PWIN98”,false,FILE_NOTIFY_CHANGE_FILE_NAME); //设置返回通知
的句柄
if(dwChangeHandle==INVALID_HANDLE_VALUE)
//判断是否设置成功
ExitProcess(GetLastError( ));
while(true){ //设置循环,监视是否有
dwWaitStatus=WaitForSingleObject(dwChangeHandle,-1); //通知返回
switch(dwWaitStatus){
case 0:
Edit1->Text=“Something Changed”; //给出提示
FindCloseChangeNotification(dwcChangeHandle); //关闭句柄
exit(EXIT_SUCCESS); //退出程序
default:
ExitProcess(GetLastError( ));
}
}
}
程序在C++Builder4/PWin98下通过,由于C++Builder语言很标准,所
以很容易扩展到其他编程语言
环境中去。
此例说明如何监视硬盘中文件变化,对于注册表,则有函数
RegNotifyChangeKeyValue( )可以实现类似
功能,这里暂省略之。
怎么样,看过本文,是否对Uninstaller Manager和Reg Monitor这样的软
件有了更深入的了解。在Wind
ows编程中,有些API函数起到了重要的作用,可以让程序实现很多高级的功能。
因为API函数是按照C语言语法
给出的,所以C++Builder有着得天独厚的优势,对API函数和宏支持得非常好
。不好,怎么跑题了?
』广 着干吗,难道你还不想赶快动?编制一个自己的Uninstaller Manager
吗?
(哈尔滨 赵晓辉)
监视程序,这个名字听起来似乎很陌生。它的用途主要是在后台监视系统中
关键信息的改变,比如注册表
的改变及硬盘上由于文件操作引起的改变等等。也许有人会问了,编制这样的程
序有什么价值呢?硬盘上文件
改变了,我只要在资源管理器里点一点不就全都清楚了吗?问题当然不会这样简
单,如今大家的硬盘都已经用
G来做单位了,一块4.3G的硬盘中,大大小小的文件全都加起来也会有若干万(
相信新购机的朋友会考虑IBM10
.1G的大硬盘,那文件数量将更加不可想象),更何况那些看不见的系统文件和
隐藏文件了。再加上注册表,那
其中的条条款款,数量也丝毫不逊于硬盘上的文件。要想随时知道自己机器是否
有所变动,绝对不是一件很轻
松的事。而监视程序就可以随时检测到这些变化,帮助我们了解这些情况。
当然这只是监视程序的一部分作用,它最大的作用就是可以记录下某个软件
安装前后系统的改变,从而为
卸载这个软件提供重要的依据。虽然Windows自带了一个Uninstall Shield,但
是它似乎并不能很干净地把原来的软件卸掉,每次卸载总会留下一些讨厌的残渣
,致使系统中的垃圾信息不断增长,我们的硬盘空间也总是莫名其妙地越用越少
。因此,一些号称能够完全卸载软件的专用卸载工具应运而生。在这其中,有一
些就运用了监视系统的技术,比如Uninstaller Manager和RegMonitor。
下面我们开始讨论如何编程实现这一监视功能。首先介绍几个重要的api函
数:
FindFirstChangeNotification( );
FindNextChangeNotification( );
WaitForSingleObject( );
其中FindFirstChangeNotification(lpzpath,fwatchsubtree,
fdwfilter)中的lpzpath表示要监视的路径名,fwatchsubtree判断是否查看子
目录,fdwfilter为要监视的事件,函数执行成功后返回一个句柄。
参数fdwfilter取值及其含义如下:
FILE_NOTIFY_CHANGE_FILE_NAME
查看指定目录下任何文件名的改变
FILE_NOTIFY_CHANGE_DIR_NAME
查看指定目录下任何目录名的改变
FILE_NOTIFY_CHANGE_SIZE
查看指定目录下文件大小的改变
FILE_NOTIFY_CHANGE_ATTRIBUTES
查看指定目录下文件属性的改变
FindNextChangeNotification(hchange),hchan
ge为FindFirstChangenNotification返回的句柄,其作用是请求系统在下次
检测到相应改变时发出改变通
知消息句柄。当函数成功返回后,应用程序可通过WaitForMultipleObjects或
WaitfForSingleObject来等待发
生改变的通知。WaitForSingleObject(hchange,dwmilliseconds)中hchange
为FindFirstChangeNotificati
on 返回的句柄,dwmilliseconds为等待时间值,指定等待完成需要的时间,单
位为毫秒。该值为-1时表示时间无限长。最好在结束监视程序之前先用
FindCloseChangeNotification(hchange)
来关闭句柄。
下面给出一个简单的实例,其功能就是监视c:\pwin98目录下是否有文件发
生变化。一旦有重命名、创建
或删除情况发生时,通过Edit控件给出提示。
//
----------------
。nclude
。ragma hdrstop
。nclude “Unit1.h”
FILE_NOTIFY_CHANGE_ATTRIBUTES
查看指定目录下文件属性的改变
FindNextChangeNotification(hchange),hchan
ge为FindFirstChangenNotification返回的句柄,其作用是请求系统在下次
检测到相应改变时发出改变通
知消息句柄。当函数成功返回后,应用程序可通过WaitForMultipleObjects或
WaitfForSingleObject来等待发
生改变的通知。WaitForSingleObject(hchange,dwmilliseconds)中hchange
为FindFirstChangeNotificati
on 返回的句柄,dwmilliseconds为等待时间值,指定等待完成需要的时间,单
位为毫秒。该值为-1时表示时间无限长。最好在结束监视程序之前先用
FindCloseChangeNotification(hchange)
来关闭句柄。
下面给出一个简单的实例,其功能就是监视c:\pwin98目录下是否有文件发
生变化。一旦有重命名、创建
或删除情况发生时,通过Edit控件给出提示。
//
----------------
。nclude
。ragma hdrstop
。nclude “Unit1.h”
//----------------
。ragma package(smart_init)
。ragma resource “*.dfm”
TForm1 *Form1;
//-----------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//-------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
DWORD dwWaitStatus;
HANDLE dwChangeHandle; //返回通知的句柄
dwChangeHandle=FindFirstChangeNotification(
“C:\\PWIN98”,false,FILE_NOTIFY_CHANGE_FILE_NAME); //设置返回通知
的句柄
if(dwChangeHandle==INVALID_HANDLE_VALUE)
//判断是否设置成功
ExitProcess(GetLastError( ));
while(true){ //设置循环,监视是否有
dwWaitStatus=WaitForSingleObject(dwChangeHandle,-1); //通知返回
switch(dwWaitStatus){
case 0:
Edit1->Text=“Something Changed”; //给出提示
FindCloseChangeNotification(dwcChangeHandle); //关闭句柄
exit(EXIT_SUCCESS); //退出程序
default:
ExitProcess(GetLastError( ));
}
}
}
程序在C++Builder4/PWin98下通过,由于C++Builder语言很标准,所
以很容易扩展到其他编程语言
环境中去。
此例说明如何监视硬盘中文件变化,对于注册表,则有函数
RegNotifyChangeKeyValue( )可以实现类似
功能,这里暂省略之。
怎么样,看过本文,是否对Uninstaller Manager和Reg Monitor这样的软
件有了更深入的了解。在Wind
ows编程中,有些API函数起到了重要的作用,可以让程序实现很多高级的功能。
因为API函数是按照C语言语法
给出的,所以C++Builder有着得天独厚的优势,对API函数和宏支持得非常好
。不好,怎么跑题了?
』广 着干吗,难道你还不想赶快动?编制一个自己的Uninstaller Manager
吗?
#11
我记得有消息可以捕获吧
#12
那个什么RegNotify什么的函数是不行的,她只能告诉你有改动,但不会告诉你具体的改动地方。我试过的。
#13
呵呵,也是啊。我这几天正在想着呢……
只是说有改动的话仅仅是编程目的中的方向性指标,但是我要的是具体的改动。不知道NowCan(能量、激情、雨水、彩虹——雷雨云)兄能否解决这个问题呢?
只是说有改动的话仅仅是编程目的中的方向性指标,但是我要的是具体的改动。不知道NowCan(能量、激情、雨水、彩虹——雷雨云)兄能否解决这个问题呢?
#14
再次关注
#15
我的收藏:
unit UMesApi;
interface
uses SysUtils, Classes;
function ToUnicode(str:string;dest:PWideChar):integer;
function SendMsg(Toh,From,Msg:string):integer;
function NetMessageBufferSend(servername:PWideChar;
MsgName:PWideChar;
FromName:PWideChar;
Buf: PWideChar;
var BufLen:integer):integer;cdecl;
implementation
function ToUnicode(str:string;dest:PWideChar):integer;
var
len:integer;
begin
len:=Length(str)*2;
//len:=length(dest^);
StringToWideChar(str,dest,len);
Result:=len;
end;
function NetMessageBufferSend; external 'netapi32.dll' name 'NetMessageBufferSend';
function SendMsg(Toh,From,Msg:string):integer;
var
ToName :array [0..64] of WideChar;
WMsgText:array [0..1000] of WideChar;
MsgLen,i:integer;
begin
for i := 0 to 64 do ToName[i] := #0;
ToUnicode(Toh,ToName);
for i := 0 to 1000 do WMsgText[i] := #0;
MsgLen:=ToUnicode(Msg,WMsgText);
Result:=NetMessageBufferSend(nil,ToName,nil,@WMsgText,MsgLen);
end;
end.
unit UMesApi;
interface
uses SysUtils, Classes;
function ToUnicode(str:string;dest:PWideChar):integer;
function SendMsg(Toh,From,Msg:string):integer;
function NetMessageBufferSend(servername:PWideChar;
MsgName:PWideChar;
FromName:PWideChar;
Buf: PWideChar;
var BufLen:integer):integer;cdecl;
implementation
function ToUnicode(str:string;dest:PWideChar):integer;
var
len:integer;
begin
len:=Length(str)*2;
//len:=length(dest^);
StringToWideChar(str,dest,len);
Result:=len;
end;
function NetMessageBufferSend; external 'netapi32.dll' name 'NetMessageBufferSend';
function SendMsg(Toh,From,Msg:string):integer;
var
ToName :array [0..64] of WideChar;
WMsgText:array [0..1000] of WideChar;
MsgLen,i:integer;
begin
for i := 0 to 64 do ToName[i] := #0;
ToUnicode(Toh,ToName);
for i := 0 to 1000 do WMsgText[i] := #0;
MsgLen:=ToUnicode(Msg,WMsgText);
Result:=NetMessageBufferSend(nil,ToName,nil,@WMsgText,MsgLen);
end;
end.
#16
unit UMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Registry,IniFiles, ExtCtrls;
type
TFormMain = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
published
procedure LogMsg(msg:string);
private
{ Private declarations }
Reg:TRegistry;
IniFile:TIniFile;
LogFile:TStringList;
LogFileName:String;
RegKeys:TStringList;
CurrUser,HostName:String;
public
{ Public declarations }
end;
var
FormMain: TFormMain;
implementation
uses UMesApi;
{$R *.DFM}
procedure TFormMain.FormCreate(Sender: TObject);
var IniName,value:string;
i:integer;
pstr:pchar;
n:Cardinal;
begin
try
n:=64;
pstr:=StrAlloc(n);
GetUserName(pstr,n);
CurrUser:=StrPas(pstr);
GetComputerName(pstr,n);
HostName:=StrPas(pstr);
StrDispose(pstr);
self.Reg:=TRegistry.Create;
with self.Reg do
begin
RootKey:=HKEY_Local_Machine;
Access:=KEY_EXECUTE;
if OpenKey('Software\Microsoft\Windows\CurrentVersion\Run',false) then
begin
RegKeys:=TStringList.Create;
GetValueNames(RegKeys);
for i:=0 to Regkeys.Count-1 do
if (GetDataType(RegKeys.Strings[i])=rdString)
or (GetDataType(RegKeys.Strings[i])=rdExpandString)
then begin
value:=ReadString(RegKeys.Strings[i]);
if value=Application.ExeName then Break;
end;
if value<>Application.ExeName then
begin //if not set run with widows ,then set it
WriteString('PiRegWatch',Application.ExeName);
end;
end
else
begin
Messagebox(0,'Can"t Open RegKey','error',mb_ok);
Application.Terminate;
end;
end ;
IniName:=Application.ExeName;
IniName:=Copy(IniName,1,Length(IniName)-4)+'.ini';
self.IniFile:=TIniFile.Create(IniName);
self.LogFile:=TStringList.Create;
self.LogFileName:=Copy(IniName,1,Length(IniName)-4)+'.log';
if FileExists(LogFileName) then self.LogFile.LoadFromFile(self.LogFileName);
if not self.IniFile.SectionExists('RunList') then
begin
for i:=0 to Regkeys.Count-1 do
if (self.Reg.GetDataType(RegKeys.Strings[i])=rdString)
or (self.Reg.GetDataType(RegKeys.Strings[i])=rdExpandString)
then begin
value:=self.Reg.ReadString(RegKeys.Strings[i]);
self.IniFile.WriteString('RunList',RegKeys.Strings[i],value);
end;
self.IniFile.Free; //Force INI file save
self.IniFile:=TIniFile.Create(IniName);
end;
except
Messagebox(0,'App Terminate','error',mb_ok);
Application.Terminate;
end;
end;
procedure TFormMain.Timer1Timer(Sender: TObject);
var i:integer;
RegVal,IniVal:string;
begin
self.Timer1.Enabled:=False;
self.Reg.GetValueNames(RegKeys);
for i:=0 to RegKeys.Count-1 do //Check to New Added items
if (self.Reg.GetDataType(RegKeys.Strings[i])=rdString)
or (self.Reg.GetDataType(RegKeys.Strings[i])=rdExpandString)
then begin
RegVal:=self.Reg.ReadString(RegKeys.Strings[i]);
IniVal:=self.IniFile.ReadString('RunList',RegKeys.Strings[i],'');
if RegVal<>IniVal then
begin
self.LogMsg('Item Add:'+RegKeys.Strings[i]+'='+RegVal);
self.IniFile.WriteString('RunList',RegKeys.Strings[i],RegVal);
try
SendMsg('ABC','','注册表被改变:新增项目'+RegKeys.Strings[i]+'='+RegVal);
finally
end;
end;
end;
self.IniFile.ReadSection('RunList',RegKeys);
for i:=0 to RegKeys.Count-1 do //Check to Deleted Items
begin
IniVal:=self.IniFile.ReadString('RunList',RegKeys.Strings[i],'');
if self.Reg.ValueExists(RegKeys.Strings[i]) and
((self.Reg.GetDataType(RegKeys.Strings[i])=rdString)
or (self.Reg.GetDataType(RegKeys.Strings[i])=rdExpandString) )
then
RegVal:=self.Reg.ReadString(RegKeys.Strings[i])
else
RegVal:='';
if (IniVal<>'') and (RegVal='') then
begin
self.LogMsg('Item Del:'+RegKeys.Strings[i]+'='+IniVal);
self.IniFile.DeleteKey('RunList',RegKeys.Strings[i]);
try
SendMsg('ABC','','注册表被改变:项目删除'+RegKeys.Strings[i]+'='+IniVal);
finally
end;
end;
end;
self.IniFile.UpdateFile;
self.Timer1.Enabled:=True;
end;
procedure TFormMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if Assigned(self.Reg) then self.Reg.Free;
if Assigned(self.IniFile) then self.IniFile.Free;
if Assigned(self.LogFile) then self.LogFile.Free;
if Assigned(self.RegKeys) then self.RegKeys.Free;
end;
procedure TFormMain.LogMsg(msg:string);
var str:string;
y,m,d:word;
begin
str:=Format('[%s] %s on %s ,%s',[DatetimeToStr(Now),self.CurrUser,self.HostName,msg]);
self.LogFile.Add(str);
if self.LogFile.Count<=100 then
self.LogFile.SaveToFile(self.LogFileName)
else begin
DecodeDate(Now,y,m,d);
str:=ExtractFilePath(self.LogFileName)+Format('%2d%2d%2d',[y,m,d])+'.log';
self.LogFile.SaveToFile(str);
self.LogFile.Clear;
self.LogFile.SaveToFile(self.LogFileName);
end;
end;
end.
有谁把他改成BCB,我看见Begin End就麻.
我下大家满足了吧!
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Registry,IniFiles, ExtCtrls;
type
TFormMain = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
published
procedure LogMsg(msg:string);
private
{ Private declarations }
Reg:TRegistry;
IniFile:TIniFile;
LogFile:TStringList;
LogFileName:String;
RegKeys:TStringList;
CurrUser,HostName:String;
public
{ Public declarations }
end;
var
FormMain: TFormMain;
implementation
uses UMesApi;
{$R *.DFM}
procedure TFormMain.FormCreate(Sender: TObject);
var IniName,value:string;
i:integer;
pstr:pchar;
n:Cardinal;
begin
try
n:=64;
pstr:=StrAlloc(n);
GetUserName(pstr,n);
CurrUser:=StrPas(pstr);
GetComputerName(pstr,n);
HostName:=StrPas(pstr);
StrDispose(pstr);
self.Reg:=TRegistry.Create;
with self.Reg do
begin
RootKey:=HKEY_Local_Machine;
Access:=KEY_EXECUTE;
if OpenKey('Software\Microsoft\Windows\CurrentVersion\Run',false) then
begin
RegKeys:=TStringList.Create;
GetValueNames(RegKeys);
for i:=0 to Regkeys.Count-1 do
if (GetDataType(RegKeys.Strings[i])=rdString)
or (GetDataType(RegKeys.Strings[i])=rdExpandString)
then begin
value:=ReadString(RegKeys.Strings[i]);
if value=Application.ExeName then Break;
end;
if value<>Application.ExeName then
begin //if not set run with widows ,then set it
WriteString('PiRegWatch',Application.ExeName);
end;
end
else
begin
Messagebox(0,'Can"t Open RegKey','error',mb_ok);
Application.Terminate;
end;
end ;
IniName:=Application.ExeName;
IniName:=Copy(IniName,1,Length(IniName)-4)+'.ini';
self.IniFile:=TIniFile.Create(IniName);
self.LogFile:=TStringList.Create;
self.LogFileName:=Copy(IniName,1,Length(IniName)-4)+'.log';
if FileExists(LogFileName) then self.LogFile.LoadFromFile(self.LogFileName);
if not self.IniFile.SectionExists('RunList') then
begin
for i:=0 to Regkeys.Count-1 do
if (self.Reg.GetDataType(RegKeys.Strings[i])=rdString)
or (self.Reg.GetDataType(RegKeys.Strings[i])=rdExpandString)
then begin
value:=self.Reg.ReadString(RegKeys.Strings[i]);
self.IniFile.WriteString('RunList',RegKeys.Strings[i],value);
end;
self.IniFile.Free; //Force INI file save
self.IniFile:=TIniFile.Create(IniName);
end;
except
Messagebox(0,'App Terminate','error',mb_ok);
Application.Terminate;
end;
end;
procedure TFormMain.Timer1Timer(Sender: TObject);
var i:integer;
RegVal,IniVal:string;
begin
self.Timer1.Enabled:=False;
self.Reg.GetValueNames(RegKeys);
for i:=0 to RegKeys.Count-1 do //Check to New Added items
if (self.Reg.GetDataType(RegKeys.Strings[i])=rdString)
or (self.Reg.GetDataType(RegKeys.Strings[i])=rdExpandString)
then begin
RegVal:=self.Reg.ReadString(RegKeys.Strings[i]);
IniVal:=self.IniFile.ReadString('RunList',RegKeys.Strings[i],'');
if RegVal<>IniVal then
begin
self.LogMsg('Item Add:'+RegKeys.Strings[i]+'='+RegVal);
self.IniFile.WriteString('RunList',RegKeys.Strings[i],RegVal);
try
SendMsg('ABC','','注册表被改变:新增项目'+RegKeys.Strings[i]+'='+RegVal);
finally
end;
end;
end;
self.IniFile.ReadSection('RunList',RegKeys);
for i:=0 to RegKeys.Count-1 do //Check to Deleted Items
begin
IniVal:=self.IniFile.ReadString('RunList',RegKeys.Strings[i],'');
if self.Reg.ValueExists(RegKeys.Strings[i]) and
((self.Reg.GetDataType(RegKeys.Strings[i])=rdString)
or (self.Reg.GetDataType(RegKeys.Strings[i])=rdExpandString) )
then
RegVal:=self.Reg.ReadString(RegKeys.Strings[i])
else
RegVal:='';
if (IniVal<>'') and (RegVal='') then
begin
self.LogMsg('Item Del:'+RegKeys.Strings[i]+'='+IniVal);
self.IniFile.DeleteKey('RunList',RegKeys.Strings[i]);
try
SendMsg('ABC','','注册表被改变:项目删除'+RegKeys.Strings[i]+'='+IniVal);
finally
end;
end;
end;
self.IniFile.UpdateFile;
self.Timer1.Enabled:=True;
end;
procedure TFormMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if Assigned(self.Reg) then self.Reg.Free;
if Assigned(self.IniFile) then self.IniFile.Free;
if Assigned(self.LogFile) then self.LogFile.Free;
if Assigned(self.RegKeys) then self.RegKeys.Free;
end;
procedure TFormMain.LogMsg(msg:string);
var str:string;
y,m,d:word;
begin
str:=Format('[%s] %s on %s ,%s',[DatetimeToStr(Now),self.CurrUser,self.HostName,msg]);
self.LogFile.Add(str);
if self.LogFile.Count<=100 then
self.LogFile.SaveToFile(self.LogFileName)
else begin
DecodeDate(Now,y,m,d);
str:=ExtractFilePath(self.LogFileName)+Format('%2d%2d%2d',[y,m,d])+'.log';
self.LogFile.SaveToFile(str);
self.LogFile.Clear;
self.LogFile.SaveToFile(self.LogFileName);
end;
end;
end.
有谁把他改成BCB,我看见Begin End就麻.
我下大家满足了吧!
#17
这个问题?
禁止注册表的改动,就可以!
禁止注册表的改动,就可以!
#18
感谢Bird1945(老唬是女人!),呵呵。去试试看先……
To dycdyc123(重出江湖),我没有说要禁止他阿,我只要看他改动哪里就可以了。哦,还有,恕我肤浅,怎样禁止注册表的改动?我不知道阿。
To dycdyc123(重出江湖),我没有说要禁止他阿,我只要看他改动哪里就可以了。哦,还有,恕我肤浅,怎样禁止注册表的改动?我不知道阿。
#19
就是让在local maching的什么里面加一个disabled
你可以去查一下
一般的黑客网站都有
你可以去查一下
一般的黑客网站都有
#20
Bird1945的代码好像有点问题
因为在formcreate时候一直监测文件夹]的变动
是不是会造成form显示不出来阿
我只是猜测阿
因为在formcreate时候一直监测文件夹]的变动
是不是会造成form显示不出来阿
我只是猜测阿
#21
没错,Bird1945的代码大有问题!
不知他自己有无调试过?
直接从网上拷过来的吧?
不知他自己有无调试过?
直接从网上拷过来的吧?