Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Groß/Kleinschreibung (Pfad) Original erhalten? (https://www.delphipraxis.net/197584-gross-kleinschreibung-pfad-original-erhalten.html)

MicMic 18. Aug 2018 18:45

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

Papaschlumpf73 18. Aug 2018 19:11

AW: Groß/Kleinschreibung (Pfad) Original erhalten?
 
Such mal hier im Forum nach CSIDL

MicMic 18. Aug 2018 19:18

AW: Groß/Kleinschreibung (Pfad) Original erhalten?
 
Zitat:

Zitat von Papaschlumpf73 (Beitrag 1411040)
Such mal hier im Forum nach CSIDL

Ist mir ein Begriff, kenne es aber nur in Verbindung mit Standard-Ordner/System-Ordner usw.
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

KodeZwerg 18. Aug 2018 21:10

AW: Groß/Kleinschreibung (Pfad) Original erhalten?
 
Ich habs nicht getestet, vielleicht gibt Dir ExpandFileName den Namen in schön wieder?
Oder ExtractFilePath ?
Oder System.IOUtils.TPath.GetDirectoryName ?

Reines WinApi würde ich SHGetFileInfo eventuell mit PIDL verwenden, das sollte Dich auch ans Ziel bringen.

Uwe Raabe 18. Aug 2018 21:52

AW: Groß/Kleinschreibung (Pfad) Original erhalten?
 
Ich denke, du suchst ExpandFileNameCase

Intern wird dort aber auch auf FindFirst/FindClose zurückgegriffen.

MicMic 18. Aug 2018 22:36

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

Uwe Raabe 18. Aug 2018 22:59

AW: Groß/Kleinschreibung (Pfad) Original erhalten?
 
Zitat:

Zitat von MicMic (Beitrag 1411061)
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.

Ich hatte jetzt angenommen, die Funktion tut bereits alles was du brauchst. Vielleicht habe ich die Anforderung aber auch nur falsch verstanden.

KodeZwerg 18. Aug 2018 23:33

AW: Groß/Kleinschreibung (Pfad) Original erhalten?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Habe es auch noch mit
Delphi-Quellcode:
FileCtrl.ProcessPath(s,drv,Dir,filename);
probiert, auch negativ.
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.

KodeZwerg 19. Aug 2018 00:40

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:

C:\Users\Public\Desktop
Viel Spass damit.

ps: Bearbeite das Uses, kann sein das da zuviel steht.

MicMic 19. Aug 2018 09:06

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:
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;
Gruß Michael


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:10 Uhr.
Seite 1 von 2  1 2      

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