?
Solved

Edit Registry Code to show the whole key IE "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"

Posted on 2008-09-29
3
Medium Priority
?
1,094 Views
Last Modified: 2012-06-21
The object here is to help show the exact  key and full path "IE"
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run  
I will except a demo that will watch the registry and show me this info or help fix the current code posted here to do so.
unit RegMonitorThread;
 
interface
 
uses
  Classes, Windows, Messages, Registry, SysUtils;
 
  const
  WM_REGCHANGE  = WM_USER + 1973;
 
//Need to redeclare the API function - instead of BOOL is uses DWORD.
function RegNotifyChangeKeyValue(       hKey: HKEY;
                                        bWatchSubtree: DWORD;
                                        dwNotifyFilter: DWORD;
                                        hEvent: THandle;
                                        fAsynchronus: DWORD): Longint; stdcall;
external 'advapi32.dll' name 'RegNotifyChangeKeyValue';
 
type
  TChangeData = record
    Key : string;
    RootKey : HKey;
  end;
 
  TRegMonitorThread = class(TThread)
 
  private
    FReg: TRegistry;
    fChangeData : TChangeData;
    fKey: string;
    fRootKey: HKey;
    fWatchSub: boolean;
    fFilter: integer;
    fWnd: THandle;
    id: integer;
    procedure InitThread;
    procedure SetFilter(const Value: integer);
    function GetFilter: integer;
    function GetChangeData: TChangeData;
 
  public
    constructor Create;
    destructor Destroy; override;
    property Key: string        read fKey       write fKey;
    property RootKey: HKey      read fRootKey   write fRootKey;
    property WatchSub: boolean  read fWatchSub  write fWatchSub;
    property Filter: integer    read GetFilter  write SetFilter;
    property Wnd: THandle       read fWnd       write fWnd;
    property i: integer    read id  write id;
    property ChangeData : TChangeData read GetChangeData;
 
  protected
    procedure Execute; override;
 
  end;
 
implementation
 
{ TRegMonitorThread }
constructor TRegMonitorThread.Create;
begin
  // Execute wont be called until after Resume is called.
  inherited Create(True);
 
  FReg := TRegistry.Create;
end;
 
destructor TRegMonitorThread.Destroy;
begin
  FReg.Free;
  inherited;
end;
 
procedure TRegMonitorThread.InitThread;
begin
  FReg.RootKey := RootKey;
  if not FReg.OpenKeyReadOnly(Key) then
        MessageBox(     fwnd  ,
                        'Error accesing key',
                        'GetLastError',
                        MB_OK or MB_ICONINFORMATION )
  else
        RegNotifyChangeKeyValue(FReg.CurrentKey, 1, Filter, Cardinal(0), Cardinal(False));
end;
 
 
procedure TRegMonitorThread.Execute;
var
        tmp : Integer;
begin
  InitThread;
 
  while not Terminated do
  begin
      fChangeData.RootKey := RootKey;
      fChangeData.Key := Key;
      SendMessage(Wnd, WM_REGCHANGE, i, LongInt(PChar(Key)));
 
      tmp := RegNotifyChangeKeyValue(    FReg.CurrentKey,
                                        1,
                                        Filter,
                                        Cardinal(0),
                                        Cardinal(0));
      if tmp <> ERROR_SUCCESS then
      begin
                // Display the string.
        MessageBox(     fwnd,
                        'Error accesing key',
                        'GetLastError',
                        MB_OK or MB_ICONINFORMATION );
        fChangeData.RootKey := 0;
        fChangeData.Key := 'Terminated due to missing key.';
        SendMessage(Wnd, WM_REGCHANGE, i, LongInt(PChar(Key)));
        self.Terminate;
       end;
  end;
end;
 
 
 
procedure TRegMonitorThread.SetFilter(const Value: integer);
begin
  if fFilter <> Value then
  begin
    fFilter := Value;
  end;
end;
 
 
function TRegMonitorThread.GetFilter: integer;
begin
  if fFilter = 0 then begin
    fFilter:=
      REG_NOTIFY_CHANGE_NAME or
      REG_NOTIFY_CHANGE_ATTRIBUTES or
      REG_NOTIFY_CHANGE_LAST_SET or
      REG_NOTIFY_CHANGE_SECURITY;
  end;
  Result := fFilter;
end;
 
 
function TRegMonitorThread.GetChangeData: TChangeData;
begin
  Result := fChangeData;
end;
 
end.
 
 
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<FOrm1Code>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, RegMonitorThread, MPlayer;
 
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Memo2: TMemo;
    Memo3: TMemo;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    CheckBox4: TCheckBox;
    Memo4: TMemo;
    Memo5: TMemo;
    Edit5: TEdit;
    CheckBox5: TCheckBox;
    soundPlayer1: TMediaPlayer;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure CheckBox1Click(Sender: TObject);
    procedure CheckBox3Click(Sender: TObject);
    procedure CheckBox2Click(Sender: TObject);
    procedure CheckBox4Click(Sender: TObject);
    procedure CheckBox5Click(Sender: TObject);
  private
    soundAvailable : BOOL;
    procedure WMREGCHANGE(var Msg : TMessage); message WM_REGCHANGE;
    procedure initSound;
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
  RegMonitorThread1 : TRegMonitorThread;
  RegMonitorThread2 : TRegMonitorThread;
  RegMonitorThread3 : TRegMonitorThread;
  RegMonitorThread4 : TRegMonitorThread;
  RegMonitorThread5 : TRegMonitorThread;
  
implementation
 
 
{$R *.dfm}
 
procedure TForm1.FormCreate(Sender: TObject);
begin
        RegMonitorThread1 := TRegMonitorThread.Create;	//We create one thread per key to watch
        RegMonitorThread2 := TRegMonitorThread.Create;
        RegMonitorThread3 := TRegMonitorThread.Create;
        RegMonitorThread4 := TRegMonitorThread.Create;
        RegMonitorThread5 := TRegMonitorThread.Create;
 
  with RegMonitorThread1 do
  begin
    FreeOnTerminate:=True;
    Wnd := Form1.Handle;
    Key := '';
    RootKey := HKEY_CLASSES_ROOT ;
        i := 1;		// thread id
    WatchSub := True;
//    Resume;		Start only when signaled to do so
  end;
 
  with RegMonitorThread2 do
  begin
    FreeOnTerminate:=True;
    Wnd := Form1.Handle;
    Key := '';
    RootKey := HKEY_CURRENT_USER ;
        i := 2;
    WatchSub := True;
  end;
 
  with RegMonitorThread3 do
  begin
    FreeOnTerminate:=True;
    Wnd := Form1.Handle;
    Key := '';
    RootKey := HKEY_LOCAL_MACHINE ;
        i := 3;
    WatchSub := True;
  end;
 
  with RegMonitorThread4 do
  begin
    FreeOnTerminate:=True;
    Wnd := Form1.Handle;
    Key := '';
    RootKey := HKEY_USERS ;
        i := 4;
    WatchSub := True;
  end;
 
  with RegMonitorThread5 do
  begin
    FreeOnTerminate:=True;
    Wnd := Form1.Handle;
    Key := '';
    RootKey := HKEY_CURRENT_CONFIG ;
        i := 5;
    WatchSub := True;
  end;
 
    initSound;
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
begin
        RegMonitorThread1.Terminate;
        RegMonitorThread2.Terminate;
        RegMonitorThread3.Terminate;
        RegMonitorThread4.Terminate;
        RegMonitorThread5.Terminate;
        if soundAvailable then	//if we were able to open the sound file
            soundPlayer1.Close;
end;
 
procedure TForm1.WMREGCHANGE(var Msg: TMessage);	//we put presentation code here
begin
 
        if Msg.WParam = 1 then
        begin
                Memo1.Lines.Add('-------------------------------------------');
                Memo1.Lines.Add('Registry change at ' + DateTimeToStr(Now));
                Memo1.Lines.Add(IntToStr(RegMonitorThread1.ChangeData.RootKey) +
                  ' - ' + RegMonitorThread1.ChangeData.Key);
        end
        else if Msg.WParam = 2 then
        begin
                Memo2.Lines.Add('-------------------------------------------');
                Memo2.Lines.Add('Registry change at ' + DateTimeToStr(Now));
                Memo2.Lines.Add(IntToStr(RegMonitorThread2.ChangeData.RootKey) +
                  ' - ' + RegMonitorThread2.ChangeData.Key);
        end
        else if Msg.WParam = 3 then
        begin
                Memo3.Lines.Add('-------------------------------------------');
                Memo3.Lines.Add('Registry change at ' + DateTimeToStr(Now));
                Memo3.Lines.Add(IntToStr(RegMonitorThread3.ChangeData.RootKey) +
                  ' - ' + RegMonitorThread3.ChangeData.Key);
        end
        else if Msg.WParam = 4 then
        begin
                Memo4.Lines.Add('-------------------------------------------');
                Memo4.Lines.Add('Registry change at ' + DateTimeToStr(Now));
                Memo4.Lines.Add(IntToStr(RegMonitorThread4.ChangeData.RootKey) +
                  ' - ' + RegMonitorThread4.ChangeData.Key);
        end
        else if Msg.WParam = 5 then
        begin
                Memo5.Lines.Add('-------------------------------------------');
                Memo5.Lines.Add('Registry change at ' + DateTimeToStr(Now));
                Memo5.Lines.Add(IntToStr(RegMonitorThread5.ChangeData.RootKey) +
                  ' - ' + RegMonitorThread5.ChangeData.Key);
        end;
        if soundAvailable then
            soundPlayer1.Play;
end;
 
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
        if not CheckBox1.Checked then
        begin
            Edit1.Enabled := True;
            Edit1.Color := clWindow;
            TerminateThread(RegMonitorThread1.Handle,0);	//Stop the thread
        end
        else
        begin
            RegMonitorThread1 := TRegMonitorThread.Create;
            Edit1.Enabled := False;				//Run the thread again
            Edit1.Color := clInactiveCaptionText;
            with RegMonitorThread1 do
            begin
                FreeOnTerminate:=True;			// I know this code is repeated
                Wnd := Form1.Handle;			// I am leaving it so you can understand
                Key := Edit1.Text;			//everything. 
                RootKey := HKEY_CLASSES_ROOT ;
                i := 1;
                WatchSub := True;
                Resume;
            end;
        end;
end;
procedure TForm1.CheckBox2Click(Sender: TObject);
begin
        if not CheckBox2.Checked then
        begin
            Edit2.Enabled := True;
            Edit2.Color := clWindow;
            TerminateThread(RegMonitorThread2.Handle,0);
        end
        else
        begin
            RegMonitorThread2 := TRegMonitorThread.Create;
            Edit2.Enabled := False;
            Edit2.Color := clInactiveCaptionText;
            with RegMonitorThread2 do
            begin
                FreeOnTerminate:=True;
                Wnd := Form1.Handle;
                Key := Edit2.Text;
                RootKey := HKEY_CURRENT_USER ;
                i := 2;
                WatchSub := True;
                Resume;
            end;
        end;
end;
procedure TForm1.CheckBox3Click(Sender: TObject);
begin
        if not CheckBox3.Checked then
        begin
            Edit3.Enabled := True;
            Edit3.Color := clWindow;
            TerminateThread(RegMonitorThread3.Handle,0);
        end
        else
        begin
            RegMonitorThread3 := TRegMonitorThread.Create;
            Edit3.Enabled := False;
            Edit3.Color := clInactiveCaptionText;
            with RegMonitorThread3 do
            begin
                FreeOnTerminate:=True;
                Wnd := Form1.Handle;
                Key := Edit3.Text;
                RootKey := HKEY_LOCAL_MACHINE ;
                i := 3;
                WatchSub := True;
                Resume;
            end;
        end;
end;
procedure TForm1.CheckBox4Click(Sender: TObject);
begin
        if not CheckBox4.Checked then
        begin
            Edit4.Enabled := True;
            Edit4.Color := clWindow;
            TerminateThread(RegMonitorThread4.Handle,0);
        end
        else
        begin
            RegMonitorThread4 := TRegMonitorThread.Create;
            Edit4.Enabled := False;
            Edit4.Color := clInactiveCaptionText;
            with RegMonitorThread4 do
            begin
                FreeOnTerminate:=True;
                Wnd := Form1.Handle;
                Key := Edit4.Text;
                RootKey := HKEY_USERS;
                i := 4;
                WatchSub := True;
                Resume;
            end;
        end;
end;
 
procedure TForm1.CheckBox5Click(Sender: TObject);
begin
        if not CheckBox5.Checked then
        begin
            Edit5.Enabled := True;
            Edit5.Color := clWindow;
            TerminateThread(RegMonitorThread5.Handle,0);
        end
        else
        begin
            RegMonitorThread5 := TRegMonitorThread.Create;
            Edit5.Enabled := False;
            Edit5.Color := clInactiveCaptionText;
            with RegMonitorThread5 do
            begin
                FreeOnTerminate:=True;
                Wnd := Form1.Handle;
                Key := Edit5.Text;
                RootKey := HKEY_CURRENT_CONFIG;
                i := 5;
                WatchSub := True;
                Resume;
            end;
        end;
end;
 
procedure TForm1.initSound();
var sWinDir: String;
    iLength: Integer;
begin
 
    iLength := 255;
    setLength(sWinDir, iLength);
    iLength := GetWindowsDirectory(PChar(sWinDir), iLength);
    setLength(sWinDir, iLength);
 
    With soundPlayer1 do
    begin
         Filename := sWinDir + '\media\notify.wav'; //specify sound file
         try
            Open;	// this throws and exception. must catch it.
         except
            on EMCIDeviceError do ShowMessage('Could not open sound file');
         end;
         if Error = 0 then
            soundAvailable := True	//flag for use
         else
            soundAvailable := False;
    end;
end;
 
 
end.

Open in new window

0
Comment
Question by:Grant Fullen
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
3 Comments
 
LVL 21

Accepted Solution

by:
ziolko earned 600 total points
ID: 22602995
not possible. RegNotifyChangeKeyValue signals only that change was made in specified registry key (or it's sub key if bWatchSubtree is true). there's no indication which values has been changed

ziolko.
0
 
LVL 21

Expert Comment

by:ziolko
ID: 22603025
... of course you can backup whole registry key to file set notification, once you get notification backup registry again and compare changes. but if you set notifications on all root keys this method will most likely completely kill preformance of your machine

ziolko.
0
 
LVL 26

Assisted Solution

by:EddieShipman
EddieShipman earned 400 total points
ID: 24310885
Per KB Q236570: http://support.microsoft.com/kb/236570

"As with the file change notification APIs, RegNotifyChangeKeyValue() does not return any indication as to what has changed in the registry key or its subkeys or values. The program must know the state of the keys or values prior to the notification, so that it can determine what has changed. "
0

Featured Post

Enroll in August's Course of the Month

August's CompTIA IT Fundamentals course includes 19 hours of basic computer principle modules and prepares you for the certification exam. It's free for Premium Members, Team Accounts, and Qualified Experts!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
Suggested Courses
Course of the Month12 days, 7 hours left to enroll

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question