Seite 1 von 3
#REG_MULTI_SZ schreiben
Verfasst: 11.03.2007 16:41
von PureBasic4.0
Hi, Leute
Ich möchte gerne einen #REG_MULTI_SZ in die Registry schreiben. Habe schon die PBOSL-Registry-Lib ausprobiert, diese schreibt aber nach dem Eintrag ein Leerzeichen und eine Null. Denke, dass ist nicht richtig, denn wenn ich den Eintrag von Windows reinschreiben lasse, gibt es kein Leerzeichen und keine Null am Ende. Stattdessen gibt es im Hex-Modus noch 5x 0 Paare:

Hat jemand noch eine lib oder nen code?
Danke,
PureBasic4.0
Verfasst: 11.03.2007 19:39
von ts-soft
Mit was läßt den die 5 0 Paare anzeigen
Entweder das ist verkehrt, oder das ist kein REG_MULTI_SZ
Ausserdem solltest Du dir Strings auch als solche anschauen
Verfasst: 12.03.2007 18:05
von PureBasic4.0

Wie du siehst: Es sind #REG_MULTI_SZs. Die Hex-Daten bekommst du mit "Rechte Maustaste auf das gewünschte Element --> Binärdaten ändern"
So sehen die Binärdaten aus, wenn man sie von Windows reinschreiben lässt:
Und so, wenn man sie per WriteMultiLineString reinschreibt:
//edit: Ich schreibe
genau das gleiche mit WriteMultiLineString in die Registry. Ich füge kein Leerzeichen oder so hinzu
Verfasst: 12.03.2007 18:10
von ts-soft
Dann probiere mal JHRegistry von Jens, findeste auf PureArea.net oder
versuch den Source der Lib anzupassen, ich hab da im moment keine Zeit
und Lust zu.
Gruß
Thomas
Verfasst: 12.03.2007 18:12
von PureBasic4.0
gut. danke. ich probier's
Verfasst: 13.03.2007 12:33
von Shardik
Ich konnte den Fehler in der Bibliothek PBOSL_Registry verifizieren. Diese Zeile in der Prozedur Reg_WriteMultiLineString() ist fehlerhaft
Code: Alles auswählen
Mem = AllocateMemory((MemoryStringLength(@Value) + 1) * SizeOf(Character))
und sollte durch diese Zeile ersetzt werden
Code: Alles auswählen
Mem = AllocateMemory((MemoryStringLength(@Value) + 2) * SizeOf(Character))
@ts-soft
Bitte ändere dies in der Bibliothek PBOSL_Registry schnell ab, weil dieser Fehler schlimmstenfalls auch zu Registry-Fehlern führen könnte. Der von Dir angeforderte Puffer ist im ASCII-Modus um 1 Byte bzw. im Unicode-Modus um 2 Bytes zu klein. Bei mir führte dies bei einem Unicode-Eintrag dazu, daß am Eintragsende hinter 3 Null-Bytes die Bytes 2B 02 folgten, was in RegEdit zu einer merkwürdigen Anzeige mit vielen wirren Zeichen am Eintragsende führte. Glücklicherweise ließ sich der Eintrag bearbeiten und löschen.
Wenn Du übrigens einmal den Wert von
(MemoryStringLength(@Value) + 1) * SizeOf(Character) mit dem von
MemorySize(Mem) verglichen hättest, hättest Du festgestellt, daß die beiden Werte unterschiedlich sind...

Verfasst: 13.03.2007 15:12
von PureBasic4.0
ok. danke
Verfasst: 14.03.2007 14:28
von PureBasic4.0
@Shardik
Dein Bugfix hat noch eine Macke: Durch die Zeile
Code: Alles auswählen
Mem = AllocateMemory((MemoryStringLength(@Value) + 2) * SizeOf(Character))
werden jetzt zwei Zeilen hinzugefügt.

Hex-Ansicht:

Möchte aber immernoch, dass es so aussieht:

Kannst du das bitte noch ausbessern?
Danke,
PureBasic4.0
Verfasst: 14.03.2007 16:54
von Shardik
PureBasic4.0 hat geschrieben:
Dein Bugfix hat noch eine Macke: Durch die Zeile
Code: Alles auswählen
Mem = AllocateMemory((MemoryStringLength(@Value) + 2) * SizeOf(Character))
werden jetzt zwei Zeilen hinzugefügt.
Sorry
Obwohl ich dies gestern ausgiebig unter WinXP SP2 und WinNT SP6 getestet habe (Unicode bekomme ich unter WinNT allerdings bis jetzt noch nicht in die Registry geschrieben!), ist mir da doch noch ein Fehler unterlaufen: ich wollte die zu ersetzende Zeile so ähnlich wie möglich wie die von ts-softs Originalzeile gestalten. Diese Zeile arbeitet aber wie von Dir erwartet:
Code: Alles auswählen
Mem = AllocateMemory(MemoryStringLength(@Value) * SizeOf(Character) + SizeOf(Character))
Bei mir wird mit dem folgenden Komplett-Beispiel (aus der PBOSL_Registry und mit der oben angegebenen veränderten Code-Zeile) unter WinXP SP2 dieser Test-Eintrag erstellt:
HKEY_CURRENT_USER\Test
und der Schlüssel
Gateway wird dort eingetragen. Wenn man den Schlüssel mit "Binärwert bearbeiten" öffnet, sieht der Inhalt genauso aus wie in Deinem Snapshot bzw. wie mit Windows direkt erstellt.
Code: Alles auswählen
Global Reg_ErrorNr.l, Reg_ErrorMsg.s
Procedure Reg_SetLastError(Error.l = 0)
Protected Buffer.l
If Error
Reg_ErrorNr = Error
Else
Reg_ErrorNr = GetLastError_()
EndIf
FormatMessage_(#FORMAT_MESSAGE_ALLOCATE_BUFFER|#FORMAT_MESSAGE_FROM_SYSTEM, 0, Reg_ErrorNr, 0, @Buffer, 0, 0)
If Buffer
Reg_ErrorMsg = PeekS(Buffer)
LocalFree_(Buffer)
EndIf
EndProcedure
Procedure Reg_ResetError()
Reg_ErrorNr = 0
Reg_ErrorMsg = ""
EndProcedure
ProcedureDLL.l Reg_WriteMultiLineString(topKey.l, KeyName.s, ValueName.s, Value.s); write a StringField, separate with #LF$, to specified ValueName
Protected Result.l, hKey.l, Error.l, dwDisposition.l, Mem.l
Reg_ResetError()
If Right(KeyName, 1) = "" : KeyName = Left(KeyName, Len(KeyName) - 1) : EndIf
Error = RegCreateKeyEx_(topKey, KeyName, 0, 0, #REG_OPTION_NON_VOLATILE, #KEY_ALL_ACCESS, 0, @hKey, @dwDisposition)
If Error = #ERROR_SUCCESS
Mem = AllocateMemory(MemoryStringLength(@Value) * SizeOf(Character) + SizeOf(Character))
If Mem
PokeS(Mem, Value)
Error = RegSetValueEx_(hKey, ValueName, 0, #REG_MULTI_SZ, Mem, MemorySize(Mem) + SizeOf(Character))
If Error = #ERROR_SUCCESS
Result = #True
Else
Reg_SetLastError(Error)
EndIf
FreeMemory(Mem)
Else
Reg_ErrorNr = -1
Reg_ErrorMsg = "can't allocate memory"
EndIf
Else
Reg_SetLastError(Error)
EndIf
If hKey : RegCloseKey_(hKey) : EndIf
ProcedureReturn Result
EndProcedure
Reg_WriteMultiLineString(#HKEY_CURRENT_USER, "Test", "Gateway", "192.168.0.1")
Verfasst: 14.03.2007 17:00
von ts-soft
Meine Orginalzeile + 1 * SizeOf(charachter) sollte rein mathematisch
dasselbe ergeben
Aber schön wenn ich auf diese Art an die noch vorhandenen Fehler komme,
weil zum Testen fehlt mir die Notwendigkeit und Zeit.
Gruß
Thomas
Code: Alles auswählen
Mem = AllocateMemory((MemoryStringLength(@Value) + 1) * SizeOf(Character))
Sollte dasselbe sein wie:
Code: Alles auswählen
Mem = AllocateMemory(MemoryStringLength(@Value) * SizeOf(Character) + SizeOf(Character))
// Test:
Code: Alles auswählen
value.s = "Hallo die Enten"
Debug (MemoryStringLength(@Value) + 1) * SizeOf(Character)
Debug MemoryStringLength(@Value) * SizeOf(Character) + SizeOf(Character)
Wichtig ist nur die Klammersetzung