![]() |
Groß/Kleinschreibung (Pfad) Original erhalten?
Hallo,
wenn ich in einer Variable "c:\windows\syswow64\" oder "c:\winDows\SYSwow64\" (als Beispiel) stehen habe, kann ich damit arbeiten aber zur Ansicht würde ich gerne die originale Groß-/Kleinschreibung nutzen. Original ist der Pfad "C:\Windows\SysWOW64". Ich frage mich, wie ich mit einfachen Mitteln (ohne FindFirst/Next) da rankomme. Vielleicht gibt es eine Win API Funktion die ich dafür nutzen/zweckentfremden kann? Michael |
AW: Groß/Kleinschreibung (Pfad) Original erhalten?
Such mal hier im Forum nach CSIDL
|
AW: Groß/Kleinschreibung (Pfad) Original erhalten?
Zitat:
Wenn ich jetzt z.B. ein neuen Ordner anlege "C:\TeSt", würde ich gerne ohne FindFirst/Next da herankommen, sprich ich übergebe "c:\test" und bekomme "C:\TeSt" zurück. Michael |
AW: Groß/Kleinschreibung (Pfad) Original erhalten?
Ich habs nicht getestet, vielleicht gibt Dir
![]() Oder ExtractFilePath ? Oder ![]() Reines WinApi würde ich SHGetFileInfo eventuell mit PIDL verwenden, das sollte Dich auch ans Ziel bringen. |
AW: Groß/Kleinschreibung (Pfad) Original erhalten?
Ich denke, du suchst
![]() Intern wird dort aber auch auf FindFirst/FindClose zurückgegriffen. |
AW: Groß/Kleinschreibung (Pfad) Original erhalten?
Danke für die Hilfestellung.
habe mal alles ausprobiert (ExtractFilePath, ExpandFileName, GetDirectoryName) und mit SHGetFileInfo auch herumexperimentiert. Keine Erfolge und zu "ExpandFileNameCase"... (kannte ich noch nicht) da kann man etwas herausholen aber dennoch müsste man das Verzeichnis (z.B. "C:\Ich\bin\so\froh\wie\der\Mops\im\Hafenstroh \") splitten und in Strings aufteilen. Am Ende eines Pfads kann man noch "\." oder "\.." angeben um ein oder zwei Verzeichnisse zurück zu gehen und hier die originale Groß-/Kleinschreibung zu bekommen. Nur nicht alles auf einmal. Aber wegen diesem Splitten und stets erneuten Aufruf von FindFirst (auf die Idee bin ich nämlich auch gekommen) - was die Funktion ja macht, ist das alles nicht gerade Optimal. Naja, nicht so schlimm. Trotzdem Danke für eure Hilfestellung. Michael |
AW: Groß/Kleinschreibung (Pfad) Original erhalten?
Zitat:
|
AW: Groß/Kleinschreibung (Pfad) Original erhalten?
Liste der Anhänge anzeigen (Anzahl: 1)
Habe es auch noch mit
Delphi-Quellcode:
probiert, auch negativ.
FileCtrl.ProcessPath(s,drv,Dir,filename);
Lustigerweise schlägt selbst ein FileCtrl.SelectDirectory() fehl, so ein Ergebnis hätte ich von so einer Funktion nicht erwartet. Anhang 49789 Ps, im Nachhinein ist mir auch eingefallen mit SHGetFileInfo bekommt man nur Infos, wie der Name selbst beinhaltet, nur leider nicht Deine benötigten. FindFirst() scheint wohl einzige Api zu sein, oder aus MFT auslesen. |
AW: Groß/Kleinschreibung (Pfad) Original erhalten?
Nun habe ich eine Lösung.
Delphi-Quellcode:
uses
ActiveX, ShlObj, SHDocVw, ComObj; function PathToPIDL(const Path: string): PItemIDList; const SFGAO_STREAM = $00400000; var Count: ULONG; Attributes: ULONG; ShellFolder: IShellFolder; begin OleCheck(SHGetDesktopFolder(ShellFolder)); Attributes := SFGAO_FOLDER or SFGAO_STREAM; OleCheck(ShellFolder.ParseDisplayName(0, nil, PWideChar(WideString(Path)), Count, Result, Attributes)); if not ((Attributes and SFGAO_FOLDER = SFGAO_FOLDER) and (Attributes and SFGAO_STREAM <> SFGAO_STREAM)) then begin CoTaskMemFree(Result); raise Exception.Create('Could not convert string to PIDL'); end; end; function PIDLToPath(const PIDL: PItemIDList): string; var Path: array[0..Max_Path] of Char; begin if ShGetPathFromIDList(PIDL, Path) then Result := Path else raise Exception.Create('Could not convert PIDL to string'); end; procedure TfrmMain.FormCreate(Sender: TObject); var s: string; PIDL: PItemIDList; begin s := 'c:\uSERs\PUBlic\DeskTop'; PIDL := PathToPIDL(s); s := PIDLToPath(PIDL); Memo1.Lines.Add(S); end; Zitat:
ps: Bearbeite das Uses, kann sein das da zuviel steht. |
AW: Groß/Kleinschreibung (Pfad) Original erhalten?
Danke @KodeZwerg
Geht SUPER. Dankeschön Habe noch zwei Fragen. Im "if not" Bereich steht "CoTaskMemFree". Sonst nicht. Sollte es nicht so oder so ausgeführt werden? Aber es ist ja hier ein "Result" was ja gebraucht wird. Dann kenne ich das "WideString" gar nicht. Bei "PWideChar(WideString(Path))". Ich mach sonst immer ein "PWideChar(Path)". Das geht auch aber was ist der Unterschied? Da ist mir sowieso noch etwas im Gedächtnis. Bin mir da nicht sicher, aber glaube gelesen zu haben das man bei PWideChar(stringvariable) noch ein "#0" dazutun soll. Also PWideChar(stringvariable+#0). Kann das sein? Ich habe jedenfalls mal folgende Funktion aus den beiden gemacht. OleCheck kenne ich auch nicht und habe es mal Anhand ähnlicher Funktionen die ich nutze abgeändert. Dabei ist folgendes herausgekommen. Hier wird dann "CoTaskMemFree" auch stets freigegeben und im jeden Fehlerfall einfach der übergebene Pfad wieder zurückgegeben. Ein nachfolgender Attribut-Check der beiden "SFGAO_..." Flags habe ich auch weggelassen, da ich denke, dass dies nicht mehr nötig ist, wenn es bei der Funktion "ParseDisplayName" gesetzt wurde. Das ist aber weniger ein technisches Verständnis, eher so eine Überlegung :)
Code:
Gruß Michael
Function PathToCS(Const Path: UnicodeString): UnicodeString;
Var Count: ULONG; Attrs: ULONG; ShellFolder: IShellFolder; Pa: Array[0..Max_Path] Of Char; Pidl: PItemIDList; Begin Attrs := SFGAO_FOLDER or SFGAO_STREAM; Count := 0; If SHGetDesktopFolder(ShellFolder) = S_OK Then Begin If ShellFolder.ParseDisplayName(0,Nil,PWideChar(Path),Count,Pidl,Attrs) = S_OK Then Begin If SHGetPathFromIDList(Pidl, Pa) Then Result := IncludeTrailingPathDelimiter(Pa) Else Result := IncludeTrailingPathDelimiter(Path); CoTaskMemFree(Pidl); End Else Result := IncludeTrailingPathDelimiter(Path); End Else Result := IncludeTrailingPathDelimiter(Path); End; |
AW: Groß/Kleinschreibung (Pfad) Original erhalten?
Zitat:
Solange es das macht was Du möchtest ist ja alles im grünen Bereich :lol: |
AW: Groß/Kleinschreibung (Pfad) Original erhalten?
Zitat:
Zitat:
Ps: Mag sein das neuere Delphi Version all das anders handhaben oder schon Routinen dafür besitzen. Für D2009 sollte das gelten was ich schrieb. |
AW: Groß/Kleinschreibung (Pfad) Original erhalten?
Nur, bei der Lösung kannst du nie Prüfen, ob die Funktion nicht fehlgeschlagen ist. OK, mag nicht so wichtig sein, da es sich wohl nur um eine optische Spielerei handelt. Aber ich wollte es nur mal erwähnt haben. ;)
|
AW: Groß/Kleinschreibung (Pfad) Original erhalten?
Zitat:
wenn sich das auf meinen Vorschlag bezieht, eigentlich sollte der nur zwei mögliche Resultate liefern. Entweder ein verwertbares oder eine Exception. ps: Man kann auch Result als Boolean auswerten und in Functiom (var DasResult:Typ) definieren. |
AW: Groß/Kleinschreibung (Pfad) Original erhalten?
@KodeZwerg... danke für die Info zum WideString.
@Luckie... Ja, die originale Groß-Kleinschreibung dient nur zur Ansicht. Deswegen keine weitere Fehlerbehandlung. Wenn's halt nicht geht, bleibt der Pfad halt so, wie er zuvor angegeben wurde. Deswegen habe ich auch aus den zwei Funktionen (die ich ja nicht schlecht mache), eine gebaut. Ist ja dann auch einfach anzugeben "path := PathToCS(path);" So passt das für meine Zwecke ganz gut. Also nochmals vielen Dank Michael |
AW: Groß/Kleinschreibung (Pfad) Original erhalten?
Zitat:
An der Funktion (bzw. an meine Funktion die ich entsprechend für meine Bedürfnisse abgeändert habe <- nachfolgender Code), bin ich gerade noch am rumwerkeln.
Code:
Ich probiere nämlich bei langen Verzeichnissen dies auch so zu lösen. Versuche mich an "SHGetPathFromIDListW" (anstatt "SHGetPathFromIDList" (ohne W)). Aber was ich auch mache, sobald mehr als 260 (glaub ich) Zeichen im Pfad sind (z.B. C:\Test\UnterOrdner\Unter\ganzvielunter\...\...\.. .), bekomme ich kurze Pfade zurück geliefert. Also z.B. diese "ICHGEH~1" verkürzten Namen. Hier im Pfad am Anfang "\\?\" anzuhängen klappt erst recht nicht.
Function PathToCS(Const Path: UnicodeString): UnicodeString;
Var Count: ULONG; Attrs: ULONG; ShellFolder: IShellFolder; Pa: Array[0..Max_Path] Of Char; Pidl: PItemIDList; Begin Attrs := SFGAO_FOLDER or SFGAO_STREAM; Count := 0; If SHGetDesktopFolder(ShellFolder) = S_OK Then Begin If ShellFolder.ParseDisplayName(0,Nil,PWideChar(Path),Count,Pidl,Attrs) = S_OK Then Begin If SHGetPathFromIDList(Pidl, Pa) Then Result := IncludeTrailingPathDelimiter(Pa) Else Result := IncludeTrailingPathDelimiter(Path); CoTaskMemFree(Pidl); End Else Result := IncludeTrailingPathDelimiter(Path); End Else Result := IncludeTrailingPathDelimiter(Path); End; Meine Versuche für den 2. Parameter für "SHGetPathFromIDListW":
Code:
Aber so geht das einfach nicht.
Var Pa: PWideChar; // zuvor "Array[0..Max_Path] Of Char;"
const NTFS_MAX_PATH = 32767; GetMem(Pa, (NTFS_MAX_PATH + 1) * 2); If SHGetPathFromIDListW (Pidl, Pa) ... Vielleicht hast du (oder jemand anderes) eine Idee? Micha |
AW: Groß/Kleinschreibung (Pfad) Original erhalten?
Ne, soviele Unterordner habe ich noch nicht getestet, hier zwei Funktionen um aus nem legitimen 8.3 wieder was langes zurück zu erhalten, ohne FindFirst() aufzurufen.
Delphi-Quellcode:
Was zuviel ist, wirf raus.
uses Windows, SysUtils, ActiveX, ShlObj;
Passend zum ersten PIDL Beispiel, hier ein weiteres
Delphi-Quellcode:
Oder lieber per WinApi:
function LongPathFromShort(const ShortPath: string): string;
var iAttributes: Cardinal; iEaten: Cardinal; IntfDesktop: IShellFolder; IntfMalloc: IMalloc; pItemList: PItemIDList; sFile: WideString; szFile: array[0..MAX_PATH] of Char; begin Result := ShortPath; if not FileExists(ShortPath) then Exit; if Succeeded(SHGetDesktopFolder(IntfDesktop)) then begin sFile := ShortPath; iAttributes := 0; if Succeeded(IntfDesktop.ParseDisplayName(0, nil, POleStr(sFile), iEaten, pItemList, iAttributes)) then begin SHGetPathFromIDList(pItemList, szFile); Result := szFile; SHGetMalloc(IntfMalloc); IntfMalloc.Free(pItemList) end end end;
Delphi-Quellcode:
function GetLongName(const APath: string): string;
var Buffer: array[0..MAX_PATH] of Char; Required: Integer; begin Required := GetLongPathName(PChar(APath), Buffer, Length(Buffer)); if Required > MAX_PATH then {Buffer too small} begin SetLength(Result, Required - 1); GetLongPathName(PChar(APath), Pointer(Result), Required); end else if Required = 0 then {Error} Result := APath else SetString(Result, Buffer, Required); end; Ich habe es nicht mit extrem langen/tiefen Ordner-Namen getestet, bei mir machts jedenfalls das was es soll, 8.3 entfalten. |
AW: Groß/Kleinschreibung (Pfad) Original erhalten?
Danke KodeZwerg. Daran hatte ich auch schon gedacht aber wollte mal schauen ob sich's auch gleich lösen lässt. Zum Glück brauch ich dies nur für ein Programmstart. Dann ist es auch nicht so schlimm, wenn sie kurz werden und man sie wieder lang machen muss. Hab die API Version mal kurz getestet. Die andere noch nicht. Grad wenig Zeit für's programmieren. Also vielen Dank für die Hilfe. Micha
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:02 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