Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
0 / 0 / 0
Регистрация: 20.07.2016
Сообщений: 22
1

Удаление ключа реестра через DeleteKey

25.07.2016, 18:31. Показов 2628. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
День добрый. Такая проблема - не могу удалить ключ реестра через DeleteKey, в котором ключ указан переменной типа String.
Процедура удаления
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
procedure TForm1.Deleter(key, path, listboxstr: String; count: integer;
  ListBox: TListBox);
 
var
Reg : TRegistry;
begin
   Reg:=TRegistry.Create;
   Reg.RootKey:=HKEY_LOCAL_MACHINE;
   if AnsiPos(key,listboxstr)>0 then 
   begin
   Reg.OpenKey(path, false);
   Reg.DeleteKey(listboxstr);
   Reg.CloseKey;
   end;
end;
Вызов процедуры
Delphi
1
Deleter('','SYSTEM\CurrentControlSet\Control\Print\Environments\Windows NT x86\Print Processors\',listbox4.Items.Strings[j],listbox4.items.count-1,listbox4);
Все нужные значения в переменных есть, пути реестра верны, все что нужно в листбоксы выводит. Проблема только в самом удалении ключей - они не удаляются, когда в DeleteKey выводится переменная типа String. Если прописывать ключ вручную, все удаляется. Как можно осуществить удаление через переменную?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.07.2016, 18:31
Ответы с готовыми решениями:

Удаление ключей реестра через Delphi
День добрый. Нужно удалить ключи реестра с неопределенными именами в Delphi. Например, данный код...

Чтение ключа реестра
Необходимо написать функцию или процедуру, которая бы считывала ключ из реестра, и при запуске...

Получение значений ключа реестра
Ниже представлена процедура чтения и вывода в ListView значений ключа реестра. В чем проблема...

Доступность чтения ключа из реестра
Всем привет. Нужно узнать какие ключи и ветки в реестре даны для чтения когда я с ограниченной...

8
Заблокирован
25.07.2016, 19:02 2
Код
procedure TForm1.DeleteKey(key, listboxstr: String; count: integer;
  ListBox: TListBox);
var
  Reg : TRegistry;
begin
  if AnsiPos(key,listboxstr)=0 then exit; // если строка не найдена, сразу выходим из процедуры.
  Reg:=TRegistry.Create; // создаётся объект. он занимает место в памяти, и после использования должен быть удален.
  try
    Reg.RootKey:=HKEY_LOCAL_MACHINE; 
    Reg.DeleteKey(listboxstr);
    reg.free; // освобождение ресурсов
  end;
end;

Пример: имеем ключ: Software\Boro-Boro\123. При вызове DeleteKey будет удален подраздел "123"
0
0 / 0 / 0
Регистрация: 20.07.2016
Сообщений: 22
27.07.2016, 19:29  [ТС] 3
Спасибо, работает!
Еще есть пару вопросов по той же программе:

1) Не могу записать несколько строк в параметр реестра.

Delphi
1
2
3
4
5
6
7
8
9
10
Reg.RootKey := HKEY_LOCAL_MACHINE;
Reg.OpenKey('SYSTEM\CurrentControlSet\Services\Spooler\', false);
Reg.WriteString('DependOnService','RPCSS');
Reg.WriteString('RequiredPrivileges','SeTcbPrivilege ' +#10 + #13+
                                      'SeImpersonatePrivilege ' +#13#10+
                                      'SeAuditPrivilege '     +#13#10+
                                      'SeChangeNotifyPrivilege ' +#13#10+
                                      'SeAssignPrimaryTokenPrivilege ' +#13#10 +
                                      'SeLoadDriverPrivilege ');
Reg.CloseKey;
Записывает все значения через пробел, а нужно, чтобы каждое значение писалось с новой строки. Не подскажите как это сделать?

Пробовал через \n, #10+#13, #13+#10 - ничего не помогает.

2) В данном фрагменте кода

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Reg.RootKey:=HKEY_CURRENT_USER;
   Reg.OpenKey('Printers\', true);
   Reg.GetKeyNames(ListBox5.Items);
 
   for j:=0 To ListBox5.Items.Count-1 Do begin
  if pos('Connections',ListBox5.Items.Strings[j])> 0 then
   begin
   ListBox5.Selected[j]:=True;
   ListBox5.DeleteSelected;
   end;
  if pos('DevModePerUser',ListBox5.Items.Strings[j])> 0 then
   begin
   ListBox5.Selected[j]:=True;
   ListBox5.DeleteSelected;
   end;
  if pos('DevModes2',ListBox5.Items.Strings[j])> 0 then
   begin
   ListBox5.Selected[j]:=True;
   ListBox5.DeleteSelected;
   end;
  if pos('Settings',ListBox5.Items.Strings[j])> 0 then
   begin
   ListBox5.Selected[j]:=True;
   ListBox5.DeleteSelected;
   end;
   Reg.GetKeyNames(ListBox5.Items);
   end;
 
   if listbox5.Items.Count >0 then
    for j:=0 To ListBox5.Items.Count-1 Do begin
   Reg.DeleteKey('Printers\'+ listbox5.Items.Strings[j]);
   end;
В разных частях кода (условиях) выводит ошибку ListBox out of bounds ("цифра").
Понимаю, что ругается скорее всего на обращение к несуществующим строкам, но не могу понять, в чем проблема алгоритма. Спасибо.
0
Хитрая блондиночка $)
1472 / 988 / 399
Регистрация: 21.12.2015
Сообщений: 3,785
27.07.2016, 19:51 4
Цитата Сообщение от X_MisterX_X Посмотреть сообщение
Записывает все значения через пробел, а нужно, чтобы каждое значение писалось с новой строки. Не подскажите как это сделать?
По-моему тебе нужен метод WriteBinaryData а не WriteString, если хочешь писать многострочный параметр.
Цитата Сообщение от X_MisterX_X Посмотреть сообщение
В разных частях кода (условиях) выводит ошибку ListBox out of bounds ("цифра").
Скорее всего из-за
Цитата Сообщение от X_MisterX_X Посмотреть сообщение
Reg.GetKeyNames(ListBox5.Items);
который помещен внутрь цикла, и я бы сказала "нарушает его целостность".
0
Заблокирован
27.07.2016, 21:57 5
С прискорбием обнаружил, что в классе TRegistry (седьмая дельфи) возможность работать с REG_MULTI_SZ - напрочь отсутствует. Возможно, этот тип ключей - нововведение, которого не было на момент разработки делфи.

Вот код юнита, который расширяет возможности TRegistry.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
unit RegistryEx;
 
interface
 
uses Registry, Classes, Windows, SysUtils;
 
type
  TRegistry = class(Registry.TRegistry)
  public
    procedure ReadStrings(const Name: string; List:TStrings);
    procedure WriteStrings(const Name: string; List: TStrings);
  end;
 
implementation
 
uses RTLConsts;
 
procedure ReadError(const Name: string);
begin
  raise ERegistryException.CreateResFmt(@SInvalidRegType, [Name]);
end;
 
procedure TRegistry.WriteStrings(const Name: string; List: TStrings);
var
  Buffer: Pointer;
  BufSize: DWORD;
  I, J, K: Integer;
  S: string;
  P: PChar;
begin
  BufSize := 0;
  for I := 0 to List.Count - 1 do
  Inc(BufSize, Length(List[I]) + 1);
  Inc(BufSize);
 
  Buffer:=AllocMem(BufSize);
  try
    K := 0;
    P := Buffer;
    for I := 0 to List.Count - 1 do
    begin
      S := List[I];
      for J := 0 to Length(S) - 1 do
      begin
        P[K] := S[J + 1];
        Inc(K);
      end;
      P[K] := #0;
      Inc(K);
    end;
    P[K]:=#0;
    if RegSetValueEx(CurrentKey, PChar(name), 0, REG_MULTI_SZ, Buffer, BufSize) <> ERROR_SUCCESS then
    raise ERegistryException.CreateResFmt(@SRegGetDataFailed, [Name]);
  finally
    FreeMem(Buffer);
  end;
end;
 
procedure TRegistry.ReadStrings(const Name: string; List:TStrings);
var
  BufSize,
  DataType: DWORD;
  Len, I: Integer;
  Buffer, P: PChar;
  S: string;
begin
  List.clear;
  Len := GetDataSize(Name);
  if Len < 1 then
  Exit;
  Buffer := AllocMem(Len);
  try
    DataType := REG_NONE;
    BufSize := Len;
    if RegQueryValueEx(CurrentKey, PChar(name), nil, @DataType, PByte(Buffer),@BufSize) <> ERROR_SUCCESS then
    raise ERegistryException.CreateResFmt(@SRegGetDataFailed, [Name]);
    if DataType <> REG_MULTI_SZ then
    ReadError(Name);
    S := '';
    P:=Buffer;
 
    if P^=#0 then exit;
 
    while true do
    begin
      if (P^=#0) then
      begin
        Inc(P);
        if (P^=#0) then exit;
      end;
 
      SetString(S,P,StrLen(P));
      List.Add(S);
      Inc(P,StrLen(P));
    end;
  finally
    FreeMem(Buffer);
  end;
end;
 
end.
0
0 / 0 / 0
Регистрация: 20.07.2016
Сообщений: 22
28.07.2016, 17:40  [ТС] 6
Не могу реализовать через WriteBinaryData.
Сделал так: записываю строки в массив типа string, и записываю его в реестр. Прочитал об это на разных форумах, но точной реализации записи именно строк там нет.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
var
B: array [1..6] of string;
...
begin
B[1]:='SeTcbPrivilege';
B[2]:='SeImpersonatePrivilege';
B[3]:='SeAuditPrivilege';
B[4]:='SeChangeNotifyPrivilege';
B[5]:='SeAssignPrimaryTokenPrivilege';
B[6]:='SeLoadDriverPrivilege';
...
Reg.WriteBinaryData('RequiredPrivileges',B, sizeof(B));
В итоге записывает в параметр такое значение (на картинке):
Удаление ключа реестра через DeleteKey


Можете подправить, как правильно это сделать? Массив типа byte не могу сделать, строки туда не переводятся.

Теперь вопрос с листбоксами.
Скорее всего из-за
Цитата Сообщение от X_MisterX_X Посмотреть сообщение
Reg.GetKeyNames(ListBox5.Items);
который помещен внутрь цикла, и я бы сказала "нарушает его целостность".
Эту функцию я поместил туда уже после возникновения ошибки, думал поможет обновление оставшихся строк в листбоксе.
Удалил сейчас, ошибка осталась.

Заметил такую вещь: в данном коде в цикле выполняются подряд 3 условия - сразу три строки из листбокса удаляются. Больше ключей там нет - листбокс становится пустым. как раз на 4 условии выскакивает ошибка.
Попробовал решить следующим образом через счетчик "k" - все получилось, удаляет то, что нужно.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
Reg.RootKey:=HKEY_CURRENT_USER;
   Reg.OpenKey('Printers\', true);
   Reg.GetKeyNames(ListBox5.Items);
 
   for j:=0 To ListBox5.Items.Count-1 Do begin
    k:=listbox5.items.count;
  if pos('Connections',ListBox5.Items.Strings[j])> 0 then
   begin
   ListBox5.Selected[j]:=True;//âûáèðàåì ñòðîêó ¹5(âìåñòî 5 ïèøèòå ñâîé íîìåð)
   ListBox5.DeleteSelected;
   k:=k-1;
   if k=0 then break;
   end;
  if pos('DevModePerUser',ListBox5.Items.Strings[j])> 0 then
   begin
   ListBox5.Selected[j]:=True;//âûáèðàåì ñòðîêó ¹5(âìåñòî 5 ïèøèòå ñâîé íîìåð)
   ListBox5.DeleteSelected;
   k:=k-1;
   if k=0 then break;
   end;
  if pos('DevModes2',ListBox5.Items.Strings[j])> 0 then
   begin
   ListBox5.Selected[j]:=True;//âûáèðàåì ñòðîêó ¹5(âìåñòî 5 ïèøèòå ñâîé íîìåð)
   ListBox5.DeleteSelected;
   k:=k-1;
   if k=0 then break;
   end;
  if pos('Settings',ListBox5.Items.Strings[j])> 0 then
   begin
   ListBox5.Selected[j]:=True;//âûáèðàåì ñòðîêó ¹5(âìåñòî 5 ïèøèòå ñâîé íîìåð)
   ListBox5.DeleteSelected;
   k:=k-1;
   if k=0 then break;
   end;
   end;
 
   if listbox5.Items.Count >0 then
    for j:=0 To ListBox5.Items.Count-1 Do begin
   Reg.DeleteKey('Printers\'+ listbox5.Items.Strings[j]);
   end;
Нынче проблема в идентичном коде для listbox3:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
   Reg.OpenKey('SYSTEM\CurrentControlSet\Control\Print\Monitors\', true);
   Reg.GetKeyNames(ListBox3.Items);
     k:=listbox3.items.count;
   for j:=0 To ListBox3.Items.Count-1 Do begin
   if pos('Document Writer Monitor',ListBox3.Items.Strings[j])> 0 then
   begin
   ListBox3.Selected[j]:=True;//âûáèðàåì ñòðîêó ¹5(âìåñòî 5 ïèøèòå ñâîé íîìåð)
   ListBox3.DeleteSelected;
   k:=k-1;
   if k=0 then exit;
   end;
   if pos('Local Port',ListBox3.Items.Strings[j])> 0 then
   begin
   ListBox3.Selected[j]:=True;//âûáèðàåì ñòðîêó ¹5(âìåñòî 5 ïèøèòå ñâîé íîìåð)
   ListBox3.DeleteSelected;
      k:=k-1;
   if k=0 then break;
   end;
 
   if pos('Standard TCP/IP Port',ListBox3.Items.Strings[j])> 0 then
   begin
   ListBox3.Selected[j]:=True;//âûáèðàåì ñòðîêó ¹5(âìåñòî 5 ïèøèòå ñâîé íîìåð)
   ListBox3.DeleteSelected;
      k:=k-1;
   if k=0 then break;
   end;
   if pos('USB Monitor',ListBox3.Items.Strings[j])> 0 then
   begin
   ListBox3.Selected[j]:=True;//âûáèðàåì ñòðîêó ¹5(âìåñòî 5 ïèøèòå ñâîé íîìåð)
   ListBox3.DeleteSelected;
      k:=k-1;
   if k=0 then break;
   end;
    if pos('WSD Port',ListBox3.Items.Strings[j])> 0 then
   begin
   ListBox3.Selected[j]:=True;//âûáèðàåì ñòðîêó ¹5(âìåñòî 5 ïèøèòå ñâîé íîìåð)
   ListBox3.DeleteSelected;
      k:=k-1;
   if k=0 then break;
   end;
if pos('Microsoft Office Live Meeting',ListBox3.Items.Strings[j])> 0 then
   begin
   ListBox3.Selected[j]:=True;//âûáèðàåì ñòðîêó ¹5(âìåñòî 5 ïèøèòå ñâîé íîìåð)
   ListBox3.DeleteSelected;
      k:=k-1;
   if k=0 then break;
   end;
 
if pos('Microsoft Shared Fax Monitor',ListBox3.Items.Strings[j])> 0 then
   begin
   ListBox3.Selected[j]:=True;//âûáèðàåì ñòðîêó ¹5(âìåñòî 5 ïèøèòå ñâîé íîìåð)
   ListBox3.DeleteSelected;
      k:=k-1;
   if k=0 then break;
   end;
 
end;
    if listbox3.items.count-1 > 0 then
    for k:=0 to listbox3.items.count-1  do begin
    Deleter(listbox3.items.strings[k],'SYSTEM\CurrentControlSet\Control\Print\Monitors\',listbox3.Items.Strings[k],listbox3.items.count-1,listbox3);
   end;
Пройдясь по условиям, удаляет из списка нужные папки, оставляет пробные для удаления как и нужно, только дальше не идет, ссылаясь на "listbox out of bounds (2)".

Можете подсказать, где изъян? Потому что вроде в одном месте алгоритм работает, в другом - нет.
Спасибо!
0
Хитрая блондиночка $)
1472 / 988 / 399
Регистрация: 21.12.2015
Сообщений: 3,785
28.07.2016, 17:54 7
Цитата Сообщение от X_MisterX_X Посмотреть сообщение
Можете подправить, как правильно это сделать?
Значит этот класс действительно не научили работать с многострочным параметром.
Цитата Сообщение от X_MisterX_X Посмотреть сообщение
Можете подсказать, где изъян?
Опиши цикл так:
Delphi
1
for j:=ListBox3.Items.Count downto 0 Do begin
0
Заблокирован
28.07.2016, 21:12 8
Цитата Сообщение от X_MisterX_X Посмотреть сообщение
Можете подправить, как правильно это сделать?
Цитата Сообщение от Hikari Посмотреть сообщение
Значит этот класс действительно не научили работать с многострочным параметром.
Настоятельно советую почитать справку. REG_BINARY совершенно не предназначен для хранения строк, там можно держать только массив байтов. На скрине всё в порядке, так и должно быть.
0
0 / 0 / 0
Регистрация: 20.07.2016
Сообщений: 22
29.07.2016, 15:33  [ТС] 9
Обошел я проблему с реестром. Как говорится, умный в гору не пойдет...=)

Более важный вопрос с листбоксом.
Еще долго сидел с ним, но так и не получается...

Имеем код:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
   Reg.OpenKey('SYSTEM\CurrentControlSet\Control\Print\Monitors\', true);
   Reg.GetKeyNames(ListBox3.Items);
     k:=listbox3.items.count-1;
   for j:= 0 to ListBox3.Items.Count-1 Do begin
   if pos('Document Writer Monitor',ListBox3.Items.Strings[j])> 0 then
   begin
   ListBox3.Selected[j]:=True;
   ListBox3.DeleteSelected;
   k:=k-1;
   if k=0 then break;
   end;
   if pos('Local Port',ListBox3.Items.Strings[j])> 0 then
   begin
   ListBox3.Selected[j]:=True;
   ListBox3.DeleteSelected;
      k:=k-1;
   if k=0 then break;
   end;
   if pos('Standard TCP/IP Port',ListBox3.Items.Strings[j])> 0 then
   begin
   ListBox3.Selected[j]:=True;
   ListBox3.DeleteSelected;
      k:=k-1;
   if k=0 then break;
   end;
   if pos('USB Monitor',ListBox3.Items.Strings[j])> 0 then
   begin
   ListBox3.Selected[j]:=True;
   ListBox3.DeleteSelected;
      k:=k-1;
   if k=0 then break;
   end;
    if pos('WSD Port',ListBox3.Items.Strings[j])> 0 then
   begin
   ListBox3.Selected[j]:=True;
   ListBox3.DeleteSelected;
      k:=k-1;
   if k=0 then break;
   end;
if pos('Microsoft Office Live Meeting',ListBox3.Items.Strings[j])> 0 then
   begin
   ListBox3.Selected[j]:=True;
   ListBox3.DeleteSelected;
      k:=k-1;
   if k=0 then break;
   end;
 
if pos('Microsoft Shared Fax Monitor',ListBox3.Items.Strings[j])> 0 then
   begin
   ListBox3.Selected[j]:=True;
   ListBox3.DeleteSelected;
      k:=k-1;
   if k=0 then break;
   end;
 
end;
    if listbox3.items.count > 0 then
    for k:=0 to listbox3.items.count-1  do begin
  //  Deleter(listbox3.items.strings[k],X,listbox3.Items.Strings[k],listbox3.items.count-1,listbox3);
    Reg.DeleteKey('SYSTEM\CurrentControlSet\Control\Print\Monitors\'+ listbox3.Items.Strings[k]);
   end;
В ключе находятся все папки из условий цикла + 3 пробных (их надо удалить)
Программа выводит в листбокс эти три папки (что и должно быть) и останавливается с ошибкой listbox out of bounds (3).
Количество нужных и пробных папок менял - аналогично в листбокс выводит как надо и выдает ту же ошибку с разными цифрами.

Замена "j:= listbox3.items.count downto 0 de begin" не помогла.
Пробовал по данному коду даже новый проект создать - не помогает.

Друзья, выручайте.
0
29.07.2016, 15:33
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.07.2016, 15:33
Помогаю со студенческими работами здесь

Удаление ключа из реестра
Мужики появилась проблема хочу удалить ключ из реестра но компилятор не видит этот ключ но он ЕСТЬ....

Удаление ключа реестра
Решил автоматизировать процесс удаления некоторых значений в реестре написал такое: #include...

Удаление защищенного ключа реестра
Нужный ключ с реестра не удаляется, вроде всё правильно. + Вин 8.1 и вручную с реестра тоже не...

Проверка наличия определённого ключа реестра и добавление этого ключа в реестр при его отсутствии
Добрый день! Пытаюсь разобраться с bat файлом, который будет запускаться при старте системы и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru