Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Считывание реестра


Автор: Bima 15.8.2006, 11:50
Добрый день!
Есть раздел в реестре:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\{E2850339-5E51-4BE7-8B70-926129663F31}\Parameters\Tcpip
в нем находится ключ: IPAddress. 
regedit показывает, что этот ключ имеет тип REG_MULTI_SZ.

Теперь сам вопрос, как можно считать этот параметр (если быть более точным, то как мне считать и преобразовать его в тип AnsiString)?
И второй вопрос, как модифицировать этот параметр?

Автор: _hunter 15.8.2006, 11:58
читай справку на предмет класса TRegistry вообще и его методов Read/WriteString в частности...

Автор: Bima 15.8.2006, 12:15
Очень полезный ответ!!!
Я спрашивал помощи, а не подобных советов.
Метод Read/WriteString применим только для строковых параметров. В regedit такие параметры отображаются  REG_SZ. При использовании подобного метода, моя программа выдает ошибку.

Автор: _hunter 15.8.2006, 12:29
во-первых: что за ошибка.
во-вторых: кто мешает воспользоваться ReadBinaryData/WriteBinaryData (это если подходящих методов нет)

Автор: Bima 15.8.2006, 12:57
При вызове процедуры ReadString (при работе программы) выдает ошибку, что тип переменной чтения неправильный.
При использовании метода ReadBinaryData тоже выдает ошибку "Failed tj get data for 'IPAddres'

Даже если я считаю эти данные, то каким образом мне их преобразовать в AnsiString.

Вот код подпрограммы:
Код

AnsiString NetKey;
int siz;
void *Buffer;
....
if (Reg->OpenKey("SYSTEM\\CurrentControlSet\\Services\\"+NetKey+"\\Parameters\\TcpIp",false))
   {
   siz=Reg->GetDataSize("IPAddress");
   EIp->Text=Reg->ReadBinaryData("IPAddress", Buffer, siz);
   }
else
   {
    // test
   }
Reg->CloseKey();


Автор: _hunter 15.8.2006, 13:13
дык а память под буффер кто выделять будет?
насчет преобразования:
Цитата

REG_MULTI_SZ 
Array of null-terminated strings that are terminated by two null characters. 

(MSDN)

Автор: dumb 15.8.2006, 13:30
Bima, внимательней читай хелп. третий параметр ReadBinaryData (у тебя - siz) - это не размер считываемых данных, а размер буфера для чтения.

и вообще... http://windowssdk.msdn.microsoft.com/en-us/library/ms691203.aspx smile

Добавлено @ 13:33 
http://www.codeproject.com/internet/

Автор: Bima 15.8.2006, 13:37
Цитата

Array of null-terminated strings that are terminated by two null characters

В том то вся и фигня, что через симол там ставится нулевой символ

у меня вот такой код:
Код

int siz;
void *Buffer;
char buf[128];
....
if (Reg->OpenKey("SYSTEM\\CurrentControlSet\\Services\\"+NetKey+"\\Parameters\\TcpIp",false))
   {
   siz=Reg->GetDataSize("IPAddress");
   Buffer=&buf;
   EIp->Text=Reg->ReadBinaryData("IPAddress", Buffer, siz);
   }
else
   {
    // test
   }
Reg->CloseKey();


но когда я смотрю char, то там такая мешанина символов, причем символов /0 очень много.
при просмотре выдает следущее:
1\09\02\0.\01\06\08 и так далее. отсюда угадывается адрес который я считываю 192.168.... но в поле EIp->Text отображается "26"

Автор: _hunter 15.8.2006, 13:42
в чем фигня -- так и не понял. что мешает строке иметь длинну в один символ?
+ тут не через символ а через число
++ приводил бы уже в HEX' е -- а то такое читать не особо приятно...

Автор: dumb 15.8.2006, 13:46
http://forum.vingrad.ru/index.php?act=Search&CODE=show&searchid=728e6704d3c1909fe636c18fc4103834&search_in=posts&result_type=posts&flag=search&debug=&highlite=widechartomultibyte&skipped=. смотри объяснение своим "нулям" в третьем найденном посте.

Автор: Bima 15.8.2006, 15:15
Пока все получилось, привожу код который я использовал:
Код

int siz;
char buf[128];
....
if (Reg->OpenKey("SYSTEM\\CurrentControlSet\\Services\\"+NetKey+"\\Parameters\\TcpIp",false))
   {
   siz=Reg->GetDataSize("IPAddress");
   Reg->ReadBinaryData("IPAddress", buf, siz);
   EIp->Text=buf;   
   }
else
   {
    // test
   }
Reg->CloseKey();

а вот код для записи параметра:
Код

AnsiString adr;
int siz;
char buf[128];
....
if (Reg->OpenKey("SYSTEM\\CurrentControlSet\\Services\\"+NetKey+"\\Parameters\\TcpIp",false))
   {
   adr=EIp->Text+'\0'+'\0';
   adr.WideChar(buf, adr.Length());
   siz=2*adr.Length()-2;
   Reg->WriteBinaryData("IPAddress", buf, siz);
   }
Reg->CloseKey();


Вроде все работает, но если есть советы по оптимизации кода - всегда выслушаю.

Автор: Bima 15.8.2006, 15:32
Блин, в 98 работает, а в ХР не хочет smile

Автор: _hunter 15.8.2006, 15:41
пересобери на машине с XP

Автор: Bima 16.8.2006, 14:15
Пересобрал, но выявил новый глюк:
Когда я делаю запись, то в реестре вместо ключа REG_MULTI_SZ, появляется ключ REG_BINARY, а мне это не нужно.
Так как всетаки записывать параметры в реестр, что бы они были REG_MULTI_SZ???

Автор: _hunter 16.8.2006, 14:23
значит забиваем на VCL и пишем/читаем данные сами: RegOpenKeyEx, RegSetValueEx

Автор: Bima 16.8.2006, 14:28
а примерчик можно?

Автор: _hunter 16.8.2006, 15:05
можно. тыкни в MSDN' e в топике по функции RegSetValueEx на ссылку "Adding a Source to the Registry" (часть Example Code)

Автор: Bima 16.8.2006, 15:10
Пример нашел, сейчас кодить буду...
потом код сюда выложу

Автор: Bima 17.8.2006, 08:04
У меня есть код, который я взял из примера:

Код

NetKey="{F58ACF6A-7789-429D-A53A-093C3D6E7111}";
sprintf(path,"\\SYSTEM\\CurrentControlSet\\Services\\%s\\Parameters\\TcpIp\0",NetKey.c_str());

result=RegOpenKeyEx(HKEY_LOCAL_MACHINE,path,0,KEY_ALL_ACCESS|KEY_READ|KEY_WRITE,&hkey);
if (result!=ERROR_SUCCESS)
   {
   return;
   }
sprintf(p,"%s",Value.c_str());
.....

но в этом коде я не могу открыть ключ, который я формирую,
то есть у меня подпрограмма выскакивает после проверки на операторе return

не могу понять, где у меня ошибка  smile 

Автор: _hunter 17.8.2006, 10:43
что GetLastError возврашает?
возможно первый \\ не нужен...

Автор: Bima 17.8.2006, 10:57
GetLastError не пробовал.
Вот код, который работат. Здесь я заменил оператор RegOpenKeyEx на RegOpenKey.

Это для чтения параметра REG_MULTI_SZ
Код

int siz;
char buf[128];
....
if (Reg->OpenKey("SYSTEM\\CurrentControlSet\\Services\\"+NetKey+"\\Parameters\\TcpIp",false))
   {
   siz=Reg->GetDataSize("IPAddress");
   Reg->ReadBinaryData("IPAddress", buf, siz);
   Form1->EIp->Text=buf;
   }
else
   {
    // test
   }
Reg->CloseKey();


А вот этот для записи параметра REG_MULTI_SZ
Код

AnsiString NetKey;
AnsiString Value;
long result;
HKEY hkey;
char path[256];
char name[]="IPAddress\0";
char p[256];

//здесь вычесляется параметр NetKey
...

sprintf(path,"SYSTEM\\CurrentControlSet\\Services\\%s\\Parameters\\TcpIp\0",NetKey.c_str());

result=RegOpenKey(HKEY_LOCAL_MACHINE,path,&hkey);
if (result!=ERROR_SUCCESS)
   {
   Application->MessageBox("No access registry (Open key)","Error",MB_ICONERROR);
   return;
   }
Value=Form1->EIp->Text;
sprintf(p,"%s",Value.c_str());

result=RegSetValueEx(hkey,(char *) &name,0,REG_MULTI_SZ, (byte *)p,lstrlen(p)+1);
if (result!=ERROR_SUCCESS)
   {
   Application->MessageBox("No access registry (Set key)","Error",MB_ICONERROR);
   return;
   }

result=RegCloseKey(hkey);
if (result!=ERROR_SUCCESS)
   {
   Application->MessageBox("No access registry (Close key)","Error",MB_ICONERROR);
   return;
   }


Немного пояснений:
В начале программы был создан объект Reg (TRegistry), а в конце программы я его удалил.
Записываю в реестр значение Value, которое берется из текстового поля EIp

Автор: Bima 18.8.2006, 10:31
Тема закрыта

Автор: bigscorp 22.11.2006, 11:19
интересно, а у меня с твоим примером (первым) в бинари перевёл  smile 

по второму дописывает шнягу ((

как дописать дополнительный символ конца строки ... надо что бы выглядело так (например): "192.168.59.16\0\0"

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)