2009-05-05 2 views
18

Я новичок в WMI, и мне нужно реализовать RegistryValueChangeEvent в службе C#.Registry Watcher C#

Мне нужен обработчик событий, который запускается каждый раз при изменении любого из значений реестра. Мне нужно поведение, подобное событию FileSystemWatcher класса Changed, но для значений реестра.

Если есть какая-то другая техника, которую я мог бы использовать для выполнения той же задачи, я был бы признателен за это. Моим минимальным требованием является то, что это лучшее решение, чем то, что у меня есть сейчас: опрос каждые 20 секунд и сравнение значения реестра с последним результатом.

Просьба привести пример кода в вашем ответе. Если я могу получить пример для просмотра только одного значения реестра, все будет хорошо.

Мне нужно решение в .Net 2.0

Спасибо.

ответ

24

WMI иногда может быть интересно работать с ... Я думаю, что я понимаю ваш вопрос, так что посмотрим на фрагменте кода ниже и дайте мне знать, если это то, что вы» ищу.

// --------------------------------------------------------------------------------------------------------------------- 
// <copyright file="Program.cs" company=""> 
// 
// </copyright> 
// <summary> 
// Defines the WmiChangeEventTester type. 
// </summary> 
// --------------------------------------------------------------------------------------------------------------------- 
namespace WmiExample 
{ 
    using System; 
    using System.Management; 

    /// <summary> 
    /// </summary> 
    public class WmiChangeEventTester 
    { 
     /// <summary> 
     /// Initializes a new instance of the <see cref="WmiChangeEventTester"/> class. 
     /// </summary> 
     public WmiChangeEventTester() 
     { 
      try 
      { 
       // Your query goes below; "KeyPath" is the key in the registry that you 
       // want to monitor for changes. Make sure you escape the \ character. 
       WqlEventQuery query = new WqlEventQuery(
        "SELECT * FROM RegistryValueChangeEvent WHERE " + 
        "Hive = 'HKEY_LOCAL_MACHINE'" + 
        @"AND KeyPath = 'SOFTWARE\\Microsoft\\.NETFramework' AND ValueName='InstallRoot'"); 

       ManagementEventWatcher watcher = new ManagementEventWatcher(query); 
       Console.WriteLine("Waiting for an event..."); 

       // Set up the delegate that will handle the change event. 
       watcher.EventArrived += new EventArrivedEventHandler(HandleEvent); 

       // Start listening for events. 
       watcher.Start(); 

       // Do something while waiting for events. In your application, 
       // this would just be continuing business as usual. 
       System.Threading.Thread.Sleep(100000000); 

       // Stop listening for events. 
       watcher.Stop(); 
      } 
      catch (ManagementException managementException) 
      { 
       Console.WriteLine("An error occurred: " + managementException.Message); 
      } 
     } 

     /// <summary> 
     /// </summary> 
     /// <param name="sender"> 
     /// The sender. 
     /// </param> 
     /// <param name="e"> 
     /// The e. 
     /// </param> 
     private void HandleEvent(object sender, EventArrivedEventArgs e) 
     { 
      Console.WriteLine("Received an event."); 
      // RegistryKeyChangeEvent occurs here; do something. 
     } 

     /// <summary> 
     /// </summary> 
     public static void Main() 
     { 
      // Just calls the class above to check for events... 
      WmiChangeEventTester receiveEvent = new WmiChangeEventTester(); 
     } 
    } 
} 
+0

Именно это я и ищу. Я попробую и дам вам знать, как это работает. –

+0

Отлично, Андрей. Дайте мне знать, если у вас возникнут проблемы с повторным назначением для вашего собственного использования. Вы можете запросить меня на AIM, если хотите - e4lt0rf3R (замените цифры буквами). Я буду рад помочь вам решить любые дополнительные вопросы, которые у вас есть, а затем опубликовать их резюме. –

+0

Извините за комментарий к «старому» ответу, но есть ли способ в этом примере, который работает для HKEY_CURRENT_USER – SomeNickName

0

Вам понадобится использовать WMI для этого. См. http://msdn.microsoft.com/en-us/library/aa393035.aspx

+0

Ha ... Я знаю. Это та часть, в которой мне нужна помощь. –

+0

Я изменил формулировку своего вопроса, чтобы отразить то, что мне действительно нужно. Любая дополнительная помощь? –

3

Вы ограничены WMI? Если вы не можете использовать RegNotifyChangeKeyValue оберток как RegistryMonitor

+0

Нет Я не ограничен WMI, это единственный метод, который я знал во время публикации. Спасибо за ссылки. Они полезны. Не могли бы вы предоставить примерный код? –

+1

Вы действительно ленивы, что не можете щелкнуть ссылку RegistryMonitor и загрузить zip-файл из CodeProject ?? –

+2

Не будем грубыми, ребята. Вопрос задан для примера кода; также следует иметь в виду, что некоторые ссылки становятся устаревшими, и примерный код будет заархивирован здесь в обозримом будущем. :) –

2

Вам действительно не нужен WMI, как указывали другие. Я тоже без проблем использовал RegistryMonitor.

Если вам нужен пример, для самого RegistryMonitor уже есть пример кода. Просканировали ли вы до этого бита в проекте кода:

public class MonitorSample 
{ 
    static void Main() 
    { 
     RegistryMonitor monitor = new 
      RegistryMonitor(RegistryHive.CurrentUser, "Environment"); 
     monitor.RegChanged += new EventHandler(OnRegChanged); 
     monitor.Start(); 

     while(true); 

     monitor.Stop(); 
    } 

    private void OnRegChanged(object sender, EventArgs e) 
    { 
     Console.WriteLine("registry key has changed"); 
    } 
} 
+1

Да, я это сделал, но ... он не отвечает требованиям моего вопроса. Мне нужен пример кода для события, которое запускается при изменении определенного реестра _VALUE_; не ключ. Я понимаю, что могу получить это от RegistryMonitor, но если кто-то хочет сэкономить мое время, у них есть много, чтобы выиграть. –