คำชี้แจง: กลุ่มหรือบุคคลอื่นที่ไม่ใช่ CSDN ที่พิมพ์บทความนี้ซ้ำจะต้องระบุแหล่งที่มาและผู้แต่ง
คลาส TRegistry ที่มาพร้อมกับ Delphi สามารถใช้งานได้เฉพาะการดำเนินการพื้นฐานของรีจิสทรีเท่านั้น หากเราต้องการตรวจสอบการเปลี่ยนแปลงในรีจิสทรีแบบเรียลไทม์หรือสแกนคีย์ย่อยทั้งหมดภายใต้คีย์เฉพาะในรีจิสทรี คลาส TRegistry จะไม่มีอำนาจ ฉันกัดกิน SDK มาเป็นเวลานาน และในที่สุดก็ตระหนักถึงการตรวจสอบและสแกนรีจิสทรีของ Delphi ฉันไม่กล้าเก็บไว้คนเดียว ดังนั้นฉันจึงทุ่มเทให้กับผู้ที่ชื่นชอบ Delphi ส่วนใหญ่
การตรวจสอบการเปลี่ยนแปลงในรายการที่เกี่ยวข้องกับรีจิสทรีต้องใช้ API: RegNotifyChangeKeyValue
ยาว RegNotifyChangeKeyValue(
HKEY hKey // จัดการกับรายการที่จะตรวจสอบ
BOOL bWatchSubtree, // จะตรวจสอบคีย์ย่อยของรายการนี้หรือไม่
DWord dwNotifyFilter // การเปลี่ยนแปลงใดในการตรวจสอบ
จัดการ hEvent // ตัวจัดการวัตถุเหตุการณ์ที่ยอมรับเหตุการณ์การเปลี่ยนแปลงรีจิสทรี
BOOL fAsynchronous // รายงานก่อนการเปลี่ยนแปลงรีจิสทรีหรือหลังการเปลี่ยนแปลงรีจิสทรี
-
โปรดทราบว่า hEvent ข้างต้นเป็นตัวจัดการวัตถุเหตุการณ์ที่ยอมรับเหตุการณ์การเปลี่ยนแปลงรีจิสทรี เราจำเป็นต้องใช้ API: CreateEvent เพื่อสร้างวัตถุเหตุการณ์ระบบ
จัดการสร้างกิจกรรม(
LPSECURITY_ATTRIBUTES lpEventAttributes, // โครงสร้าง SECURITY_ATTRIBUTES
BOOL bManualReset, // ไม่ว่าจะรีเซ็ตอัตโนมัติหรือไม่
BOOL bInitialState, // ไม่ว่าจะตั้งค่าสถานะเริ่มต้นหรือไม่
LPCTSTR lpName //ชื่อของวัตถุเหตุการณ์
-
สร้างโครงการใหม่และเพิ่มกล่องรายการและปุ่มสองปุ่ม
//ขั้นแรกให้เขียนตัวอย่างการตรวจสอบรีจิสทรี
//ตรวจสอบคีย์ย่อยทั้งหมดภายใต้รายการ HKEY_CURRENT_USER/Software
ขั้นตอน TForm1.Button1Click (ผู้ส่ง: TObject);
var
hNotify: THandle;
hKeyx:HKEY;
DWRes: DWORD;
เริ่ม
hNotify := CreateEvent( ไม่มี //อย่าใช้โครงสร้าง SECURITY_ATTRIBUTES
FALSE // อย่ารีเซ็ตโดยอัตโนมัติ
TRUE // ตั้งค่าสถานะเริ่มต้น
'RegistryNotify' //ชื่อของวัตถุเหตุการณ์
-
ถ้า hNotify = 0 แล้ว
เริ่ม
Showmessage('สร้างกิจกรรมล้มเหลว');
ออก;
จบ;
ถ้า RegOpenKeyEx(HKEY_CURRENT_USER, //ทำตามคีย์
'ซอฟต์แวร์' //คีย์ย่อย
0, //สงวนไว้
KEY_NOTIFY // สำหรับการตรวจสอบ
hKeyx // บันทึกที่จับ
) <> ERROR_SUCCESS แล้ว
เริ่ม
CloseHandle( hแจ้งเตือน );
Showmessage('RegOpenKeyEx ล้มเหลว');
ออก;
จบ;
ถ้า RegNotifyChangeKeyValue(hKeyx, //Monitor subkey handle
TRUE //ตรวจสอบคีย์ย่อยของรายการนี้
REG_NOTIFY_CHANGE_NAME หรือ REG_NOTIFY_CHANGE_LAST_SET
hNotify, //ตัวจัดการวัตถุเหตุการณ์ที่ยอมรับเหตุการณ์การเปลี่ยนแปลงรีจิสทรี
TRUE // รายงานก่อนการเปลี่ยนแปลงรีจิสทรี
) <> ERROR_SUCCESS แล้ว
เริ่ม
CloseHandle( hแจ้งเตือน );
RegCloseKey( hKeyx );
Showmessage('RegNotifyChangeKeyValue ล้มเหลว');
ออก;
จบ;
dwRes := WaitForSingleObject( hNotify, 60 * 1,000 ); // ตรวจสอบเป็นเวลาหนึ่งนาที
ถ้า dwRes = 0 แล้ว
Showmessage( 'ข้อมูลรีจิสทรีจะถูกเปลี่ยน' );
CloseHandle( hแจ้งเตือน );
RegCloseKey( hKeyx );
จบ;
โปรดทราบว่า API: WaitForSingleObject จะไม่กลับมาจนกว่าเหตุการณ์การเปลี่ยนแปลงรีจิสทรีจะเกิดขึ้นหรือหมดเวลาลง ในช่วงเวลานี้ โปรแกรมของเราจะสูญเสียการตอบสนอง วิธีแก้ไขคือสร้างเธรดใหม่และตรวจสอบรีจิสทรีในชุดข้อความใหม่
มีการใช้ API อีกสองรายการในการสแกนรีจิสทรี: RegEnumKey และ RegEnumValue
ยาว RegEnumKey(
HKEY hKey // จัดการรายการรีจิสทรีที่จะสแกน
DWORD dwIndex,//หมายเลขซีเรียลคีย์ย่อยที่จะสแกน
LPTSTR lpName,//ชื่อคีย์ย่อยที่จะสแกน
LPDWORD lpcbName // ชื่อคีย์ย่อยที่จะสแกนใช้พื้นที่
-
วิธีการใช้ฟังก์ชันนี้คือ ขั้นแรกให้กำหนด 0 ให้กับ dwIndex แล้วเรียก RegEnumKey จากนั้นจึงเรียก Inc(dwIndex) แล้วเรียก RegEnumKey จนกว่าค่าที่ส่งคืนจะเป็น ERROR_NO_MORE_ITEMS ซึ่งบ่งชี้ว่าไม่มีรายการย่อยอีกต่อไป
// ตัวอย่างการสแกนรีจิสทรี
//สาธิตวิธีการระบุรายการย่อยหนึ่งระดับภายใต้ HKEY_CURRENT_USER/Software เท่านั้น
ขั้นตอน TForm1.Button2Click (ผู้ส่ง: TObject);
var
buf : อาร์เรย์ [0..255] ของถ่าน;
iRes : จำนวนเต็ม;
hKeyx:HKEY;
dwIndex, dwSize: DWORD;
เริ่ม
ถ้า RegOpenKeyEx (HKEY_CURRENT_USER, 'ซอฟต์แวร์', 0, KEY_READ หรือ
KEY_ENUMERATE_SUB_KEYS, hKeyx ) <> ERROR_SUCCESS แล้ว
เริ่ม
Showmessage('RegOpenKeyEx ล้มเหลว');
ออก;
จบ;
dwดัชนี := 0;
ทำซ้ำ
dwSize := 255;
iRes := RegEnumKey( hKeyx, dwIndex, buf, dwSize );
ถ้า iRes = ERROR_NO_MORE_ITEMS แล้ว
หยุดพัก
อย่างอื่นถ้า iRes = ERROR_SUCCESS แล้ว
เริ่ม
Listbox1.Items.Add(buf);
Inc(dwIndex);
จบ;
จนกระทั่ง iRes <> ERROR_SUCCESS;
RegCloseKey( hKeyx );
จบ;