![]() |
Registry ReadBinaryData Problem
Hallo Liebe DP'ler :-),
Ich habe leider folgendes Problem, da steckt wohl im Code der Wurm drin :-):
Delphi-Quellcode:
Dieser Code sollte eigentlich einfach nur einen Binary Registry Wert auslesen und anzeigen aber PusteKuchen, er zeigt mir leider keinen Debugger Fehler an sondern einen Programm Fehler mit einer Access Violation an. :-( Erkennt wer meinen Fehler?
procedure TForm1.Button1Click(Sender: TObject);
var regist: TRegistry; n:string; size:integer; begin regist:=TRegistry.Create; try regist.RootKey:=HKEY_CURRENT_USER; regist.OpenKey('Software\Microsoft\Windows\Shell\Bags\1\Desktop',false); size := regist.GetDataSize('ItemPos1280x1024(1)'); regist.ReadBinaryData('ItemPos1280x1024(1)', n, size); //Hier wohl der Fehler Edit1.Text:=n; Memo1.Text:=n; finally regist.Free; end; end; |
Re: Registry ReadBinaryData Problem
Du solltest auch genügend Platz im String reservieren
|
Re: Registry ReadBinaryData Problem
Und wie mache ich das? ^^ Sry Anfänger... :wall:
|
Re: Registry ReadBinaryData Problem
Delphi-Quellcode:
Setlength(n, size);
|
Re: Registry ReadBinaryData Problem
Leider immernoch die Selbe Fehlermeldung bei einer anderen "höheren" Adresse...
Delphi-Quellcode:
Ich habe mir einmal size ausgeben lassen, es kam die Zahl 1888 heraus.
procedure TForm1.Button1Click(Sender: TObject);
var regist: TRegistry; n:string; size:integer; begin regist:=TRegistry.Create; try regist.RootKey:=HKEY_CURRENT_USER; regist.OpenKey('Software\Microsoft\Windows\Shell\Bags\1\Desktop',false); size := regist.GetDataSize('ItemPos1280x1024(1)'); Setlength(n, size); regist.ReadBinaryData('ItemPos1280x1024(1)', n, size); Edit1.Text:=n; Memo1.Text:=n; finally regist.Free; end; end; Was kann ich dagegen tun? MfG Darkface |
Re: Registry ReadBinaryData Problem
Moin Darkface,
ehrlich gesagt finde ich Deinem Code mehr als einen Fehler ;-) Die AV wird dadurch verursacht, dass ReadBinaryData keine Typenangabe für den Buffer verwendet. Deshalb musst Du, wenn Du einen String als Buffer verwendest, noch angeben, ab welcher Stelle des Strings der Buffer gefüllt werden soll. In der Regel wird dieses die erste Stelle sein. Wenn Du hier mal nach ![]()
Delphi-Quellcode:
Nun noch zu den anderen "Problemstellen":
regist.ReadBinaryData('ItemPos1280x1024(1)', n[1], size);
OpenKey ist eine Funktion, liefert also einen Wert zurück, der anzeigt, ob der Aufruf erfolgreich war. Nur in diesem Falle sollten dann auch die Zeilen ausgeführt werden, die im Erfolgsfalle auszuführen sind. Nach dem erfolgreichen Öffnen des Keys benötigst Du wieder einen try/finally-Block, um das Schliessen des Keys sicherzustellen. CloseKey fehlt. Ich weiss, bei TRegistry.Free wird, über TRegistry.Destroy auch CloseKey aufgerufen, aber sobald man mehrere Keys öffnet werden Resourcen nicht wieder freigegeben. Auch wenn man nur einen Key öffnet, ist es einfach sauberer diesen auch wieder gezielt zu schliessen. Ausserdem hast Du noch ein ganz anderes Problem: Jetzt wirst Du zwar keine AV mehr bekommen, aber Edit und Memo werden leer bleiben. Du liest schliesslich einen Binären Wert, aus dem Du erst einmal die gewünschten Werte extrahieren und in eine lesbares Format umwandeln musst, bevor Du sie anzeigen kannst. |
Re: Registry ReadBinaryData Problem
Danke, die Fehlermeldung bleibt wirklich aus. Aber wie zum Geier kann ich denn einen Binär Wert in einen normalen String umwandeln? Ich möchte mein gesammtes "n" als ganz normale Reinschrift haben. Und das Selbe auch wieder zurück wandeln können (String in Binär Wert)....
MfG Darkface :cat: |
Re: Registry ReadBinaryData Problem
Was ist denn ein Binärwert? Daten sind Daten, der Rest ist eine Frage der Interpretation.
|
Re: Registry ReadBinaryData Problem
ahja? ^^ anders gefragt halt ^^... wie kann ich das n hier in "reinschrift" lesen
Delphi-Quellcode:
Danke &
procedure TForm1.Button1Click(Sender: TObject);
var regist: TRegistry; n:string; size:integer; begin regist:=TRegistry.Create; try regist.RootKey:=HKEY_CURRENT_USER; try regist.OpenKey('Software\Microsoft\Windows\Shell\Bags\1\Desktop',false); size := regist.GetDataSize('ItemPos1280x1024(1)'); Setlength(n, size); regist.ReadBinaryData('ItemPos1280x1024(1)', n[1], size); Edit1.Text:=n; Memo1.Text:=n; regist.CloseKey; except regist.CloseKey; end finally regist.Free; end; end; MfG Darkface |
Re: Registry ReadBinaryData Problem
Hallo, du musst die #0 noch entfernen
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
const CDataValue: string = 'ItemPos1280x1024(1)'; CKeyName: string = 'Software\Microsoft\Windows\Shell\Bags\1\Desktop'; var regist: TRegistry; KeyExists: boolean; vSize, p: integer; tmpStr: string; begin regist := TRegistry.Create; try regist.RootKey := HKEY_CURRENT_USER; try KeyExists := regist.OpenKey(CKeyName, false); if (KeyExists) then begin vSize := regist.GetDataSize(CDataValue); if (vSize > 0) then begin SetLength(tmpStr, vSize); regist.ReadBinaryData(CDataValue, tmpstr[1], vSize); repeat p := Pos(#0, tmpStr); if p <> 0 then Delete(tmpStr, p, 1); until p = 0; Memo1.Text := tmpStr; end; end; except regist.CloseKey; end finally regist.Free; end; end; |
Re: Registry ReadBinaryData Problem
Ich würde wenn schon "string" als Puffer benutzt wird, diesen explizit als "AnsiString" deklarieren, vor allem im Hinblick auf das (wohl) kurz vor dem Release stehende Delphi 2009, bei dem "string" = "UnicodeString" ist und somit "SizeOf(Byte) = SizeOf(Char)" nicht mehr zutrifft.
|
Re: Registry ReadBinaryData Problem
Hi und danke Toms, es scheint das dein Code das richtige macht, aber wenn ich ihn ausführe dann ist außer den Dateinamen auf meinem Desktop doch alles ziemlich kaudawelsch... liegt das am Code oder ist das eben von windows so(was ich nicht ganz glaube weil dort eigentlich icon positionen auf dem desktop gespeichert sein sollten, ich aber nicht wirklich zahlen lesen kann :D...
|
Re: Registry ReadBinaryData Problem
push? :D hoffe erlaubt ^^
|
Re: Registry ReadBinaryData Problem
Frage: Warum möchtest du die Icon Positionen aus der Registry auslesen und nicht gleich direkt die Icon Positionen ermitteln?
|
Re: Registry ReadBinaryData Problem
Weil ich bis jetzt für den einzigen weg hielt... aber das auslesen ist ja nur die eine seite, die andere fast wichtigere Seite ist auch das verändern... aber um zu wissen was ich verändere muss ich auch wissen was da ist. gibt es denn einen weg dies zu bewerkstelligen ohne den "umweg" über die regestry...?
|
Re: Registry ReadBinaryData Problem
Zitat:
![]() |
Re: Registry ReadBinaryData Problem
Du meinst jetzt aber nicht LuckieDIPs? ^^ Was mit dieser möglichkeit ist schrieb ich auf der selben Seite ^^...
|
Re: Registry ReadBinaryData Problem
Also mal zur Erklärung, was dir die Leute sagen wollen.
Stell dir vor die hexadezimale Darstellung deiner Daten wäre folgendes. hexadezimal: 54 45 53 54 Je nach dem wie du diese Daten jetzt interpretierst kommt was anderes heraus. Nimmt du zB. an, - daß jedes Byte ein Buchstabe ist, dann heisst das oben TEST - daß dies eine Integer Zahl ist kommt 1413829460 heraus - daß jeweils 2 byte eine Zahl sind kommt 21573 und 21332 heraus - usw. Wie du siehst kann man Binärdaten verschieden interpretieren. Deine Aufgabe ist es rauzufinden, wie die Daten in diesem Binärstrom zu interpretieren sind. |
AW: Re: Registry ReadBinaryData Problem
Hallo,
nach dem Umstieg auf Delphi XE hatte ich auch ein Problem mit ReadBinaryData. Die Werte wurden nicht mehr korrekt ausgelesen. Auf der Suche nach der Ursache (bzw. Lösung, denn die URsache schien klar zu sein) bin ich auf diesen Thread gestoßen. Dieser Hinweis hier Zitat:
Welche "stabile" Alternativen hat man sonst noch, wenn AnsiString keine gute Lösung ist? |
AW: Registry ReadBinaryData Problem
Wie wäre es denn mit PByte? Für die Interpretation der Daten musst Du allerdings später selber sorgen.
|
AW: Registry ReadBinaryData Problem
Du kannst auch einen String/UnicodeString/WideString verwenden, aber bedenke, daß dieser 2 Byte pro Char besitzt.
PS: Statt des AnsiStrings, verwendet man für sowas den RawByteString ... das ist zwar auch ein AnsiString, aber ohne Behandlung der CodePage. Genauso, wie es den Utf8String gibt, welches einen "AnsiString" mit voreingestellter UTF-8-CodePage (CP_UTF8) darstellt. Wobei man eben auch TBytes (ein Array of Byte) verwenden könnte, oder halt doch PByte und Co. Bei RawByteString und TBytes hat man den Vorteil, daß sich Delphi um die Speicherverwaltung (vorallem die Freigabe) kümmert und das sogar threadsave, über mehrere Referenzen hinweg. (ja, man mag es kaum glauben, aber auch die RTL kann teilweise threadsave sein) Und ja, auch in einem Unicode-Programm ist es manchmal ratsam/sinnvoll, wenn man AnsiStrings verwendet ... eben genau dann, wenn man wirklich ANSI benötigt (genau so wie man damals auch in einem ANSI-Programm den WideString nutzen konnte) oder eben wenn man einen "String" als Byte-Puffer nutzen will, denn SizeOf(AnsiChar) = SizeOf(Byte). So war es damals eigentlich schon fahrlässig, wenn man für solche Datenpuffer den "String" verwendete, obwohl man eigentlich den AnsiString hätte nutzen müssen, weil sich der String ja ändern konnte/tat. |
AW: Registry ReadBinaryData Problem
Ok, verstehe.
Vielen Dank Detlef und himitsu! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:22 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz