AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Delphi-PRAXiS - Lounge Betriebssysteme Probleme, wenn ShortPathName länger ist, als der eigentliche/lange Dateiname?
Thema durchsuchen
Ansicht
Themen-Optionen

Probleme, wenn ShortPathName länger ist, als der eigentliche/lange Dateiname?

Ein Thema von himitsu · begonnen am 4. Jun 2024 · letzter Beitrag vom 13. Jul 2024
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#1

Probleme, wenn ShortPathName länger ist, als der eigentliche/lange Dateiname?

  Alt 4. Jun 2024, 16:05
Betriebssystem: Win 10
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 MSDN-Library durchsuchenGetLongPathName den Namen abgeschnitten zurück und tut dabei den auch den ShortName nicht durch den Langen ersetzen.


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 MSDN-Library durchsuchenGetLongPathName macht aus dem M1D63~1.GRA auch nicht den LongName.
Code:
C:\Users\m.grawxyz\AppData\Local\Temp\abcdefg.hij
C:\Users\M1D63~1.GRA\AppData\Local\Temp\abcdefg.h
Ein erster Test, via CMD eine Datei mit soeinem Namen zu erzeugen und sich den Kurzname geben zu lassen, hatte nicht funktioniert.
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 von Share per PUSHD als Laufwerk, damit CMD funktioniert:
Z:\Neuer Ordner\m.gramxyzabcdef
Z:\N4BIQL~M\M9OYAG~B
$2B or not $2B

Geändert von himitsu ( 4. Jun 2024 um 16:38 Uhr)
  Mit Zitat antworten Zitat
TomyN

Registriert seit: 8. Nov 2006
Ort: Bayreuth
252 Beiträge
 
Delphi 10.3 Rio
 
#2

AW: Probleme, wenn ShortPathName länger ist, als der eigentliche/lange Dateiname?

  Alt 5. Jun 2024, 09:10
Hmm,

Vielleicht hat es was mit dieser Bermerkung zu GetLongPathName zu tun, wobei ich sie nicht ganz verstehe:

Zitat:
If the return value is greater than the value specified in cchBuffer, you can call the function again with a buffer that is large enough to hold the path. For an example of this case, see the Example Code section for GetFullPathName.

Note Although the return value in this case is a length that includes the terminating null character, the return value on success does not include the terminating null character in the count.
Gut, eigentlich sollte also die Länge für den String + 1 kommen, wenn die Anzahl am Anfang zu klein ist. Evtl. ist sie das nicht, so dass die Zahl dann um eins zu kurz wäre.
Was passiert denn, wenn Du zwei Zeichen mehr als Länge angibst?
Thomas Neumann
Meine Projekte
www.satlive.audio
www.levelcheck.de
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#3

AW: Probleme, wenn ShortPathName länger ist, als der eigentliche/lange Dateiname?

  Alt 5. Jun 2024, 12:24
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.


Vielleicht hat es was mit dieser Bermerkung zu GetLongPathName zu tun, wobei ich sie nicht ganz verstehe
Ist schon richtig, auch wenn es schon bissl "eigenartig" ist,
aber selbst wenn dabei ein Fehler drin wäre, dann dürfte nur ein und nicht zwei Zeichen fehlen.
  • wenn Fehler (z.B. Buffer zu klein oder nicht angegeben), dann Result=Chars+#0
  • wenn kein Fehler (Buffer und groß genug), dann nur Result=Chars (ohne #0)
  • so oder so, reingeben muß man immer inkl. #0 (oder 0 wenn Buffer=nil)
    und raus bekommt man die benötigte Länge (bei Fehler, bzw. Abfrage) oder nur die Anzahl der Zeichen, wenn es OK war.

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 ) ... 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;

...
$2B or not $2B
  Mit Zitat antworten Zitat
QuickAndDirty

Registriert seit: 13. Jan 2004
Ort: Hamm(Westf)
1.944 Beiträge
 
Delphi 12 Athens
 
#4

AW: Probleme, wenn ShortPathName länger ist, als der eigentliche/lange Dateiname?

  Alt 5. Jun 2024, 12:51
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.
Andreas
Monads? Wtf are Monads?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#5

AW: Probleme, wenn ShortPathName länger ist, als der eigentliche/lange Dateiname?

  Alt 5. Jun 2024, 13:29
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)
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#6

AW: Probleme, wenn ShortPathName länger ist, als der eigentliche/lange Dateiname?

  Alt 13. Jul 2024, 12:51
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.
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)
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:58 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