Recent

Author Topic: move folders to another drive  (Read 2369 times)

Ericktux

  • Sr. Member
  • ****
  • Posts: 345
move folders to another drive
« on: November 20, 2022, 05:30:49 pm »
hello brothers, i am looking for the simplest way to move folders to another drive, the "renamefile" function is simple and cross-platform, but it only moves folders in the same drive, for other drives it cannot move. opening as admin doesn't work either  :(

Code: Pascal  [Select][+][-]
  1. var
  2.   Form1: TForm1;
  3.   origen_1, destino_1 : string;  
  4.  
  5. ....
  6.  
  7. procedure TForm1.Button1Click(Sender: TObject);
  8. begin
  9.   origen_1:='D:\test\casa\';
  10.   destino_1:='C:\test\trabajo\casa\';
  11.   //destino_1:='F:\test\trabajo\casa\'; // doesn't work either
  12.  
  13.  if RenameFile(origen_1,destino_1) then
  14.   begin
  15.   ShowMessage('yes');
  16.   end
  17.      else
  18.      begin
  19.      ShowMessage('not');
  20.      end;
  21. end;  

PD: I am using win10x64 + lazarusx86
« Last Edit: November 20, 2022, 05:35:10 pm by Ericktux »

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: move folders to another drive
« Reply #1 on: November 20, 2022, 05:47:13 pm »
I'm afraid you'll have to copy and then delete...

Bart

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2010
  • Fifty shades of code.
    • Delphi & FreePascal
Re: move folders to another drive
« Reply #2 on: November 20, 2022, 07:01:21 pm »
PD: I am using win10x64 + lazarusx86
https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-movefile
This works very well for me on Windows for files or folders.
If you need an example exclusive for Windows I can write you one.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

PascalDragon

  • Hero Member
  • *****
  • Posts: 5448
  • Compiler Developer
Re: move folders to another drive
« Reply #3 on: November 20, 2022, 10:49:18 pm »
hello brothers, i am looking for the simplest way to move folders to another drive, the "renamefile" function is simple and cross-platform, but it only moves folders in the same drive, for other drives it cannot move. opening as admin doesn't work either  :(

You need to do a copy-and-delete. That's how it works on any operating system and that's what a function like WinAPI's MoveFile that was suggested by KodeZwerg does as well. So you can just as well develop it yourself (or there might already be cross platform functions for that) and then you'll be cross platform anyway.

Ericktux

  • Sr. Member
  • ****
  • Posts: 345
Re: move folders to another drive
« Reply #4 on: November 21, 2022, 03:37:47 am »
Hello friends, I just tried with movefile and it doesn't move to another unit either, not as admin either, could it be that Windows 10 works differently?

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   origen_1:='D:\test\casa';
  4.   destino_1:='C:\test\trabajo\casa';
  5.  
  6.  //if RenameFile(origen_1,destino_1) then
  7.  if moveFile(pchar(origen_1),pchar(destino_1)) then
  8.   ShowMessage('yes')
  9.      else
  10.      ShowMessage('not');
  11. end;    

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2010
  • Fifty shades of code.
    • Delphi & FreePascal
Re: move folders to another drive
« Reply #5 on: November 21, 2022, 04:30:33 am »
Hello friends, I just tried with movefile and it doesn't move to another unit either, not as admin either, could it be that Windows 10 works differently?
1. You do not need to run such as admin, only when source or destination is protected.
2. I show you my own implementation that worked for me.
3. Copy and Delete is as suggested the better way for x-Platform etc.
Code: Pascal  [Select][+][-]
  1. //https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-movefile
  2. function MoveFileW(lpExistingFileName, lpNewFileName: PWideChar): BOOL; stdcall; external 'Kernel32.dll' name 'MoveFileW';
  3.  
  4. procedure TForm1.Button1Click(Sender: TObject);
  5. var
  6.   Src, Dst: WideString;
  7. begin
  8.   Src := 'C:\Test\FileOrg.txt';
  9.   Dst := 'D:\Test\FileNew.txt';
  10.   if ForceDirectories(ExtractFilePath(Dst)) then
  11.     begin
  12.       if (not MoveFileW(PWideChar(Src), PWideChar(Dst))) then
  13.         ShowMessage(Src + ' -> ' + Dst + ' failed to move.');
  14.     end
  15.     else
  16.       ShowMessage(ExtractFilePath(Dst) + ' folder creation error.');
  17.  
Happy testing.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Ericktux

  • Sr. Member
  • ****
  • Posts: 345
Re: move folders to another drive
« Reply #6 on: November 21, 2022, 05:02:48 am »
thank you very much friend for your help, i just tried and it works with files but not with folders, still the same error, can't move folders to another drive  :(

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2010
  • Fifty shades of code.
    • Delphi & FreePascal
Re: move folders to another drive
« Reply #7 on: November 21, 2022, 06:24:20 am »
thank you very much friend for your help, i just tried and it works with files but not with folders, still the same error, can't move folders to another drive  :(
I am sorry, it was my fault, I didnt fully read the Microsoft remarks!
Quote
The one caveat is that the MoveFile function will fail on directory moves when the destination is on a different volume.
So here is a working Folder move, including sub-folder etc...
Code: Pascal  [Select][+][-]
  1. type
  2.   TSHFileOpStruct = record
  3.     Wnd: HWND;
  4.     wFunc: UINT;
  5.     pFrom: LPCWSTR;
  6.     pTo: LPCWSTR;
  7.     fFlags: FILEOP_FLAGS;
  8.     fAnyOperationsAborted: BOOL;
  9.     hNameMappings: Pointer;
  10.     lpszProgressTitle: LPCWSTR;
  11.   end;
  12.  
  13. const
  14.   FO_MOVE = $0001;
  15.   FOF_NOCONFIRMMKDIR = $0200;
  16.  
  17. function SHFileOperationW(const lpFileOp: TSHFileOpStruct): Integer; stdcall; external 'shell32.dll' name 'SHFileOperationW';
  18.  
  19. function MoveDir(SrcDir, DstDir: WideString): Boolean;
  20. var
  21.   FOS: TSHFileOpStruct;
  22. begin
  23.   ZeroMemory(@FOS, SizeOf(FOS));
  24.   FOS.Wnd := Application.Handle;
  25.   FOS.wFunc := FO_MOVE;
  26.   FOS.fFlags := FOF_NOCONFIRMMKDIR;
  27.   FOS.pFrom := PWideChar(IncludeTrailingPathDelimiter(SrcDir) + '*.*'#0);
  28.   FOS.pTo := PWideChar(DstDir + #0);
  29.   Result := (SHFileOperationW(FOS) = 0);
  30. end;
  31.  
  32. procedure TForm1.Button1Click(Sender: TObject);
  33. var
  34.   Src, Dst: WideString;
  35. begin
  36.   Src := 'C:\Test';
  37.   Dst := 'D:\Test';
  38.   if (not MoveDir(Src, Dst)) then
  39.     ShowMessage(Src + ' -> ' + Dst + ' failed to move.')
  40.     else
  41.     if (not RemoveDir(Src)) then
  42.       ShowMessage('Unable to remove ' + Src);
  43. end;
Happy testing. (and please do not use my above stuff by checking for true as result, only work with false checking like i showed!)
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

ASerge

  • Hero Member
  • *****
  • Posts: 2223
Re: move folders to another drive
« Reply #8 on: November 21, 2022, 04:05:04 pm »
Happy testing.
By the way, the RenameFile function internally uses the MoveFileW function in Windows.
So the problem is most likely either in the permissions, or in the absence of a directory, or in the existence of the resulting file.

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2010
  • Fifty shades of code.
    • Delphi & FreePascal
Re: move folders to another drive
« Reply #9 on: November 21, 2022, 04:59:59 pm »
Happy testing.
By the way, the RenameFile function internally uses the MoveFileW function in Windows.
So the problem is most likely either in the permissions, or in the absence of a directory, or in the existence of the resulting file.
Or in the remark from Microsoft what I have quoted above that MoveFile does not work when moving folders to other volumes.  O:-)
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Ericktux

  • Sr. Member
  • ****
  • Posts: 345
Re: move folders to another drive
« Reply #10 on: November 21, 2022, 05:50:53 pm »
hello friend now it works, but when i use it with files these files are created as folders...   %)
I see that there is no simple way  :(, no way I will continue trying, I think I have a similar code I will look for it

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2010
  • Fifty shades of code.
    • Delphi & FreePascal
Re: move folders to another drive
« Reply #11 on: November 21, 2022, 06:08:18 pm »
hello friend now it works, but when i use it with files these files are created as folders...   %)
I see that there is no simple way  :(, no way I will continue trying, I think I have a similar code I will look for it
You got a windows solution from me for files.
You got a windows solution from me for folders.

What you need more?
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: move folders to another drive
« Reply #12 on: November 21, 2022, 06:23:13 pm »
How difficult can it be to simply iterate the files in source, copy to dest, delete after succesfull copy (delete target if copy partially fails)?

And if that is too difficult, you can always use ShellExcute() to launch move.exe with appropriate paramters.

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2010
  • Fifty shades of code.
    • Delphi & FreePascal
Re: move folders to another drive
« Reply #13 on: November 21, 2022, 07:46:09 pm »
hello friend now it works, but when i use it with files these files are created as folders...   %)
I see that there is no simple way  :(, no way I will continue trying, I think I have a similar code I will look for it
If you have no idea how to solve, that works aslong you keep mechanism to my above examples.
Code: Pascal  [Select][+][-]
  1.   if FileExists(Src) then
  2.     begin
  3.       if ForceDirectories(ExtractFilePath(Dst)) then
  4.         begin
  5.           if (not MoveFileW(PWideChar(Src), PWideChar(Dst))) then
  6.             ShowMessage(Src + ' -> ' + Dst + ' failed to move.');
  7.         end
  8.         else
  9.           ShowMessage(ExtractFilePath(Dst) + ' folder creation error.');
  10.     end;
  11.   if DirectoryExists(Src) then
  12.     begin
  13.       if (not MoveDir(Src, Dst)) then
  14.           ShowMessage(Src + ' -> ' + Dst + ' failed to move.')
  15.           else
  16.           if (not RemoveDir(Src)) then
  17.             ShowMessage('Unable to remove ' + Src);
  18.     end;
« Last Edit: November 21, 2022, 07:50:41 pm by KodeZwerg »
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Ericktux

  • Sr. Member
  • ****
  • Posts: 345
Re: move folders to another drive
« Reply #14 on: November 22, 2022, 02:13:07 am »
hello friend now it works, but when i use it with files these files are created as folders...   %)
I see that there is no simple way  :(, no way I will continue trying, I think I have a similar code I will look for it
If you have no idea how to solve, that works aslong you keep mechanism to my above examples.
Code: Pascal  [Select][+][-]
  1.   if FileExists(Src) then
  2.     begin
  3.       if ForceDirectories(ExtractFilePath(Dst)) then
  4.         begin
  5.           if (not MoveFileW(PWideChar(Src), PWideChar(Dst))) then
  6.             ShowMessage(Src + ' -> ' + Dst + ' failed to move.');
  7.         end
  8.         else
  9.           ShowMessage(ExtractFilePath(Dst) + ' folder creation error.');
  10.     end;
  11.   if DirectoryExists(Src) then
  12.     begin
  13.       if (not MoveDir(Src, Dst)) then
  14.           ShowMessage(Src + ' -> ' + Dst + ' failed to move.')
  15.           else
  16.           if (not RemoveDir(Src)) then
  17.             ShowMessage('Unable to remove ' + Src);
  18.     end;

Thank you very much friend, now it works for files and folders  :), just one last question:
where can i put showmessage('successful operation')  :-\

 

TinyPortal © 2005-2018