![]() |
Betriebssystem: Win 10
Probleme, wenn ShortPathName länger ist, als der eigentliche/lange Dateiname?
Moin Moin,
das genaue Problem kennen wir nicht nicht und sind noch am Suchen, bzw. am Nachstellen des Problems. Wir bekommen von Outlook per Drag&Drop einen Dateianhang. Vor Jahren hatten wir alles umbebaut, weil Outlook plötzlich Dateien als STREAM übergab, aber jetzt wieder als WM_DROPFILE mit Kopie im Temp. Nun heißt es bei einem Rechner eines Kunden "Datei existiert nicht". Ja klar, da fehlen am Ende zwei Buchstaben. Scheinbar gibt ![]() Und ja, natürlich rufe ich GetLongPath nicht mit MAX_PATH auf, oder sowas, sondern zwei mal, also einmal um die Länge zu bekommen und die String-Länge zu setzen und dann nochmal, um die Daten zu bekommen. Witzig ist jetzt aber, dass Outlook uns den ShortPathName gibt und es fiel irgendwann auf, dass weiter vorne ein ShortName zufällig zwei Zeichen länger ist, als das Original. Und ![]()
Code:
Ein erster Test, via CMD eine Datei mit soeinem Namen zu erzeugen und sich den Kurzname geben zu lassen, hatte nicht funktioniert.
C:\Users\m.grawxyz\AppData\Local\Temp\abcdefg.hij
C:\Users\M1D63~1.GRA\AppData\Local\Temp\abcdefg.h Weder in Win10, noch in Win11 wurde überhaupt ein Kurzname erzeugt. (dieses Verhalten ist ja, seit 'ner ganzen Weile, standardmäßig im Windows deaktiviert) In Google und Co. fand ich noch nichts, aber kennt hier vielleicht jemand auch sowas ähnliches? Auf NTFS macht %~s1 aktuell garnichts, aber auf Samba (NAS) zeigt es, dass der Befehl per se funktioniert. Zitat:
|
AW: Probleme, wenn ShortPathName länger ist, als der eigentliche/lange Dateiname?
Hmm,
Vielleicht hat es was mit dieser Bermerkung zu GetLongPathName zu tun, wobei ich sie nicht ganz verstehe: Zitat:
Was passiert denn, wenn Du zwei Zeichen mehr als Länge angibst? |
AW: Probleme, wenn ShortPathName länger ist, als der eigentliche/lange Dateiname?
So, ich hab es jetzt auch in einem Programm versucht,
sowie dort auch explizit nochmal mit der ANSI-API, aber im Windows 11 bekomme ich niemals einen Kurznamen. (außer wenn ich es im Samba auf einen Share des Synology-NAS versuche) Auf einem Windows Server 2016 dagegen, klappt es, mit dem Kurznamen-Test. siehe Anhang, die Test.cmd ausführen So, jetzt bau ich noch ein Drag&Drop-Testprogramm fertig und dann mal beim Kunden nachsehn. Zitat:
aber selbst wenn dabei ein Fehler drin wäre, dann dürfte nur ein und nicht zwei Zeichen fehlen.
Es gibt milliarden Varianten der Implementation. Da "hier" der Pfad kürzer als MAX_PATH ist, dürfte alles der Nachfolgenden gehen. Die ersten 3 machen es aber eigetlich richtig und fragen vorher die Länge ab. Empfehlen würde ich die 2 (meine Implementation :angle2:) ... Viele machen es mehr wie bei 3 oder bissl wie 1, aber wozu den Speichermanager unnötig beanspruchen.
Delphi-Quellcode:
function GetShortName(Filename: string): string;
var Len, Res: Cardinal; Buffer: TBytes; begin // so mehr C++-ig Len := GetShortPathName(PChar(Filename), nil, 0); SetLength(Buffer, Len * SizeOf(Char)); // oder halt eigentlich mit Pointer, GetMem und anschließend FreeMem (und natürlich mit einem Try-Finally) Res := GetShortPathName(PChar(Filename), Pointer(Buffer), Len); if Res > Len then raise Exception.Create('das sollte zwar nie passieren, da wir die Größe ja vorher abgefragt hatten, aber wir prüfen es einfach nochmal'); SetLength(Result, Res); MoveMemory(PChar(Result), Pointer(Buffer), Res * SizeOf(Char)); end; function GetShortName(Filename: string): string; begin // ich schneide die #0 ab, da String implizit zwei #0#0 am Ende besitzt und Diese auch beschreibbar sind SetLength(Result, GetShortPathName(PChar(Filename), nil, 0) - 1); GetShortPathName(PChar(Filename), PChar(Result), Length(Result) + 1); end; function GetShortName(Filename: string): string; begin // Puffer erstmal inkl. der #0 und dann wieder abschneiden SetLength(Result, GetShortPathName(PChar(Filename), nil, 0)); SetLength(Result, GetShortPathName(PChar(Filename), PChar(Result), Length(Result)); // hier müsste man noch -1, wenn die #0 bei OK inkl. wäre end; function GetShortName(Filename: string): string; begin // MAX_PATH = maximal 260 Chars // 3 = Laufwerk (C:\) // 256 = Pfad // 1 = #0 SetLength(Result, MAX_PATH); SetLength(Result, GetShortPathName(PChar(Filename), PChar(Result), MAX_PATH); // hier müsste man noch -1, wenn die #0 bei OK inkl. wäre end; function GetShortName(Filename: string): string; var Temp: array[0..MAX_PATH-1] of Char; Len: Cardinal; begin Len := GetShortPathName(PChar(Filename), @Temp, MAX_PATH); SetString(Result, @Temp, Len); // bei einem Fehler, z.B. wenn Pfad länger MAX_PATH, dann wäre eine #0 im String //Result := PChar(Result); // den Fehlerfall könnte man so beheben (#0 weg), aber der Pfad bleibt dennoch abgeschnitten (maximal 259 Zeichen) end; function GetShortName(Filename: string): string; var Temp: array[0..MAX_PATH-1] of Char; begin // einfach blind hindurch GetShortPathName(PChar(Filename), @Temp, MAX_PATH); Result := Temp; end; function GetShortName(Filename: string): string; var Temp: array[0..MAX_PATH-1] of Char; begin // auf Gott vertrauen und hoffen es knallt nicht, // aber wenn keine #0 im Temp vorkommt, dann ab in die Hölle GetShortPathName(PChar(Filename), @Temp, MAX_PATH); Result := PChar(@Temp); end; function GetShortName(Filename: string): string; var Temp: array[0..MAX_PATH-1] of Char; begin // einfach blind hindurch if GetShortPathName(PChar(Filename), @Temp, MAX_PATH) <> 0 then Result := PChar(@Temp) else Result := ''; end; ... |
AW: Probleme, wenn ShortPathName länger ist, als der eigentliche/lange Dateiname?
Ist es möglich dass Dateinamen beim Drag und drop Double-Null-Terminated Strings sind, weil theoretisch gesehen kann es sich ja auch um ein Array von Strings handeln und ich meine mal gelesen zu haben dass in C++ für solche Zwecke gerne Double-Null terminated Strings benutzt werden.
|
AW: Probleme, wenn ShortPathName länger ist, als der eigentliche/lange Dateiname?
Ja, wenn es ein WM_DROPFILES ist, dann ist es eine DoppelNull-Liste (#0#0), aber DragQueryFile liefert jeweils nur einen Dateinamen und die sind EinfachNull (#0).
Wenn es über IDropTarget geht, ist es wieder anders. (immer nur eine #0) |
AW: Probleme, wenn ShortPathName länger ist, als der eigentliche/lange Dateiname?
Leider lieferte der erste Test noch keine Antwort/Lösung.
Ja, ich kann ein * anhängen und dann nach der Datei suchen, hoffen nur eine Datei zu finden und Diese dann zu nehmen, aber eine wirkliche Lösung ist das auch nicht. (dennoch erstmal so ins Programm eingebaut) Jetzt nochmal unsere Drag&Drop-Komponente aufgebohrt und überall Logasgaben und Tests reingebaut, dann schonmal in unser Probramm erstmal einen "BugfixCode", aber weiß nicht, ob der an der richtigen Stelle ist, da ich noch nichtmal weiß, ab wo es genau knallt. Und nachdem ich nun auch noch erfahren hatte, was das für Kreise zieht, hatte ich meinen zweiten Test nun etwas größer ausgelegt und tagelang an an meiner Testapp gefeilt. Da war letztens der Firmencheff dabei, dann die IT, der Abteilungsleiter, der Mitarbeiter des Arbeitsplatzes und via Teamviewer unser Supporttyp .... und am Ende keine Ergebnisse. :oops: Und es brauchte Tage, bis das alles in die Wege geleitet wurde, um mal eben eine Test.exe und eine Batch dort laufen zu lassen. (die bauen unter anderem Teile für ein großes europäisches Luftfahrtunternehmen und haben in ihrer IT sich an gewisse Vorgaben zu halten) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:07 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