Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   TStringList Max String länge (https://www.delphipraxis.net/130628-tstringlist-max-string-laenge.html)

EWeiss 11. Mär 2009 12:34


TStringList Max String länge
 
Vielleicht hat jemand eine Idee.
Wenn ich ca 100 Dateien zu einer TStringList addieren möchte bei dem der Pfad zu diesen extrem lang ist
kracht es in Delphi gewaltig beim Debugen.

Was ich dann machen muss ist soviele Dateien entfernen so das die maximale stringlänge nicht überschritten wird.
Irgendwo kann es das aber nicht sein.

Hab mir überlegt nur den Dateinamen zu übergeben dann hab ich aber das problem
das ich dann keine recursive suche mehr durchführen kann da in diesen Fall der Pfad nicht mehr bekannt ist.

Habe da schon so viel versucht scheitere aber immer an der länge des Pfads(string)
Also die Frage wie würdet ihr das lösen ?

gruss Emil

nuclearping 11. Mär 2009 12:36

Re: TStringList Max String länge
 
Anderer Vorschlag:

TList mit PChar statt TStringList.

hoika 11. Mär 2009 12:37

Re: TStringList Max String länge
 
Hallo,

beim Debuggen oder auch zur Laufzeit.
was heisst "krachen"


Heiko

Bernhard Geyer 11. Mär 2009 12:40

Re: TStringList Max String länge
 
Ich tippe eher darauf das das "Krachen" in der Stringlist durch einen anderen Fehler verursacht wird.
Kannst du ein Minimalbeispiel posten wo dieses Verhalten auftritt?

EWeiss 11. Mär 2009 12:50

Re: TStringList Max String länge
 
Beispiel:
Zitat:

C:\Dokumente und Einstellungen\Emil Weiss\Desktop\BassVisWrapper_SVN\BassVis_Wrapper_E xample\BassVisWrapper_Example\bin\Debug\splugins\
In dem Pfad befinden sich 100 Odner mit den Namen der Plugins die recursiv durchsucht werden.
Das ist einer.

Zitat:

C:\Dokumente und Einstellungen\Emil Weiss\Desktop\BassVisWrapper_SVN\BassVis_Wrapper_E xample\BassVisWrapper_Example\bin\Debug\splugins\A cidspunk
da angehängt noch das Plugin selbst.
Zitat:

C:\Dokumente und Einstellungen\Emil Weiss\Desktop\BassVisWrapper_SVN\BassVis_Wrapper_E xample\BassVisWrapper_Example\bin\Debug\splugins\A cidspunk\Acidspunk.svp
Dieser String wird getrennt durch einen Delemiter der übergeben werden kann .. default ist Commalist
Nun kann man sich vorstellen wie lang der String wird wenn ich 100 Ordner addiere.

Zitat:

beim Debuggen oder auch zur Laufzeit.
was heisst "krachen"
Zugriffs verletzung lesen von 00000000 und so weiter
Beim Debugen
Wenn die Exe Kompiliert ist also außerhalb der IDE gestarte wird funktioniert es.

Das ist der aufruf
Delphi-Quellcode:
function GlobalFindPlugins(Kind: TBASSVIS_KIND_T;
                           Vispath: PAnsiChar;
                           flags: DWord;
                           Delimiter: AnsiChar = ','): PAnsiChar;

Zitat:

TList mit PChar statt TStringList.
War meine vorherige version geht auch nicht.
Was ich noch dabei sagen muss die liste wird aus einer DLL übergeben

gruss Emil

EWeiss 11. Mär 2009 12:54

Re: TStringList Max String länge
 
Zitat:

Zitat von Bernhard Geyer
Ich tippe eher darauf das das "Krachen" in der Stringlist durch einen anderen Fehler verursacht wird.
Kannst du ein Minimalbeispiel posten wo dieses Verhalten auftritt?

Wie schon gesagt tritt auf wenn der Strin seine Max länge erreicht hat.
Kann das nur beseitigen indem ich einige Ordner entferne.

Der Code... Beispiele ist schlecht da aus DLL
changed kein code problem

Gruss EMil

Bernhard Geyer 11. Mär 2009 12:58

Re: TStringList Max String länge
 
Kann es eher sein das hier eine Windows-Eigenheit zuschlägt das Dateinamen/Pfad nur aufgelöst werden können wenn sie < 255 Zeichen sind bzw. weniger als 255 Zeichen vom aktuellen pfad entfernt sind?

EWeiss 11. Mär 2009 13:03

Re: TStringList Max String länge
 
Zitat:

Zitat von Bernhard Geyer
Kann es eher sein das hier eine Windows-Eigenheit zuschlägt das Dateinamen/Pfad nur aufgelöst werden können wenn sie < 255 Zeichen sind bzw. weniger als 255 Zeichen vom aktuellen pfad entfernt sind?

Ja .. Das ist so
Deshalb meine Frage wie ich das anderes lösen kann.
Am Code liegt es nicht .. der ist in Ordnung da ändert auch nichts dran wenn ich TList verwende.

Wie gesagt wenn ich nur das Plugin übergeben hätte ich kein problem mehr mit der länge des String
Kann aber dann den Pfad nicht übergeben was bedeute das recursive suchen wäre dann sinnlos.

gruss Emil

Klaus01 11. Mär 2009 13:50

Re: TStringList Max String länge
 
Hallo Emil,

wie es ausschaut, wirst Du wohl nicht viel anderes
übrigbleiben als Dir Dein eigenes ExtractFilePath
zu schreiben.

Die Routinen könnten in etwa so aussehen:

Delphi-Quellcode:
function extractFileName(s:string):String;
var
  i: Integer;
begin
  i:= length(s);
  while (i > 0) and (s[i] <> '\') do
    begin
      dec(i);
    end;
  result := copy(s,i+1,length(s)-i+1);
end;

function extractFilePath(s:string):String;
var
  i: Integer;
begin
  i:= length(s);
  while (i > 0) and (s[i] <> '\') do
    begin
      dec(i);
    end;
  result := copy(s,1,i-1);
end;
Kann man sicherlich noch eleganter machen ...

Grüße
Klaus

Muetze1 11. Mär 2009 15:02

Re: TStringList Max String länge
 
(sorry)

EWeiss 11. Mär 2009 15:17

Re: TStringList Max String länge
 
Zitat:

Zitat von Klaus01
Hallo Emil,

wie es ausschaut, wirst Du wohl nicht viel anderes
übrigbleiben als Dir Dein eigenes ExtractFilePath
zu schreiben.

Die Routinen könnten in etwa so aussehen:

Delphi-Quellcode:
function extractFileName(s:string):String;
var
  i: Integer;
begin
  i:= length(s);
  while (i > 0) and (s[i] <> '\') do
    begin
      dec(i);
    end;
  result := copy(s,i+1,length(s)-i+1);
end;

function extractFilePath(s:string):String;
var
  i: Integer;
begin
  i:= length(s);
  while (i > 0) and (s[i] <> '\') do
    begin
      dec(i);
    end;
  result := copy(s,1,i-1);
end;
Kann man sicherlich noch eleganter machen ...

Grüße
Klaus

Danke werd mal schaun ob es hilft.

gruss Emil

EWeiss 11. Mär 2009 20:19

Re: TStringList Max String länge
 
Ich übergebe den Pfad nun mit GetShortName ist das einzigste was mir einfällt.
Kann aber nicht sagen ob das jetzt wieder mit anderen Sprachen probleme macht.

Was mir noch aufgefallen ist und ebenfalls mit zu dem Problem beiträgt ist
das diese DLL "CosmicBelt.svp" ein exception auslößt.

Wie kann man bei LoadLibrary das exception abfangen ohne das es zum crash kommt ?
Delphi-Quellcode:
  try
    dll := LoadLibrary(PAnsiChar(APlugin));
  except
    exit;
  end;
hilft nix kracht trotzdem.

gruss Emil

quendolineDD 11. Mär 2009 21:27

Re: TStringList Max String länge
 
Zu deinem Problem mit dem Pfad:

Zitat:

In Windows API MAX_PATH is 260 characters long. WinRAR supports only this length. At the same time, Windows Unicode API support 32767 character long filen paths. Microsoft promised to include support of long naming in whidbey but I don't know if it's supported with .net applications now. To access file paths using this API program should call the file using \\?\ prefix before the path. The only reason, I guess, why most programs are still using old APIs are compatibility reason although, to tell the truth, a very few programs are now support non-NT OSes and the security as they say that this limitation is used intentionally to prevent buffer overflow attacks. Thus having the full path of 260 we are actually limited to a 248 character-long directory name as the remaining 12 are needed for the filename.
See this article for details. See this for the _MAX_XXXX constant description and their values. By the way there is an interesting bug within the next Visual Studio codenamed Orcas posted just a few days ago.
Quelle: hier #13

Zu deiner letzten Frage (eigentlich nur eine Frage pro Thread :roll: )
Versuch mal GetLastError auszulesen. Kann natürlich sein, das die DLL Fehler in ihrer DllMain()-Procedur hat und dort die Exception auftritt. Diese kannst du dann natürlich nicht abfangen.

EWeiss 11. Mär 2009 21:37

Re: TStringList Max String länge
 
Zu 1. Danke das ist gelößt mit GetShortName. Mehr kann ich da eh nicht machen :)
Zu 2. Die DLL wurde gepackt daher kam es zum Exception. Hab sie gelöscht und mir einen vermerk gemacht.

Vielen Dank.

gruss Emil

Muetze1 11. Mär 2009 21:59

Re: TStringList Max String länge
 
1. MSDN: Maximum Path Length
2. Delphi-Referenz durchsuchenSafeLoadLibrary()

Luckie 11. Mär 2009 22:01

Re: TStringList Max String länge
 
Zitat:

Zitat von EWeiss
Ich übergebe den Pfad nun mit GetShortName ist das einzigste was mir einfällt.

Du musst aber aufpassen:
Zitat:

Zitat von Windows PSDK
When an application calls this function and specifies a path on a volume that does not support 8.3 aliases, the function fails with ERROR_INVALID_PARAMETER if the path is longer than 67 bytes.

Man kann die Unterstützung für kurze Dateinamen unter NTFS abschalten. Du solltest auf alle Fälle den Fehler abfangen.

EWeiss 11. Mär 2009 22:39

Re: TStringList Max String länge
 
Zitat:

Zitat von Luckie
Zitat:

Zitat von EWeiss
Ich übergebe den Pfad nun mit GetShortName ist das einzigste was mir einfällt.

Du musst aber aufpassen:
Zitat:

Zitat von Windows PSDK
When an application calls this function and specifies a path on a volume that does not support 8.3 aliases, the function fails with ERROR_INVALID_PARAMETER if the path is longer than 67 bytes.

Man kann die Unterstützung für kurze Dateinamen unter NTFS abschalten. Du solltest auf alle Fälle den Fehler abfangen.

Danke für die Infos war mir nicht bekannt .. gut zu wissen.
Denke das müßte reichen.
Delphi-Quellcode:
procedure SearchFiles(PluginType: byte;
                      path: string;
                      recurse: BOOL; var List :TStrings);
var
  sr : TSearchrec;
  tmpPath: string;

begin

 if (Path[length(path)] <> '\') then
    path := path + '\';

 try
     tmpPath := GetShortName(Path);
 except
     if GetlastError = ERROR_INVALID_PARAMETER then
       tmpPath := Path;
 end;
@Mutze1
1. da war ich schon daher auch die Idee mit GetShortName
2. Habe es mal mit SafeLoadLibrary() versucht das gleiche problem
Die DLL ist mit Petite Kompremiert http://www.un4seen.com/petite/
dieser scheint die Datei zerschossen zu haben oder es ist einfach nicht möglich diese dann mit LoadLibrary zu laden.

trotzdem danke muss halt alles versuchen.

gruss Emil

Luckie 11. Mär 2009 23:13

Re: TStringList Max String länge
 
Denk aber daran, dass API-Funktionen keine Exception werfen, sondenr einen Fehlercode zurückgeben. Deine Funktion GetShortName muss also im Fehlerfall eine Exception werfen.

EWeiss 11. Mär 2009 23:16

Re: TStringList Max String länge
 
Zitat:

Zitat von Luckie
Denk aber daran, dass API-Funktionen keine Exception werfen, sondenr einen Fehlercode zurückgeben. Deine Funktion GetShortName muss also im Fehlerfall eine Exception werfen.

Verstehe ich jetzt nicht was du meinst.. sorry
Ist was falsch an meiner Error prüfung ?

EDIT:
Ach so verstehe jetzt was du meinst
Hier mal die Funktion aus dem Forum hier...

Delphi-Quellcode:
var
  ErrorCode: DWord;
Delphi-Quellcode:
function GetShortName(sLongName: string): string;
var
  sShortName:   string;
  nShortNameLen: Integer;
begin
  SetLength(sShortName, MAX_PATH);
  nShortNameLen := GetShortPathName(PChar(sLongName), PChar(sShortName), MAX_PATH - 1);
  if (0 = nShortNameLen) then
  begin
    ErrorCode := ERROR_INVALID_PARAMETER; // Du meinst das hier in etwa ? 
    Exit;
  end;
  SetLength(sShortName, nShortNameLen);
  Result := sShortName;
end;
gruss Emil

Muetze1 12. Mär 2009 07:57

Re: TStringList Max String länge
 
Zitat:

Zitat von EWeiss
@Mutze1
1. da war ich schon daher auch die Idee mit GetShortName

Und warum nutzt du dann nicht die im Text angegebene Möglichkeit über UNC Angaben um wenigstens auf eine Pfadtiefe von 32767 Zeichen zu kommen?

Zitat:

Zitat von EWeiss
2. Habe es mal mit SafeLoadLibrary() versucht das gleiche problem

Ich hatte gehofft, dass es ein MS Visual C Startup Code in der DLL ist, der das CW der FPU umsetzt, ansonsten hätte es keine Auswirkungen.

EWeiss 12. Mär 2009 08:18

Re: TStringList Max String länge
 
@Muetze
Delphi-Quellcode:
Und warum nutzt du dann nicht die im Text angegebene Möglichkeit über UNC Angaben um wenigstens auf eine Pfadtiefe von 32767 Zeichen zu kommen?
Weil ich zu meiner schande gestehen muss das ich nur die hälfte von dem verstehe was da steht.
Habe nie English gelernt das einzige was ich verstehe ist Denglish aus der Werbung und (Computer English) oder wie man es sonst nennen will.

gruss Emil

Klaus01 12. Mär 2009 08:22

Re: TStringList Max String länge
 
Guten Morgen Emil,

eingentlich brauchst Du nur \\?\ vor die PfadStrings schreiben,
denn dann weiß Windows dass ein langer Pfadname folgt.

Delphi-Quellcode:
s:=extractFileExt('\\?\'+Aplugin);
Grüße
Klaus

EWeiss 12. Mär 2009 08:38

Re: TStringList Max String länge
 
Zitat:

Zitat von Klaus01
Guten Morgen Emil,

eingentlich brauchst Du nur \\?\ vor die PfadStrings schreiben,
denn dann weiß Windows dass ein langer Pfadname folgt.

Delphi-Quellcode:
s:=extractFileExt('\\?\'+Aplugin);
Grüße
Klaus

Guten Morgen Klaus
Danke für die Info..

Und dann verkürzt Window den Pfad ?

gruss Emil

Klaus01 12. Mär 2009 08:42

Re: TStringList Max String länge
 
Zitat:

Zitat von EWeiss
Guten Morgen Klaus
Danke für die Info..

Und dann verkürzt Window den Pfad ?

gruss Emil

wenn ich das richtig verstanden habe:
Nö, die ExctractFileExt ruft eine Win-Api auf und die kommt dann mit den langen Pfadnamen zurecht.

Grüße
Klaus

Luckie 12. Mär 2009 08:44

Re: TStringList Max String länge
 
Zitat:

Zitat von EWeiss
Ach so verstehe jetzt was du meinst
Hier mal die Funktion aus dem Forum hier...

Delphi-Quellcode:
var
  ErrorCode: DWord;
Delphi-Quellcode:
function GetShortName(sLongName: string): string;
var
  sShortName:   string;
  nShortNameLen: Integer;
begin
  SetLength(sShortName, MAX_PATH);
  nShortNameLen := GetShortPathName(PChar(sLongName), PChar(sShortName), MAX_PATH - 1);
  if (0 = nShortNameLen) then
  begin
    ErrorCode := ERROR_INVALID_PARAMETER; // Du meinst das hier in etwa ? 
    Exit;
  end;
  SetLength(sShortName, nShortNameLen);
  Result := sShortName;
end;

Richtig. Und damit ist dieser try-except-Block:
Delphi-Quellcode:
try
     tmpPath := GetShortName(Path);
except
     if GetlastError = ERROR_INVALID_PARAMETER then
       tmpPath := Path;
end;
überflüssig.

Aber ich würde in der Funktion GetShortName eine Exception werfen.

EWeiss 12. Mär 2009 08:57

Re: TStringList Max String länge
 
Zitat:

Zitat von Luckie

Richtig. Und damit ist dieser try-except-Block:
Delphi-Quellcode:
try
     tmpPath := GetShortName(Path);
except
     if GetlastError = ERROR_INVALID_PARAMETER then
       tmpPath := Path;
end;
überflüssig.

Aber ich würde in der Funktion GetShortName eine Exception werfen.

Ich mache hier nichts anderes als den alten Pfad mit langen Namen weiter zu leiten sollte der Kurze nicht unterstützt werden.
Warum wäre dieser Block dann ungültig ?.

Edit:
Grmm .. glaube du meinst lediglich den Block nicht die abfrage.
Delphi-Quellcode:
     
tmpPath := GetShortName(Path);
if GetlastError = ERROR_INVALID_PARAMETER then
  tmpPath := Path;
das wäre es dann.
end Edit

Zitat:

Aber ich würde in der Funktion GetShortName eine Exception werfen.
werfen ?
Hab ich noch nichts mit zu tun gehabt
Wie geht das ?


@Klaus01
Zitat:

wenn ich das richtig verstanden habe:
Nö, die ExctractFileExt ruft eine Win-Api auf und die kommt dann mit den langen Pfadnamen zurecht.
Das ist aber sehr unsicher. Oder ?

Hab jetzt verschiedene möglichkeiten.
Die frage ist was nun am besten verwenden.

gruss Emil

Luckie 12. Mär 2009 09:27

Re: TStringList Max String länge
 
So könnte es zum Beispiel gehen:

Delphi-Quellcode:
resourcestring
  rsEInvalidParameter = 'Der Parameter %s ist ungültig';

type
  EInvalidParameter = class(Exception)
  public
    constructor CreateFmt(Parameter: string);
  end;

{ EInvalidParameter }

constructor EInvalidParameter.CreateFmt(Parameter: string);
begin
  inherited CreateFmt(rsEInvalidParameter, [Parameter]);
end;

procedure TForm1.RaiseDemoException;
begin
  Raise EInvalidParameter.CreateFmt('Foobar');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  try
    RaiseDemoException;
  except
    on E: EInvalidParameter do ShowMessage(E.Message);
  end;
end;
Ich habe eine eigene Exceptionklasse abgeleitet, weil ich keine passende, fertige Exception gefunden habe.

EWeiss 12. Mär 2009 09:37

Re: TStringList Max String länge
 
@Luckie
Danke schön ..
Dann kann ich die noch ausbauen für etwaige andere überprüfungen.

gruss Emil

Luckie 12. Mär 2009 09:55

Re: TStringList Max String länge
 
Richtig du kannst dir da dann weitere Exceptions für deine speziellen Fälle deklarieren. Habe ich bei meiner Adress-Datenbank auch gemacht. Da habe ich zum Beispiel die Exeptions:

Delphi-Quellcode:
type
  EArgumentNull = class(Exception)
  public
    constructor CreateFmt(const MethodeName: String; const Parameter: String);
  end;

  EXMLError = class(Exception)
  public
    constructor CreateFmt(const MethodeName: String; const Msg: String; const Parameter: String);
  end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:00 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-2025 by Thomas Breitkreuz