PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Рееств Windows. RegSetValueEx_ не полностью записівает строку.


Рееств Windows. RegSetValueEx_ не полностью записівает строку.

Сообщений 1 страница 10 из 10

1

Доброго времени суток.

Есть такой вот код:

Код:
Procedure RegSetString(Key, SubKey.s, ValueName.s, String.s, Type.b = #REG_SZ)
    Protected hKey
    If Not RegOpenKeyEx_(Key, SubKey, 0, #KEY_ALL_ACCESS, @hKey) And hKey
        RegSetValueEx_(hKey, @ValueName, 0, Type, @String, Len(String) +1)
        RegCloseKey_(hKey)
    EndIf
EndProcedure

RES$="SOFTWARE\Test123"
TestString$="d5aa2680a2404a100fd31121a2e3aaba"

RegSetString(#HKEY_CURRENT_USER, REG$, "StringA", TestString$)

Создается в реестре запись.
Имя параметра появляется "StringA"
Тип записи REG_SZ
А вот далее интереснее: значение вместо:
d5aa2680a2404a100fd31121a2e3aaba
Стает как бы обрезаным:
d5aa2680a2404a10

В чем может быть причина, если учесть, что вручную через REGEDIT запись спокойно создается с таким значением. Также спокойно читается и с PureBasic. даже все 4 компилятора перепробывал. Не помогает.

Ответ получен от V Dryagin из чата в Телеграмме

Судя по тому, что длина урезалась в два раза, возможно, вместо Len нужно использовать StringByteLength, с указанием формата.

Благодарю за помощь!

Отредактировано Black Wolf (14.12.2022 05:01:23)

0

2

Black Wolf
можно использовать Registry Module, но скачать его из этого комплекта, смотри там архив PB User.7z

Ещё есть код архив winapi, там смотри папку "реестр".

Отредактировано AZJIO (14.12.2022 09:44:46)

0

3

AZJIO написал(а):

Black Wolf
можно использовать Registry Module, но скачать его из этого комплекта, смотри там архив PB User.7z

Ещё есть код архив winapi, там смотри папку "реестр".

Благодарен!

0

4

Black Wolf написал(а):

Len(String) +1)

кажись здесь надо умножать на два

0

5

newJS написал(а):

RegSetValueEx_

Совершенно верно,так как RegSetValueEx_() последний параметр это  размер в байтах,и если компиляция как unicod=2 байта на символ+завершающий 0 то len("stroka")*2+1(или 2?)

0

6

Sergeihik написал(а):

или 2?

#PB_Unicode +2
#PB_UTF8 и #PB_Ascii +1

Почему #PB_Unicode +2. потому что латинские буквы один байт и перед ними всегда будет 00, поэтому при встрече первой латинской буквы перед которой 00 это было бы нуль-терминированным концом, поэтому для юникода (16) концом является 2 раза по 00. А #PB_Ascii понятно, там 1 байт на символ и один 00 является концом. Для #PB_UTF8 если буква 1 байт (латинские) то перед ней не будет 00, а если 2 байта, то она тоже не будет иметь предшествующий 00.

Закоментируй ненужные блоки чтобы посмотреть один из вариантов:

Код:
EnableExplicit

Global c, *t, t$
t$ = "hello привет"
*t = Ascii(t$)
c = StringByteLength(t$, #PB_Ascii)
ShowMemoryViewer(*t, c + 1)
FreeMemory(*t)

Global c, *t, t$
t$ = "hello привет"
*t = UTF8(t$)
c = StringByteLength(t$, #PB_UTF8)
ShowMemoryViewer(*t, c + 1)
FreeMemory(*t)


Global c, t$
t$ = "hello привет"
c = StringByteLength(t$, #PB_Unicode)
ShowMemoryViewer(@t$, c + 2)

и смотрим завершающий 00

Отредактировано AZJIO (19.12.2022 20:19:59)

0

7

Для #PB_UTF8 если буква 1 байт (латинские) то перед ней не будет 00, а если 2 байта, то она тоже не будет иметь предшествующий 00.
Так у винды функции заточены Unicode и Ascii(ansi)  а  UTF8 нет, так что #PB_UTF8 для id редактора для хранения в файле и т.д.
и компилятор компилит их так.

Отредактировано Sergeihik (19.12.2022 20:28:14)

0

8

Sergeihik
Это я в общем, я сам раньше думал что добавить 1 байт или 2 байта и для перестраховки добавлял 2 байта.
У реестра есть бинарный тип, туда можно засунуть всё что угодно и автор программы зная формат своих данных может читать оттуда в UTF8, если он предварительно в этом формате заснул их туда. Хотя можно засунуть как будто это строка #PB_Ascii, а вытащить, как будто это строка #PB_UTF8, по сути реестр не знает в каком формате у него строка, кроме как то что она завершается 00.

Отредактировано AZJIO (19.12.2022 21:18:50)

0

9

AZJIO написал(а):

Это я в общем, я сам раньше думал что добавить 1 байт или 2 байта и для перестраховки добавлял 2 байта.

SizeOf(Character) - универсально.

0

10

AZJIO написал(а):

Sergeihik
Это я в общем, я сам раньше думал что добавить 1 байт или 2 байта и для перестраховки добавлял 2 байта.
У реестра есть бинарный тип, туда можно засунуть всё что угодно и автор программы зная формат своих данных может читать оттуда в UTF8, если он предварительно в этом формате заснул их туда. Хотя можно засунуть как будто это строка #PB_Ascii, а вытащить, как будто это строка #PB_UTF8, по сути реестр не знает в каком формате у него строка, кроме как то что она завершается 00.

Отредактировано AZJIO (Вчера 21:18:50)

Так речь не про бинарный тип а про функцию RegSetValueEx()
Про которую прочитал что  [in] lpData
Данные, которые необходимо сохранить.
Для строковых типов, таких как REG_SZ, строка должна заканчиваться нулем . Для типа данных REG_MULTI_SZ(Несколько строк в памяти(файле) разделённых двумя  00) строка должна заканчиваться двумя нулевыми символами.
[in] cbData
Размер информации, на которую указывает параметр lpData , в байтах. Если данные имеют тип REG_SZ, REG_EXPAND_SZ или REG_MULTI_SZ, cbData должен включать размер завершающего нулевого символа или символов.

Отредактировано Sergeihik (20.12.2022 17:34:24)

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Рееств Windows. RegSetValueEx_ не полностью записівает строку.