Page 1 of 1
Copy Directory
Posted: Thu Jul 06, 2023 10:59 am
by Marc Vanzegbroeck
Hi,
I use copyfile() to copy a single file.
Is there a function to copy a complete directory?
Thanks
Re: Copy Directory
Posted: Thu Jul 06, 2023 11:07 am
by Antonio Linares
Dear Marc,
AEval( Directory( "*.prg" ), { | aFile | CopyFile( aFile[ 1 ], "path\" + aFile[ 1 ] ) } )
Re: Copy Directory
Posted: Thu Jul 06, 2023 3:10 pm
by FiveWiDi
Marc Vanzegbroeck wrote:Hi,
I use copyfile() to copy a single file.
Is there a function to copy a complete directory?
Thanks
Code: Select all | Expand
/* *************************** */
#include "Directry.ch"
FUNCTION lCopyFolder( AMPAARRA, cFolderOrig, cFolderDest, lAllFolder )
/* Les carpetes es reben acabades en "\".
----------------------------------- */
Local lResposta := .T.
Local nContador := 0
Local aFiles := {}
Local cDummy1 := ""
Local cDummy2 := ""
//Traza( 1, "cFolderOrig=", cFolderOrig )
//Traza( 1, "cFolderDest=", cFolderDest )
//lMakeDirectorio( cFolderDest, .F., .T. )
/* Fitxers de la carpeta origen incloses les subcarpetes i els seus fitxers.
---------------------------------------------------------------------- */
aFiles := Directory( cFolderOrig + "*.*" , "D" )
For nContador := 1 To Len( aFiles )
//Traza( 1, cFolderOrig + aFiles[ nContador ][ F_NAME ] )
If aFiles[ nContador ][ F_ATTR ] = "D" // És un directori
//Traza( 1, "Directori." )
If lAllFolder
If .Not. ( aFiles[ nContador ][ F_NAME ] $ ".." )
//Traza( 1, aFiles[ nContador ][ F_NAME ] + "\" )
//Traza( 1, SubStr( aFiles[ nContador ][ F_NAME ] + "\", Len( cFolderOri ) + 1 ) )
//Traza( 1, cFolderDest + SubStr( aFiles[ nContador ][ F_NAME ] + "\", Len( cFolderOri ) + 1 ) )
// lMakeDirectorio( cFolderDest + aFiles[ nContador ][ F_NAME ] + "\", .F., .T. )
lResposta := lCopyFolder( AMPAARRA, ;
cFolderOrig + aFiles[ nContador ][ F_NAME ] + "\", ;
cFolderDest + aFiles[ nContador ][ F_NAME ] + "\", ;
lAllFolder )
Endif
EndIf
Else
cDummy1 := cFolderOrig + aFiles[ nContador ][ F_NAME ]
cDummy2 := cFolderDest + aFiles[ nContador ][ F_NAME ]
/*
Msgnowait( AMPAarra, ;
GetTrad("Esperi uns moments, copiant a " ) + FilePath( cDummy2, "\", 1 ) + " ...", ;
GetTrad("Copiant fitxer de: " ) + cDummy1 + CRLF + GetTrad("a: " ) + cDummy2 )
*/
Sysrefresh()
If .not. COPYFILE( (cDummy1), (cDummy2), .F. )
/*GenError( 2, GetTrad("Problemes al copiar DE " ) + (cDummy1) )
GenError( 2, GetTrad(" A " ) + (cDummy2) )
*/
lResposta := .F.
EndIf
EndIf
Endfor
Return lResposta
/* *************************** */
Re: Copy Directory
Posted: Thu Jul 06, 2023 5:05 pm
by nageswaragunupudi
Using Windows FileSystem Object, we can copy entire folder with one line of code:
Code: Select all | Expand
oFs:CopyFolder( cSourceFolder\*.*, cDestFolder, lOverWrite )
We need to make sure the destination folder exists and if not create it first.
This is a working example:
Code: Select all | Expand
function TestCopyFolder()
local cSrcFolder := "c:\fwh\bitmaps\"
local cDstFolder := "c:\myimages\fwh\"
local oFs, lCopied := .f.
oFs := FileSysObj()
if oFs:FolderExists( cDstFolder ) .or. ;
lMkFullPath( cDstFolder )
//
TRY
oFs:CopyFolder( cSrcFolder + "*.*", cDstFolder, .t. )
lCopied := .t.
CATCH
END
endif
? lCopied
return nil
Note: If you do not have FWH function FileSys() in your version of FWH, we can create filesystem object this way:
Re: Copy Directory
Posted: Thu Jul 06, 2023 5:45 pm
by Armando
Friends:
My five cents, Take a look at the RoboCopy() windows command
Regards
Re: Copy Directory
Posted: Thu Jul 06, 2023 5:53 pm
by nageswaragunupudi
Windows command RoboCopy is more powerful than XCopy.
We consider using WinExec( "robocopy .... " )
But to copy a file, we do not use WinExec( "copy file1 file2" ), though this is also can be used.
Same way instead of WinExec( "xcopy .. " ), we better use any functions provided by Windows, like oFs:CopyFolder
Re: Copy Directory
Posted: Thu Jul 06, 2023 8:50 pm
by Jimmy
hi,
the Windows Explorer Way to "copy" files are ShFileOperation() API
Code: Select all | Expand
HB_FUNC( SHFILE )
{
#ifndef _WIN64
HWND hWnd = ( HWND ) hb_parnl( 1 );
#else
HWND hWnd = ( HWND ) hb_parnll( 1 );
#endif
SHFILEOPSTRUCT sh;
memset( ( char * ) &sh, 0, sizeof( sh ) );
sh.hwnd = hWnd ;
sh.wFunc = ( UINT ) hb_parnl( 2 );
sh.pFrom = ( LPSTR ) hb_parc( 3 );
sh.pTo = ( LPSTR ) hb_parc( 4 );
sh.fFlags = ( FILEOP_FLAGS ) hb_parnl( 5 );
sh.hNameMappings = 0;
sh.lpszProgressTitle = NULL;
hb_retnl( SHFileOperation( &sh ) );
}
call it using this
Code: Select all | Expand
FUNCTION ShellFiles( hWnd, acFiles, acTarget, nFunc, fFlag )
LOCAL cTemp
LOCAL cx
LOCAL lRet := .T.
// SourceFiles, convert Array to String
DEFAULT acFiles TO CHR( 0 )
IF VALTYPE( acFiles ) == "A"
cTemp := ""
FOR cx := 1 TO LEN( acFiles )
cTemp += acFiles[ cx ] + CHR( 0 )
NEXT
acFiles := cTemp
ENDIF
acFiles += CHR( 0 )
// TargetFiles, convert Array to String
DEFAULT acTarget TO CHR( 0 )
IF VALTYPE( acTarget ) == "A"
cTemp := ""
FOR cx := 1 TO LEN( acTarget )
cTemp += acTarget[ cx ] + CHR( 0 )
NEXT
acTarget := cTemp
ENDIF
acTarget += CHR( 0 )
// call SHFileOperation
DO CASE
CASE nFunc = FO_COPY
lRet := SHFile( hWnd, FO_COPY, acFiles, acTarget, fFlag )
CASE nFunc = FO_MOVE
lRet := SHFile( hWnd, FO_MOVE, acFiles, acTarget, fFlag )
CASE nFunc = FO_DELETE
lRet := SHFile( hWnd, FO_DELETE, acFiles, acTarget, fFlag )
CASE nFunc = FO_RENAME
lRet := SHFile( hWnd, FO_RENAME, acFiles, acTarget, fFlag )
ENDCASE
RETURN lRet
to "prepare" Files use this
Code: Select all | Expand
FUNCTION DoSH3func( cAction, lConfirm, lPaperbin, acFiles, acTarget, nSourceSide )
LOCAL nFocus := nSourceSide
LOCAL iMax := LEN( acFiles )
LOCAL lRet := .F.
LOCAL nHWnd, nFunc, fFlag
fFlag := FOF_SIMPLEPROGRESS
DO CASE
CASE cAction = "COPY"
nFunc := FO_COPY
CASE cAction = "MOVE"
nFunc := FO_MOVE
CASE cAction = "DELETE"
nFunc := FO_DELETE
CASE cAction = "RENAME"
nFunc := FO_RENAME
CASE cAction = "ZIPFILE"
nFunc := 0
ENDCASE
IF iMax > 1
fFlag := nOr( fFlag, FOF_MULTIDESTFILES )
ENDIF
IF lPaperbin
fFlag := nOr( fFlag, FOF_ALLOWUNDO )
ENDIF
IF lConfirm
ELSE
// fFlag += FOF_NOCONFIRMATION + FOF_NOCONFIRMMKDIR + FOF_RENAMEONCOLLISION
fFlag := nOr( fFlag, FOF_NOCONFIRMATION, FOF_NOCONFIRMMKDIR )
ENDIF
// ===========================================================================
// Function ShellFile( hParentWnd, aFiles, aTarget, nFunc, nFlag )
//
// Purpose:
// Performs a copy, move, rename, or delete operation on a file system object.
// Parameters:
// aFiles is an Array of Source-Filenamestrings, or a single Filenamestring
// aTarget is an Array of Target-Filenamestrings, or a single Filenamestring
// nFunc determines the action on the files:
// FO_MOVE, FO_COPY, FO_DELETE, FO_RENAME
// fFlag Option Flag ( see the file SHELL32.CH )
//
// ===========================================================================
lRet := ShellFiles( nHWnd, acFiles, acTarget, nFunc, fFlag )
RETURN lRet
Re: Copy Directory
Posted: Thu Jul 06, 2023 9:39 pm
by nageswaragunupudi
Nice.
Can you please show an example usage of the function ShellFiles(...) to copy a folder like this?
c:\fwh\bitmaps\*.* (including sub-folders)
to
c:\myimages\fwh\ (create folders if they do not exist)
Re: Copy Directory
Posted: Fri Jul 07, 2023 3:04 am
by Jimmy
nageswaragunupudi wrote:Nice.
Can you please show an example usage of the function ShellFiles(...) to copy a folder like this?
c:\fwh\bitmaps\*.* (including sub-folders)
to
c:\myimages\fwh\ (create folders if they do not exist)
Folder default are copy recursive so it is simple
Code: Select all | Expand
Start_SHfunc( {"bitmaps",0,DATE(),TIME(),"D"}, "COPY", "c:\fwh\", "c:\myimages\fwh\", .F., .F. )
1.st Parameter is a Array with Elements from DIRECTORY()
here in Sample it is only Folder "bitmaps" in Array
Code: Select all | Expand
FUNCTION Start_SHfunc( aItem, cAction, cSourceDir, cTargetDir, lConfirm, lPaperbin )
LOCAL ii, iMax
LOCAL cFile, cAttr
LOCAL acFiles := {}
LOCAL acTarget := {}
LOCAL lRet := .F.
iMax := LEN( aItem )
FOR ii := 1 TO iMax
cFile := aItem[ ii ] [ F_NAME ]
cAttr := aItem[ ii ] [ F_ATTR ]
AADD( acFiles, cSourceDir + cFile )
IF cAction = "DELETE"
AADD( acTarget, "" + CHR( 0 ) )
ELSE
AADD( acTarget, cTargetDir + cFile )
ENDIF
NEXT
lRet := DoSH3func( cAction, lConfirm, lPaperbin, acFiles, acTarget )
RETURN lRet
as you see it build Array with "full-path" which depend on cSourceDir + cFile / cTargetDir + cFile
i use Result from "Everything" instead of DIRECTORY() so it can also be different SourceDir
p.s. as ShFileOperation can show Animation "open" full Detail
Re: Copy Directory
Posted: Fri Jul 07, 2023 3:08 am
by nageswaragunupudi
Thanks
I don't know "Everything", but I understand we need to get the names into an array by recursion.
Thanks again.
Btw, Harbour has a function DirectoryRecurse().
Re: Copy Directory
Posted: Fri Jul 07, 2023 8:57 am
by Marc Venken
Jimmy,
Is this now running for standard FWH or for your Software Tools ?
Re: Copy Directory
Posted: Fri Jul 07, 2023 5:56 pm
by Jimmy
hi Marc
Marc Venken wrote:Is this now running for standard FWH or for your Software Tools ?
HB_FUNC( SHFILE ) is general for harbour 32 / 64 Bit
Demo c:\fwh\samples\dlgfile.prg only are for 32 Bit
other *.PRG may different like
---
i have "split" *.PRG as i call it in different Situation e.g. "dragdrop"
this will get all "marked" Files in TGrid()