Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Exception beim Ermitteln des TEMP-Ordners unter Delphi 2010 (https://www.delphipraxis.net/150398-exception-beim-ermitteln-des-temp-ordners-unter-delphi-2010-a.html)

berens 15. Apr 2010 14:00


Exception beim Ermitteln des TEMP-Ordners unter Delphi 2010
 
Hallo mal wieder!

Anhand von diesem Tip: http://www.swissdelphicenter.ch/de/showcode.php?id=385 habe ich mir die Prozedur für den TEMP-Ordner zusammengestückelt. Unter Delphi 2007 problemlos. Unter 2010 kommt beim Ausführen die Exception
Zitat:

---------------------------
Benachrichtigung über Debugger-Problem
---------------------------
In Projekt C:\test\Project1.exe trat ein Problem mit folgender Meldung auf: 'access violation at 0x00000000: read of address 0x00000000'. Prozess angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK
---------------------------
Teilweise mit dem Zusatz "Es traten zu viele Exceptions in kurzer Folge auf" (oder ähnlich).

Delphi-Quellcode:
function Test1: string;
var
  Buffer: array[0..MAX_PATH] of Char;
begin
  GetTempPath(SizeOf(Buffer) - 1, Buffer);
  Result := Buffer;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
   Caption := Test1;
end;
1) Kann das jemand nachvollziehen
2) Mache ich was falsch? Wohl ja, irgendwelche Pointer sind nicht initialisiert oder so?
3) Gibt es einen alternativen Weg, den TEMP-Ordner als String zu bekommen?

Danke im Vorraus,
Mathias

Edit: Ich würde ja fast vermuten: SetLength(Result, MAX_PATH); , aber seit wann muss einem String Speicher zugewiesen werden?

DeddyH 15. Apr 2010 14:05

Re: Exception beim Ermitteln des TEMP-Ordners unter Delphi 2
 
Ich hab kein Delphi 2010, aber wie sieht es so aus?
Delphi-Quellcode:
function Test1: string;
begin
  SetLength(Result,GetTempPath(0, nil) + 1);
  GetTempPath(Length(Result),PChar(Result));
end;

himitsu 15. Apr 2010 14:08

Re: Exception beim Ermitteln des TEMP-Ordners unter Delphi 2
 
Auch wenn es nicht optimal ist, wenn man eine WinAPI aufruft und ihren Rückgabewert ungeprüft verwenden will...
Delphi-Quellcode:
function Test1: string;
var
  Buffer: array[0..MAX_PATH] of Char;
begin
  GetTempPath(Length(Buffer), Buffer);
  Result := Buffer;
end;
SizeOf = Bytes
aber der Parameter will Chars (Zeichenanzahl)
> siehe MSDN-Library durchsuchenGetTempPath

GetTempPath füllt den Puffer mit Nullen und schreibt einen String an den Anfang

D2010 = Unicode (2 Byte pro Char) und schwups hast du einen Pufferüberlauf, da du behauptest der Puffer wäre größer, als er ist.

berens 15. Apr 2010 14:20

Re: Exception beim Ermitteln des TEMP-Ordners unter Delphi 2
 
@DeddyH: Funktioniert einwandfrei, vielen Dank! Edit: Achtung Siehe unten!

@himitsu: Genau sowas habe ich befürchtet. Wie hätte man denn jetzt idealerweise den Rückgabewert geprüft?

Wenn ich das richtig verstehe, hat Delphi bis 2007 (2009?) bei SizeOf -in diesem Fall- den identischen Wert zurückgegeben wie length, und es war -in diesem Fall- egal was man verwendete. Oder war das Beispiel auf http://www.swissdelphicenter.ch/de/showcode.php?id=385 mit dem SizeOf einfach schon immer falsch?

Wenn ich jetzt all meine Quellcodes durchsehe und will die 2010 "fit" machen, worauf muss ich also achten? Überall da wo mit Char und SizeOf oder Length gearbeitet schauen ob das stimmt? Wegen Unicode und so?



Edit: Achtung, DeddyH: Bei deinem Code sind hängt noch #0#0 an dem String dran. Damit kann ich also nicht tmpString := GetTempFolder + 'temp.tmp' machen; der String verändert sich nicht mehr. Mit:

Delphi-Quellcode:
SetLength(Result,GetTempPath(0, nil) + 1);
GetTempPath(Length(Result),PChar(Result));
Result := trim(Result);
geht es, aber es ist die Frage, ob man nicht direkt mit -1 statt +1 arbeiten müsste/sollte? Keine Ahnung...

DeddyH 15. Apr 2010 14:35

Re: Exception beim Ermitteln des TEMP-Ordners unter Delphi 2
 
Dann lass das "+ 1" mal weg, da scheine ich das MSDN falsch verstanden zu haben.

berens 15. Apr 2010 14:40

Re: Exception beim Ermitteln des TEMP-Ordners unter Delphi 2
 
Naja, selbst dann wäre noch ein #0 zuviel. Laut MSDN wird ja die Länge (length) von dem string zurückgegeben, ohne TerminationCharacter, den muss man also noch dazuzählen wenn man die Puffergröße festlegen will, deshalb wäre imho die +1 auch ok. Ich kapiert das nicht.

DeddyH 15. Apr 2010 14:54

Re: Exception beim Ermitteln des TEMP-Ordners unter Delphi 2
 
Nein, das hatte ich ja auch erst so verstanden, aber dann noch einmal gelesen.
Zitat:

If the function succeeds, the return value is the length, in TCHARs, of the string copied to lpBuffer, not including the terminating null character. If the return value is greater than nBufferLength, the return value is the length, in TCHARs, of the buffer required to hold the path.
[edit] Bevor wir hier jetzt stundenlang rumraten, wie das wirklich gemeint ist:
Delphi-Quellcode:
function TempPath: string;
begin
  SetLength(Result,GetTempPath(0, nil));
  GetTempPath(Length(Result),PChar(Result));
  SetLength(Result,StrLen(PChar(Result)));
end;
Sollte auf jeden Fall passen ;)[/edit]

[edit2] Was auch gehen müsste:
Delphi-Quellcode:
function TempPath: string;
begin
  SetLength(Result,GetTempPath(0, nil));
  SetLength(Result,GetTempPath(Length(Result),PChar(Result)));
end;
[/edit2]


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:53 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz