Kopiowanie SHFileOperation() - tworzy folder, zamiast pliku

0

Witam.

Próbuje użyć znalezionej na forum funkcji do kopiowania pliku
Kod:

procedure TForm1.Button1Click(Sender: TObject);
var
  R : TSHFileOpStruct;
begin
with R do
 begin
   Wnd:=Handle;
   lpszProgressTitle := 'Skopiuj plik....';
   wFunc:=FO_COPY;
   R.pFrom := pchar('p:\a\baza.s3db');
   R.pTo :=   pchar('p:\a\baza2.s3db');
   fFlags:=FOF_NOCONFIRMMKDIR;
 end;
 SHFileOperation(R);   
end;  

Działa poprawnie.
Jednak gdy do ścieżek chce dodać zmienną zamiast skopiowanego pliku pojawia się folder (w tym przypadku o nazwie (baza2.s3db)). Dlaczego ?

procedure TForm1.Button1Click(Sender: TObject);
var
  R : TSHFileOpStruct;
  app_path: string;
begin
app_path := 'p:\a\';

with R do
 begin
   Wnd:=Handle;
   lpszProgressTitle := 'Skopiuj plik....';
   wFunc:=FO_COPY;
   R.pFrom := pchar(app_path+'baza.s3db');
   R.pTo :=   pchar('p:\a\baza2.s3db');
   fFlags:=FOF_NOCONFIRMMKDIR;
 end;
SHFileOperation(R);
end;      
3

Zobacz na poniższy przykład:

uses
  Windows, ShellAPI;

  function OwnCopyFile(const ASource, ADest: PAnsiChar): Boolean;
  var
    fosFile: TSHFileOpStructA;
  begin
    FillChar(fosFile, SizeOf(fosFile), #0);

    fosFile.wFunc  := FO_COPY;
    fosFile.pFrom  := ASource;
    fosFile.pTo    := ADest;
    fosFile.fFlags := FOF_SILENT;

    Result := (SHFileOperationA(fosFile) = 0) and (fosFile.fAnyOperationsAborted = False);
  end;

var
  pchrSource, pchrDest: PAnsiChar;
  boolResult: Boolean;
begin
  pchrSource := 'C:\Foo\File.txt'#0; // tu
  pchrDest   := 'C:\Bar\'#0;  // tu
  boolResult := OwnCopyFile(pchrSource, pchrDest);
  Write('Result: ', boolResult);
  ReadLn;
end.

Łańcuchy typu PAnsiChar czy PChar muszą być zakończone znakiem o kodzie 0, a Twoje rzutowanie tego nie zapewnia; Poza tym nie zerujesz pamięci struktury, jak się przyjęło robić w WinAPI, co może kiedyś się zemścić; No i kolejna sprawa to to, że pole pTo powinno dostać ścieżkę katalogu dla pliku docelowego, a nie nazwę pliku.

0

@furious programming dziękuję serdecznie za odpowiedź.

Jeśli chodzi o używanie WinAPI to przyznam że nie mam w ogóle obeznania co i jak powinno się robić, zainteresowałem się TSHFileOpStruct ponieważ "zwykłe" CopyFile zwracało błąd przy próbie kopiowania pliku bazy danych SQLite, który był aktualnie otwarty w programie (zwykłe kopiowanie w Windows'ie działało, więc pomyślałem że metoda z WinAPI też zadziała - i działa :)).

Napisałeś o tym że pTo powinno zawierać ścieżkę katalogu docelowego a nie nazwę pliku.
W poradniku z którego korzystałem (http://4programmers.net/Delphi/Artyku%C5%82y/Kopiowanie_plik%C3%B3w) w pTo znajduje się c:\Windows\Pulpit\system.zip stąd takie zastosowanie u mnie (przy okazji dołączyłem myśl aby zmienić nazwę pliku) - ten sposób "póki co" działa :)

Podsumowując - @furious programming dzięki Twojej wskazówce z zakończaniem łańcucha znakiem o kodzie 0 funkcja kopiująca zaczęła działać zgodnie z oczekiwaniem. Dziękuję.

1 użytkowników online, w tym zalogowanych: 0, gości: 1