Copy Directory

Copy Directory

Postby Marc Vanzegbroeck » Thu Jul 06, 2023 10:59 am

Hi,

I use copyfile() to copy a single file.
Is there a function to copy a complete directory?

Thanks
Regards,
Marc

FWH32+xHarbour | FWH64+Harbour | BCC | DBF | ADO+MySQL | ADO+MariaDB | ADO+SQLite
Marc Vanzegbroeck
 
Posts: 1159
Joined: Mon Oct 17, 2005 5:41 am
Location: Belgium

Re: Copy Directory

Postby Antonio Linares » Thu Jul 06, 2023 11:07 am

Dear Marc,

AEval( Directory( "*.prg" ), { | aFile | CopyFile( aFile[ 1 ], "path\" + aFile[ 1 ] ) } )
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42117
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Copy Directory

Postby FiveWiDi » Thu Jul 06, 2023 3:10 pm

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 view  RUN
/* *************************** */
#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
/* *************************** */
Un Saludo
Carlos G.

FiveWin 24.02 + Harbour 3.2.0dev (r2403071241), BCC 7.7 Windows 10
FiveWiDi
 
Posts: 1190
Joined: Mon Oct 10, 2005 2:38 pm

Re: Copy Directory

Postby nageswaragunupudi » Thu Jul 06, 2023 5:05 pm

Using Windows FileSystem Object, we can copy entire folder with one line of code:
Code: Select all  Expand view  RUN
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 view  RUN
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:
Code: Select all  Expand view  RUN
oFS   := CreateObject( "Scripting.FileSystemObject" )
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10646
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Copy Directory

Postby Armando » Thu Jul 06, 2023 5:45 pm

Friends:

My five cents, Take a look at the RoboCopy() windows command

Regards
SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
User avatar
Armando
 
Posts: 3229
Joined: Fri Oct 07, 2005 8:20 pm
Location: Toluca, México

Re: Copy Directory

Postby nageswaragunupudi » Thu Jul 06, 2023 5:53 pm

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
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10646
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Copy Directory

Postby Jimmy » Thu Jul 06, 2023 8:50 pm

hi,

the Windows Explorer Way to "copy" files are ShFileOperation() API
Code: Select all  Expand view  RUN
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 view  RUN
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 view  RUN
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
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1732
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: Copy Directory

Postby nageswaragunupudi » Thu Jul 06, 2023 9:39 pm

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)
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10646
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Copy Directory

Postby Jimmy » Fri Jul 07, 2023 3:04 am

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 view  RUN
  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 view  RUN
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
Image
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1732
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: Copy Directory

Postby nageswaragunupudi » Fri Jul 07, 2023 3:08 am

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().
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10646
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Copy Directory

Postby Marc Venken » Fri Jul 07, 2023 8:57 am

Jimmy,

Is this now running for standard FWH or for your Software Tools ?
Marc Venken
Using: FWH 23.04 with Harbour
User avatar
Marc Venken
 
Posts: 1437
Joined: Tue Jun 14, 2016 7:51 am
Location: Belgium

Re: Copy Directory

Postby Jimmy » Fri Jul 07, 2023 5:56 pm

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
Code: Select all  Expand view  RUN
 DEFAULT acFiles TO
 DEFAULT acFiles :=


---

i have "split" *.PRG as i call it in different Situation e.g. "dragdrop"
Code: Select all  Expand view  RUN
LOCAL aItem := ::oGrid:Getdata()

this will get all "marked" Files in TGrid()
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1732
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 86 guests