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/)
-   -   : Fehler beim Umbenennen der Datei (https://www.delphipraxis.net/104258-fehler-beim-umbenennen-der-datei.html)

Opa 30. Nov 2007 10:59


: Fehler beim Umbenennen der Datei
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich bekomme folgende Meldung aus: Fehler beim Umbenennen der Datei...(... kann nicht umbenannt werden: Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch.
Dieses passiert im ersten Arbeitsschritt zur Dateinamen bereinig (Schritt 1 z.B. PDF in pdf). Erst im zweiten schritt wollte ich auch diesen „Müll“ bereinigen.
Gibt es eine Möglichkeit das „W-Doof“ das erst mal ignoriert (ohne so eine MSG-Box-Meldung) die ist nämlich die stört

Warum ich das bekomme ist mir schon klar, die Datei hat ein paar falsche Zeichen in ihren Namen. (Diese Zeichen hier darzustellen ist nicht möglich).
Code:
  SHFileOpStruct: TSHFileOpStruct;
begin
  Application.ProcessMessages;
  with SHFileOpStruct do
  begin
    Wnd              := Application.Handle;
    wFunc            := Func;
    fFlags           := Flags;
    pFrom            := PChar(_ExBackSlash(FromFile)+#0+#0);
    hNameMappings    := nil;
    lpszProgressTitle := nil;
http://www.sozialhilfe-pragmatik.org...ar/Msg-Box.jpg

mirage228 30. Nov 2007 11:15

Re: : Fehler beim Umbenennen der Datei
 
Du könntest bei den Flags das Flag "NO_ERRORUI" (oder Ähnlich) angeben, dann werden Fehlermeldungen unterdrückt.

mfG
mirage228

Opa 30. Nov 2007 11:31

Re: : Fehler beim Umbenennen der Datei
 
Das werde ich mal probieren, löst aber das Problem nicht ganz, Da der Müll so ein „Scheiß“ Unicode ist: Gibt es eine Möglichkeit in Delphi den direkt umzuwandeln in ANSI.

Das Flag heißt im übrigen : FOF_NOERRORUI

Mfg

SirThornberry 30. Nov 2007 14:30

Re: : Fehler beim Umbenennen der Datei
 
versuch mal einen einfachen Cast nach Unicode. Zudem erinnere ich mich das wir irgendwo hier schonmal die Lösung hatten. Leider weiß ich nicht wonach man da suchen könnte.

Könntest du das Bild aus dem ersten Beitrag bitte in den Anhang packen damit es auch noch verfügbar ist wenn du es von deinem Webspace gelöscht hast. Ansonsten würde das Bild dann irgendwann fehlen und ein wichtiger Teil des Beitrags wäre verloren.

Opa 30. Nov 2007 19:13

Re: : Fehler beim Umbenennen der Datei
 
Ich weiß mittlerweile warum ich das nicht umbennen kann
Aus diesen Zeichen werden Direkt im String ???-Zeichen gemacht, damit ist klar das dieser Name nicht zu ändern ist.
Möglicherweise kann man dieses mit WideCharToMultiByte umghen, da gibt es aber ein Problem:
Ich lese die Dateinamen so ein:
Code:
type
SR       : TSearchRec;
...
      if FindFirst(APfad+AMaske,AAttrDatei, SR) = 0 then
      begin
        repeat
          FilesAdd(DateiRecList,Directory,SR);
        until FindNext(SR) <> 0;
...
SR.Name hat dann schon die ???-Zeichen.
Meine Frage ist wie lese ich Datei-Namen unter Umgehung von SR.Name ein und dieses fortlaufend.
Wenn das geht den Datei-Namen evtl. sofort in „lesbare“ Zeichen umzuwandeln und ändern.
Kann ja sein das dazu einer einen Tipp hat.
Mfg

marabu 30. Nov 2007 19:22

Re: : Fehler beim Umbenennen der Datei
 
Hallo Opa,

damit Unicode-Dateinamen auch als solche in deinem Programm ankommen, musst du wohl auf die Unicode-Versionen der API Funktionen zurückgreifen: FindFirstFileW() und MoveFileW().

Grüße vom marabu

Opa 1. Dez 2007 01:21

Re: : Fehler beim Umbenennen der Datei
 
Liste der Anhänge anzeigen (Anzahl: 2)
Nach dem ich jetzt den ganzen Aufwand betrieben habe um den Dateinamen ggf. korrekt auszulesen kann ich die Datei immer noch nicht (Automatisch), Tolal-Comander und W-Doof selber kann das, umbennen.

Ich kann die nicht mal ohne Umbenennung auf meinen FTP Senden.
Die Datei ist (ist nur aus versehen bei mir gelandet) eine chinesische Anleitung für Delphi 7. :-D
"Mann" muss zwar wegen dieser einen Datei nicht den Aufwand betreiben, es dürfte aber nerven wenn man Seiten (PDF-Datein) aus China bekommt, das man diese erst mit der Hand ändern muss, wenn der Chinese was als Kommentar zusätzlich geschrieben hat.

http://www.sozialhilfe-pragmatik.org...g-Meldung2.jpg

http://www.sozialhilfe-pragmatik.org...-Commander.jpg

Die ???-Zeichen habe ich auch im Wide-Code – nur zum Einlesen des Dateinamen, hat sich das ändern des Prg. nicht gelohnt. :wall:

Als Unicode liest sich der Mist so:

http://www.sozialhilfe-pragmatik.org...ar/Unicode.jpg
Mfg

DP-Maintenance 1. Dez 2007 08:50

DP-Maintenance
 
Dieses Thema wurde von "Matze" von "Programmieren allgemein" nach "Windows API / MS.NET Framework API" verschoben.
Das schaut sehr nach einer Delphi-Frage aus. ;)

himitsu 1. Dez 2007 21:34

Re: : Fehler beim Umbenennen der Datei
 
Zitat:

Zitat von Opa
Nach dem ich jetzt den ganzen Aufwand betrieben habe um den Dateinamen ggf. korrekt auszulesen kann ich die Datei immer noch nicht (Automatisch)...

Die ???-Zeichen habe ich auch im Wide-Code – nur zum Einlesen des Dateinamen, hat sich das ändern des Prg. nicht gelohnt. :wall:

Als Unicode liest sich der Mist so:

ja und wie ließt du jetzt die Dateinamen ein, damit sowas rauskommt?
(wenn es richtig eingelesend wird, dann kommt sowas auch nicht raus)

Opa 2. Dez 2007 07:59

Re: : Fehler beim Umbenennen der Datei
 
Code:
type
  PDateiRec = ^TDateiRec;
  TDateiRec = packed record
    _DateiName : WideString;
    _FileName  : TFileName;
    _Erw0       : TFileName;
    _Erw1       : TFileName;
    _Pfad      : string;
    _Time      : TDateTime;
    _Attr      : integer;
    _Size      : int64;
    _CRC64Calc : int64;
  end;
const
  cUnicodeStr = ['?'];
  C_P        = '.';
  C_PP       = '..';
//------------------------------------------------------------------------------
function _StringToWideString(const S: AnsiString): WideString;
var
  X       : integer;
  CodePage : word;
begin
  CodePage := CP_ACP;
  if S = ''
  then Result := ''
  else begin
         X := MultiByteToWideChar(codePage, MB_PRECOMPOSED, PChar(@S[1]), - 1, nil, 0);
         SetLength(result, X - 1);
         if X > 1 then MultiByteToWideChar(CodePage, MB_PRECOMPOSED, PChar(@S[1]),- 1, PWideChar(@Result[1]), X - 1);
  end;
end;
//------------------------------------------------------------------------------
function _WideStringToString(const WS: WideString): AnsiString;
var
  X       : integer;
  CodePage : word;
begin
  CodePage := CP_ACP;
  {CP_ACP ANSI code page
  CP_MACCP Macintosh code page
  CP_OEMCP OEM code page}
  if WS = '' then result := ''
  else begin
         X := WideCharToMultiByte(codePage,WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,
         @WS[1], - 1, nil, 0, nil, nil);
         SetLength(result, X - 1);
         if X > 1 then WideCharToMultiByte(codePage,
         WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,@WS[1], - 1, @result[1], X - 1, nil, nil);
  end;
end; { WideStringToString }
//------------------------------------------------------------------------------
function _ReNameFile(const FromFile,ToFile:string;AHandle:THandle=0):boolean;
begin
  result := _ShellFileOperation(FromFile,ToFile,FO_RENAME,FOF_NOCONFIRMATION or FOF_SILENT);
  if not result and (AHandle <> 0) then SendMessage(AHandle,WM_SYSTEM_DATEI,longInt(@FromFile),14);
end;
//------------------------------------------------------------------------------
{Proceduren/Functionen-Anfang**************************************************}
{Damit können wir also die Dateien "windowsgemäß" löschen, die "fFlags" können folgendes
sein:
- FOF_ALLOWUNDO      = läßt ein Rückgängigmachen, falls möglich zu
- FOF_NOWCONFIRMATION = Löschen ohne Bestätigungsfrage
- FOF_SIMPLEPROGRESS = mit Fortschritts-Dialogbox, allerdings ohne die Dateinamen anzuzeigen
_ FOF_SILENT         = ohne Fortschritts-Dialogbox Mehrere Flags können mit OR kombiniert werden.}
//------------------------------------------------------------------------------
function _ShellFileOperation(const FromFile,ToFile: string; const Func,Flags: integer;AHandle:THandle=0):boolean;
var //uses Forms,ShellAPI
  SHFileOpStruct: TSHFileOpStruct;
begin
  Application.ProcessMessages;
  with SHFileOpStruct do
  begin
    Wnd              := Application.Handle;
    wFunc            := Func;
    fFlags           := Flags;// or FOF_NOERRORUI; //keine Fehlermeldung
    pFrom            := PChar(_ExBackSlash(FromFile)+#0+#0);
    hNameMappings    := nil;
    lpszProgressTitle := nil;
    if ToFile = ''
    then pTo := nil
    else pTo := PChar(ToFile+#0+#0);
//    if ToFile = pFrom then exit;
//    if pFrom ='' then exit;
  end;
  result := SHFileOperation(SHFileOpStruct) = 0;
  if not result then SendMessage(AHandle,WM_SYSTEM_DATEI,longInt(@FromFile),15);
  Application.ProcessMessages;
end;
//------------------------------------------------------------------------------
procedure TDrive.GetFiles(APfad,AMaske:string);
var
  SR       : TSearchRec;
  HFind    : THandle;
  Directory : string;
  SRW      : WIN32_FIND_DATAW;
  X :String;
begin
//  X := 'C:\Temp\Test\*.*';
  Directory:= ExtractFilePath(APfad);
  try
    HFind:=FindFirstFileW(PWideChar(_StringToWideString(APfad+AMaske)),SRW);
    if HFind<>INVALID_HANDLE_VALUE then
    begin
      repeat
        if SRW.dwFileAttributes and faDirectory <> faDirectory then FilesAdd(DateiRecList,Directory,SRW);
      until FindNextFileW(HFind,SRW) <> true;
    end;
  except
  end;

  if not AMitDir then exit;
  try
    try
      if FindFirst(Directory + '*.*',AAttrDir ,SR) = 0 then
      begin
        repeat
          if ((SR.Attr and faDirectory) = faDirectory) and ((SR.Name[1] <> C_P) and (SR.Name[1] <> C_PP)) then
          begin
            SendMessage(Handle,WM_READ_PFAD,0,DateiRecList.Count);
            GetFiles(Directory+_BackSlash(SR.Name)+ExtractFileName(APfad),AMaske);
          end;
        until FindNext(SR) <> 0;
      end;
    except
    end;
  finally
    SysUtils.FindClose(SR);
  end;
end;
//------------------------------------------------------------------------------
function _UniCodeErkennen(var Value: string;Ch :TChOfSet):boolean;
var
  I: integer;
begin
  Result := false;
  for I:=1 to length(Value) do
    if Value[I] in Ch then
    begin
      Value[I] := '_';
      Result := true;
    end;
end;
//------------------------------------------------------------------------------
procedure TDrive.ClearRec(P:pointer);
begin
  with PDateiRec(P)^ do
  begin
    _DateiName :=#0;
    _FileName  := '';
    _Erw0       := '';
    _Erw1       := '';
    _Pfad      := '';
    _Time      := 0;
    _Attr      := 0;
    _Size      := 0;
    _CRC64Calc := 0;
  end;
end;
//------------------------------------------------------------------------------
procedure TDrive.FilesAdd(TL:TList;Directory:string;SRW : WIN32_FIND_DATAW);
var//uses SysUtils,_Strings;
  P : pointer;
  FromFile : string;
  ToFile  : string;
begin
  with SRW do
  begin
    P := new(PDateiRec);
    with PDateiRec(P)^,SRW do
    begin          //_StringToWideString
      ClearRec(P);
      if dwFileAttributes and faDirectory <> faDirectory then _DateiName := cFileName;
      ToFile    := _WideStringToString(_DateiName);
      _Pfad     := Directory;
      if _UniCodeErkennen(ToFile,cUnicodeStr) then
      begin
        {$I+}
//          Dispose(P);
        {$I-}
//        exit; //Noch keine Lösung für das Problem
        FromFile := _Pfad+_WideStringToString(_DateiName);
        ToFile  := _Pfad+ToFile;
        _ReNameFile(FromFile,ToFile)
      end;
      _FileName := _WideStringToString(_DateiName);
      _Erw0     := _ExtractFileExtOhnePunkt(_FileName);
      _Erw1     := ExtractFileExt(_FileName);
      _FileName := ChangeFileExt(_FileName,'');
      _Pfad    := Directory;
      _Time    := _FileTimeToDateTime(ftCreationTime);//TFileTime
      _Attr    := dwFileAttributes;
      _Size    := nFileSizeHigh shl 32 or nFileSizeLow;
    end;
  end;
  TL.Add(P);
end;
So da haste fast alles (könnte was übersehen haben den ganzen Code-Teil). Da ich bis jetzt noch keine Lösung habe (Du weißt sie vermutlich auch nicht) und da es sich z.Z. nur um eine Datei handelt, ignoriere ich das.

Es ärgert mich allerdings sehr, weil es NICHT RICHTIG IST was zu ignorieren. Bin für jeden Vorschlag dankbar aber ich denke das ich hier (verständlich ist nicht häufig der Fehler), keine Lösung finden werde. Das Problem für mich ist das ich leider kein Englisch/Russisch kann, dann hätte ich vermutlich schon eine Lösung.

Nur als Hintergrund wissen: Soll ein Privates Programm werden das (ich habe viele Hefte und Bücher als PDF) und ich möchte sie, nach meinem Schema verwalten. Und weil jeder seien eigen „Müll“ in die Dateinamen schreibt, ich den nicht will und ich ein bisschen Proggen kann, will ich mir das Problem weitergehend automatisch vom Halse schaffen. (Gut in der Zeit könnte ich die Dateinamen auch mit der Hand ändern. Macht aber nicht soviel Spaß. Und doppelte Dateien zu finden ist auch nicht so einfach (per hand), nicht wenn man mehr als 5.000 Bücher auf den Rechner hat. Ich habe die meisten davon schon gelesen (sogar gekauft) aber das ist eine andere Geschichte,...

Zufrieden? Alle Fragen geklärt?

Mfg


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:21 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