Удаление разделов реестра в цикле

441
10 августа 2017, 21:00

Подскажите можно как-нибудь удалить разделы реестра используя List<string> ?

static List<string> LoggerSearch = new List<string>()
{
    @"HKEY_CURRENT_USER\Software\Logger",
    @"HKEY_LOCAL_MACHINE\SOFTWARE\Logger"
};

Если стандартно используется такая схема:

Registry.LocalMachine.DeleteSubKeyTree(LoggerPath, true);

Почему именно в цикле? ( отвечаю )

У меня не получается удалить 2 раздела реестра в такой последовательности:

Registry.LocalMachine.DeleteSubKeyTree(LoggerPath, true);
Registry.CurrentUser.DeleteSubKeyTree(LoggerPath, true);

Если только использовать для каждого try/catch но как-то это не культурно =)

P.S: Как прогнать в цикле for список LoggerSearch

В таком виде: Registry.DeleteSubKeyTree(LoggerSearch[i]); ?

Answer 1

1. Плохая новость

.NET не предоставляет средств простым и удобным способом перебирать произвольные ключи из произвольных кустов реестра. В пределах одного куста (например HKLM) - пожалуйста, если нужны разные кусты - нет. WMI - тоже самое.

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

2. Относительно хорошая новость

Если все таки очень хочется цикл (например для длинных списков ключей) и не хочется обрабатывать каждый куст по-отдельности, то один вариант есть.

Можно использовать консольную команду REG DELETE для работы с реестром прямо из приложения. В коде это может выглядеть так:

foreach(var key in LoggerSearch)
{
    var psi = new ProcessStartInfo("REG", @"DELETE {key} /f");
    //ключ /f подавляет запрос подтверждения операции
    psi.UseShellExecute = false;//глушим мелькание консоли
    Process.Start(psi);
}

На ваше усмотрение, можно перенаправить стандартный поток вывода в файл или еще куда-нибудь, и фиксировать текстовые сообщения о результатах операции. Также можно узнать результат завершения операции если дождаться окончания выполнения процесса и прочитать его свойство Process.ExitCode, только не пытайтесь его читать сразу после выполнения Process.Start, это приведет к исключению, оно доступно только после завершения процесса.

В общем-то таким не слишком хитрым способом с помощью утилиты REG можно выполнять в реестре все. Мне такой способ не нравится, но он работает, выбирать вам.

Answer 2
string keyName = @"HKEY_CURRENT_USER\Software\Logger";
string[] hiveAndName = keyName.Split(new[]{'\\'}, 2);
RegistryKey root;
if ("HKEY_CURRENT_USER".Equals(hiveAndName[0], StringComparison.OrdinalIgnoreCase)) root = Registry.CurrentUser;
// else if ... // TODO
root.DeleteSubKeyTree(hiveAndName[1], false);

Так же нужно не забывать что 2-ой параметр должен быть false).

С использованием циклов:

for (var j = 0; j < LoggerSearch.Count; j++)
{
   string[] hiveAndName = LoggerSearch[j].Split(new[] { '\\' },2);
   if("HKEY_CURRENT_USER".Equals(hiveAndName[0],StringComparison.OrdinalIgnoreCase))
   {
      root = Registry.CurrentUser;
      root.DeleteSubKeyTree(hiveAndName[1], false);
   }
   else if ("HKEY_LOCAL_MACHINE".Equals(hiveAndName[0], StringComparison.OrdinalIgnoreCase))
   {
      root = Registry.LocalMachine;
      root.DeleteSubKeyTree(hiveAndName[1], false);
   }
}
READ ALSO
Ajax.BeginForm не правильно конструирует Action?

Ajax.BeginForm не правильно конструирует Action?

Есть форма для добавления товара в корзину:

331
Ожидание в асинхронности

Ожидание в асинхронности

Есть абстрактный пример:

279
WPF. Максимальный размер текста в Label

WPF. Максимальный размер текста в Label

Нужна помощьКак узнать, какой размер шрифта (свойство FontSize) в Label будет максимальным для полного отображения (без каких-либо обрезаний букв...

383
Вывод коллекции

Вывод коллекции

Есть массив и список такого же типаВ цикле я изменяю массив и после каждого изменения добавляю его в список (по окончанию цикла хочу получить...

395