C#. Удаление значений (values) из ключа Реестра

Преамбула

Задача довольно простая, имеется ключ в разделе Реестра Windows, необходимо удалить оттуда все значения (values).

Термины и определения

Реестр — иерархическая база данных, хранящая основные настройки системы и программ.
Корневой ключ (в некоторых источниках просто ключ или раздел Реестра), это один из основных ключей Реестра. Обычно присутствуют следующие:

HKEY_CLASSES_ROOT (HKCR) — Зарегистрированные типы файлов, объекты COM и ActiveX
HKEY_CURRENT_USER (HKCU) — Настройки текущего пользователя, в данный момент вошедшего в систему.
HKEY_LOCAL_MACHINE (HKLM) — Общие настройки для всех пользователей данного компьютера.
HKEY_USERS (HKU) — Профили всех пользователей данной машины.
HKEY_CURRENT_CONFIG (HKCC) — Профили оборудования, информация о драйверах.

Подключ/Subkey (иногда Ключ, если корневой раздел называется корневым разделом или корневым ключом) Реестра — путь в Реестре, аналогичный пути к каталогу (папке) файловой системы. Обычно каждый подключ хранит или настройки для конкретного случая. Например, настройки конкретной программы или профиль конфигурации оборудования. Выглядит примерно так: Software\TestKey (в полном виде, вместе с корневым ключом, например: HKEY_CURRENT_USER\Software\TestKey).

Подключ может содержать как и другие подключи, так и значения (values), представляющие собой поименованные переменные, содержащие значения конкретного параметра

Обзорная статья про Реестр Windows на Википедии

Тестовый ключ

Для тестирования создадим тестовый ключ, который не будет влиять на какие либо программы и компоненты ОС. Это можно сделать, как вручную, с помощью программы Regedit, так и в автоматическом режиме, с помощью reg-файла, например, такого:

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\TestKey]
"value0"="text0"
"value1"="text1"
"value2"="text2"
"value3"="text3"
"value4"="text4"
"value5"="text5"

Файл на GitHub

Можно создать и reg-файл для удаления тестового ключа из Реестра, если что-то пойдет не так:

Windows Registry Editor Version 5.00

[-HKEY_CURRENT_USER\Software\TestKey]

Файл на GitHub

Решение

1. Подключаем пространство имен Microsoft.Win32:

using Microsoft.Win32;

2. Создаем переменную с именем подключа Реестра и переменную типа RegistryKey. Этот объект и будет рулить нужной веткой Реестра:

string subkey = "Software\\TestKey";
RegistryKey key = null;

3. Любые операции с Реестром могут привести к ошибкам, потому их как и операции ввода-вывода желательно оборачивать в try..catch:

try
{
    //тут будет код.
}
catch (Exception ex)
{
    Console.WriteLine("ERROR: " + ex.Message);
}

4. Открываем (под)ключ Реестра:

key = Registry.CurrentUser.OpenSubKey(subkey, true);

Внимание! Если необходимо писать в ключ Реестра, обязательно устанавливаем второй параметр функции OpenSubKey в true, т.к. в противном случае, мы получим ошибку UnauthorizedAccessException: Не удалось выполнить запись в раздел реестра.

Обсуждение на Cyberforum

5. Получить список значений в (под)ключе можно функцией GetValueNames(), которая выдает строковый массив с именами значений Реестра.

6. Получаем имена всех значений и в цикле удаляем их с помощью функции DeleteValue(имя_параметра);

foreach (string valname in key.GetValueNames())
{
    Console.WriteLine("Delete value: " + valname);
    key.DeleteValue(valname);
}

7. Закрываем (под)ключ Реестра.

key.Close();

Все получилось:

Код целиком

На PasteBin

Тестовый пример

Пример на GitHub

C#, генератор файлов (нужного количества и с определенным содержимым).

Описание задачи

Итак, требуется написать программу, которая генерирует заданное количество файлов с определенным содержимым. Содержимое задается или в качестве байтового паттерна (т.е. если программе указать 0xFF, то файл будет заполнен указанным количеством байт со значением 0xFF) или случайных байт. Файлам также можно задать расширение, или сделать и имя файла случайным.

Программа

Выполнена в виде консольной программы, запускаемой со следующими параметрами:

Использование: filegen.exe <количество_файлов> <размер>[K|M|G] <расширение|/R> [байтовый_паттерн|/R]

<количество_файлов> - количество файлов
<размер> - размер:

   по умолчанию - байты
   K - килобайты
   M - мегабайты
   G - гигабайты

<расширение> - расширение файла или /R - случайное имя файла
[байтовый_паттерн] - байтовый паттерн (HEX): от 0x00 до 0xFF, по умолчанию 0x00 или /R случайные байты

Использованные алгоритмы

1. С#, Заполнение массива одним значением. (копия)
2. C#, заполнение массива случайными числами. (копия)
3. C#, Количество цифр (разрядов) числа. (копия)
4. C#. Перевод кило- мега- и гигабайтов в байты. (копия)

Пример программы

На GitHub

C#. Перевод кило- мега- и гигабайтов в байты

Преамбула

Простая учебная задача, но почему-то до моего решения долюбились, в конце объясню, почему долюбились, и почему, в случае C#, это зря было.

Решение

И так, задача состоит в том, чтобы всякие кратные единицы перевести в байты (кому надо обратную задачу, либо все во все — пишите в комментарии). Для этого достаточно сделать следующую функцию, исходя из того, что 1 Кб == 1024 Б, 1 Мб = 1024 Кб, 1 Гб = 1024 Мб. В функцию добавим некую переменную-модификатор, для консольного приложения было проще сделать строковую, в ином случае, может и есть сделать отдельный Enum для единиц, но я обошелся строковой.
Переменная-модификатор (modificator) принимает строковые значения G(g), M(m) и K(k), соответственно для гига- мега- и килобайта.

Функция получается такая:

public static ulong ToBytes(ulong bytes, string modificator)
{
    ulong Ret = 0;
    switch (modificator)
    {
        case "":
            {
                Ret = bytes;
            } break;
        case "K":
        case "k":
            {
                Ret = bytes * 1024;
            } break;
        case "M":
        case "m":
            {
                Ret = bytes * 1024 * 1024;
            } break;
        case "G":
        case "g":
            {
                Ret = bytes * 1024 * 1024 * 1024;
            } break;
        default:
            {
                throw new ArgumentException("Wrong modificator ["
                    + modificator + "]. Set K(k), M(m), G(g)");
            }                    
    }

    return Ret;
}

Почему не стал заморачиваться с Enum’ом

Задача была очень простая, чисто учебная. Консольная программа принимает в качестве одного параметра число с единицей без пробела, т.е. команда вида program.exe 10G, должна вывести количество байт. Надо ли Enum городить, ну красиво было бы, но до Enum‘ов они не добрались 🙂

В основной программе надо отрезать последний символ из параметра, проверить ли является он нужной буквой (K/M/G) и пересчитать. Если буквы нету, а только цифры — значит оно уже сразу байты.

В функции Main() отрезаем последний символ от первого параметра командной строки, если он K/M/G, считаем, что все остальное число, отрезаем его, а все остальное пытаемся сконвертировать в ulong (Int64) и передать функции ToBytes() с отрезанным символом, как модификатором для расчета. Если нет — просто считаем, что вся строка число, пытаемся конвертировать, а функции передаем пустой модификатор.

Ошибки конвертации ловим try/catch:

string size_s = args[1];

try
{
    string mdf = size_s.Substring(size_s.Length - 1, 1);
    if ((mdf != "K") && (mdf != "k") && (mdf != "M") && (mdf != "m") &&
        (mdf != "G") && (mdf != "g"))
    {
        mdf = "";
        //in parameter only numbers or param wrong...
    }
    else // remove modificator
    {
        size_s = size_s.Substring(0, size_s.Length - 1);
    }
    BytesCount = ToBytes(Convert.ToUInt64(size_s), mdf);
}
catch (Exception ex)
{
    Console.WriteLine("Wrong <size> parameter!");
    Console.WriteLine(ex.Message);
    Console.Write("Press Enter...");
    Console.ReadLine();
    return 2;
}

Пример целиком на GitHub

Почему долюбились

За вот эти вот конструкции:

Ret = bytes * 1024;
Ret = bytes * 1024 * 1024;
Ret = bytes * 1024 * 1024 * 1024;

Типа «ну тут числа, ты бы их сначала перемножил, результат записал , а потом на переменную помножил».

Почему зря.

Дебилы, бля, как говорил Лавров. В интерпретируемых языках или старом Трупопоскакале под DOS, может это и какой-то рояль играет, но в C# компилятор перемножает константы до сборки экзешника, а 1024*1024*1024 для компилятора константы, во время компиляции. Т.е. процессору скормят 1073741824. А код останется более понятен и читабелен.