Page 2 of 4

Re: CopyFileEx API call

Posted: Sun Nov 17, 2019 6:48 pm
by gonpublic2k
Excellent! That worked as expected. Much appreciated

Re: CopyFileEx API call

Posted: Sun Nov 17, 2019 7:09 pm
by infratec
I optimized it a bit and structured it a bit better.

Re: CopyFileEx API call

Posted: Sun Nov 17, 2019 7:14 pm
by gonpublic2k
infratec wrote:Programming is not copy and paste :wink:

Code: Select all

EnableExplicit

;======================================================================
;   ShareCopy.PB -  A Muli-Function Copy Tool that uses: Shell32.dll
;                   I found a subroutine on VB web-site -  author unknown
;                   modified for PureBasic -  Public Domain
;                   Bob Houle - updated Nov 02/02    [url]mailto:blueb@shaw.ca[/url]
;======================================================================
#Window1 = 1
#Btn_Copy = 1
#Btn_Move = 2
#Btn_Rename = 3
#Btn_Delete = 4
#Btn_Quit = 5
#W1String1 = 6
#W1String2 = 7
#W1Check1 = 8
#W1Check2 = 9
#W1Check3 = 10
#W1Check4 = 11
#W1Check5 = 12
#W1Text1 = 13
#W1Text2 = 14

#Window1Flags = #PB_Window_MinimizeGadget | #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_ScreenCentered



Procedure.i Button_Click(Index.i)
  
  ;define variables
  Protected wFunc.u
  Protected lresult.l
  Protected fFlags.u
  Protected.i ChkDir, ChkFilesOnly, ChkRename, ChkSilent,ChkYesToAll
  Protected FromDirectory$, ToDirectory$
  Protected SHFileOp.SHFILEOPSTRUCT    ;Windows API Structure
  
  ;Get status of checkboxes
  ChkDir = GetGadgetState(#W1Check4)
  ChkFilesOnly = GetGadgetState(#W1Check5)
  ChkRename = GetGadgetState(#W1Check3)
  ChkSilent = GetGadgetState(#W1Check1)
  ChkYesToAll = GetGadgetState(#W1Check2)
  
  ;Get the edit box values
  FromDirectory$ = GetGadgetText(#W1String1)
  ToDirectory$ = GetGadgetText(#W1String2)
  
  ;Find out which button was pressed
  Select Index
    Case #Btn_Copy
      wFunc = #FO_COPY
    Case #Btn_Move
      wFunc = #FO_MOVE
    Case #Btn_Rename
      wFunc = #FO_RENAME
    Case #Btn_Delete
      ChkYesToAll = 0      ;No mattter what - confirm Deletes! Prevents OOPS!
      wFunc = #FO_DELETE
  EndSelect
  
  If ChkSilent
    fFlags | #FOF_SILENT
  EndIf
  If ChkYesToAll
    fFlags | #FOF_NOCONFIRMATION
  EndIf
  If ChkRename
    fFlags | #FOF_RENAMEONCOLLISION
  EndIf
  If ChkDir
    fFlags | #FOF_NOCONFIRMMKDIR
  EndIf
  If ChkFilesOnly
    fFlags | #FOF_FILESONLY
  EndIf
  
  ; NOTE:  If you add the #FOF_ALLOWUNDO Flag you can move
  ;        a file to the Recycle Bin instead of deleting it.
  
  SHFileOp\wFunc = wFunc
  SHFileOp\pFrom = @FromDirectory$
  SHFileOp\pTo = @ToDirectory$
  SHFileOp\fFlags = fFlags
  
  lresult = SHFileOperation_(SHFileOp)
  
  ;  If User hit Cancel button While operation is in progress,
  ;  the fAnyOperationsAborted parameter will be true
  ;  - see win32api.inc For Structure details.
  
  If lresult = 0 Or SHFileOp\fAnyOperationsAborted
    ProcedureReturn 0
  EndIf
  
  MessageRequester("Operation Has Completed", "PureBasic Rules!", 0)
  
  ProcedureReturn lresult
  
EndProcedure



Define.i Event

If OpenWindow(#Window1, 0, 0, 500, 230, "Window-Like File Operations", #Window1Flags)
  
  ButtonGadget(#Btn_Copy,7,200 ,89,25,"Copy")
  ButtonGadget(#Btn_Move,105,200 ,89,25,"Move")
  ButtonGadget(#Btn_Rename,205,200 ,89,25,"Rename")
  ButtonGadget(#Btn_Delete,305,200 ,89,25,"Delete")
  ButtonGadget(#Btn_Quit,405,200 ,89,25,"Quit", 1)
  StringGadget(#W1String1,220,8,250,21,"")
  StringGadget(#W1String2,220,30 ,250,21,"")
  CheckBoxGadget(#W1Check1,90,80 ,391,17,"Don't display a progress dialog box")
  CheckBoxGadget(#W1Check2,90,100 ,403,17,"Respond with 'Yes to all' for any dialog box that is displayed")
  CheckBoxGadget(#W1Check3,90,120 ,404,17,"Rename the file (eg:'Copy #1 of...') if the target name already exists")
  CheckBoxGadget(#W1Check4,90,140 ,384,17,"Do not confirm the creation of a new directory if the operation requires it")
  CheckBoxGadget(#W1Check5,90,160 ,398,17,"Perform the operation only on files if a wildcard filename (*.*) is specified")
  TextGadget(#W1Text1,50,12 ,161,17,"Source File or Folder", #PB_Text_Right)
  TextGadget(#W1Text2,50,35,161,17,"Destination File or Folder", #PB_Text_Right)
  
  Repeat
    Event = WaitWindowEvent()
    
    Select Event
        
      Case #PB_Event_Gadget
        
        Select EventGadget()
          Case #Btn_Copy
            Button_Click(#Btn_Copy)
          Case #Btn_Move
            Button_Click(#Btn_Move)
          Case #Btn_Rename
            Button_Click(#Btn_Rename)
          Case #Btn_Delete
            Button_Click(#Btn_Delete)
          Case #Btn_Quit
            Event = #PB_Event_CloseWindow
        EndSelect
        
    EndSelect
    
  Until Event = #PB_Event_CloseWindow
  
EndIf
It compiles now and is starting, but I have not tested it.

But I think it is really outdated.
So it would be better if you tell us what you want to do, or to have
What I want to have is something that copy files as fast as ROBOCOPY but to display some sort of
progress so tha the user is aware what's going on. At the end a log file of the files that were copied
and all the operations that were performed. Should be a graphical window with the option to specify
a source and destination and perhaps what folders or files to exclude if given the names. Basically,
I want something like I said as fast as ROBOCOPY but with a graphical interface and display a progress
bar or percentage of files and directories copied and a log at the end. That's all. I just don't know how
to accomplish that in PB.

Thank you!!

Re: CopyFileEx API call

Posted: Sun Nov 17, 2019 11:10 pm
by infratec
Hmm...

then use robocopy or rsync in background (hidden with RunProgram()) and catch the output.

Re: CopyFileEx API call

Posted: Sun Nov 17, 2019 11:45 pm
by gonpublic2k
infratec wrote:Hmm...

then use robocopy or rsync in background (hidden with RunProgram()) and catch the output.
Yes, I'd like to do that the problem is I don't find any examples to get me started. :)

Re: CopyFileEx API call

Posted: Mon Nov 18, 2019 8:05 am
by infratec
This forum, like any other, has a search function.
If you search for robocopy, you will find something...

viewtopic.php?f=13&t=50611&hilit=robocopy

Re: CopyFileEx API call

Posted: Mon Nov 18, 2019 8:47 am
by gonpublic2k
infratec wrote:This forum, like any other, has a search function.
If you search for robocopy, you will find something...

viewtopic.php?f=13&t=50611&hilit=robocopy
Thank you, unfortunately this code doesn't work. After I input the source and destination the program just quits without any
information. Also, I don't want a console interface, I want a GUI to enter the source and destination paths. Even if robocopy
runs in the background in console mode, I need a way to tell the user something is going on, so a graphical of some sort (progressbar or else) is definetely a plus. Finally, a log of the results to be displayed in a window.

Re: CopyFileEx API call

Posted: Mon Nov 18, 2019 5:45 pm
by blueb
Hi gonpublic2k,

First... WOW! Was that a long time ago, but I have no problem using my Muli-Function Copy Tool on 5.71 (x86) or (x64)

I'm also not sure how robust 'SHFileOperation' is compared to RoboCopy.exe

Having said that... from what I can gather even RoboCopy cannot copy files that are locked open (or in use)



For this I'd suggest: GSCopyPro Version 8.1 https://www.gurusquad.com/GSCOPYPRO

GSCopyPro comes with an 'open file agent' which can copy files that are locked/ opened by other processes.

This point is crucial when copying server files... there is 'always' an open file somewhere in the system. {grin}

Here's their basic help PDF: https://www.gurusquad.com/GSCOPYPro_v81_Admin_Guide.pdf

PS - The 'Enterprise version' has even more options.
• Operates real-time.
• Provides byte-level file replication to save on bandwidth and file copy time.
• Uses compressed data during transmission, making transfers much more efficient and robust.
• Provides WebDAV support.
• Provides the option to replicate data across the internet with data being highly encrypted during
transmission.

Ya kind'a get what you pay for when it comes to backing up servers.

Re: CopyFileEx API call

Posted: Mon Nov 18, 2019 6:44 pm
by gonpublic2k
blueb wrote:Hi gonpublic2k,

First... WOW! Was that a long time ago, but I have no problem using my Muli-Function Copy Tool on 5.71 (x86) or (x64)

I'm also not sure how robust 'SHFileOperation' is compared to RoboCopy.exe

Having said that... from what I can gather even RoboCopy cannot copy files that are locked open (or in use)



For this I'd suggest: GSCopyPro Version 8.1 https://www.gurusquad.com/GSCOPYPRO

GSCopyPro comes with an 'open file agent' which can copy files that are locked/ opened by other processes.

This point is crucial when copying server files... there is 'always' an open file somewhere in the system. {grin}

Here's their basic help PDF: https://www.gurusquad.com/GSCOPYPro_v81_Admin_Guide.pdf

PS - The 'Enterprise version' has even more options.
• Operates real-time.
• Provides byte-level file replication to save on bandwidth and file copy time.
• Uses compressed data during transmission, making transfers much more efficient and robust.
• Provides WebDAV support.
• Provides the option to replicate data across the internet with data being highly encrypted during
transmission.

Ya kind'a get what you pay for when it comes to backing up servers.
Hi BlueB ,

Thanks for the reply. Well, reading on the ROBOCOPY information, you can actually copy files in backup mode which takes care of the issue if a file
is locked. I want to write something in PB myself and not have to use any commercial solution, for that there are many out there, this is more of
a personal project that I want to complete in the process learn PB while I'm at it. If you think that 'SHFileOperation' can be as fast as ROBOCOPY
then I'm cool with that but I still need to modify it so that it creates an interface where the user can provide some options to exclude certain files
or folders if needed to. Having said that, I believe that your script will be more robust if it had those options included. I just don't know how to
add them. I'll keep exploring the forum and asking for help until I get that part resolved. I appreciate everyone's help so far, this is a great community.

:)

Re: CopyFileEx API call

Posted: Tue Nov 19, 2019 1:13 pm
by gonpublic2k
Hello all,

Going forward here's what I want to accomplish in my adventure of discovering the power of PureBasic. The following
illustrates at its best what I want to do, exactly what I had in mind - if there's a way to replicate something like this in
PureBasic then I'd be happy:

https://sourceforge.net/projects/robocoprobocopy/

Check out that project and let me know who wants to join me in this adventure!

:)

Thanks!!

Re: CopyFileEx API call

Posted: Tue Nov 19, 2019 1:48 pm
by infratec
Read the help about RunProgram() carefully.

Then you will also notice a flag called #PB_Program_Hide :wink:

It is possible with PB.
You have simply to do it.

Build your GUI, then start robocopy with the correct parameters in background and collect the output.
Both, stdout and stderr.
You have to do this in a thread to be able to update your GUI.

Re: CopyFileEx API call

Posted: Tue Nov 19, 2019 1:54 pm
by blueb
Hi gonpublic2k,

The fact that Microsoft has deprecated 'SHFileOperation' for 'IFileOperation'
leads me to favor RoboCopy... which has way more parameters (and option flags).

...you can actually copy files in backup mode which takes care of the issue if a file
is locked.
I'd be wary of that statement... look into this closely.

Another issue is long path names, I believe RoboCopy can handle this issue.

There are a lot of possibilities when you want to create your own programs with PureBasic...
- 'SHFileOperation' or 'IFileOperation'
-Xcopy
-RoboCopy
-RichCopy

And, using PureBasic as a front-end, you can always use proprietary 'command line tools' such
as GSCopyPro (and many others)... it just depends on how deep you want to go down the rabbit hole. :mrgreen:

Re: CopyFileEx API call

Posted: Tue Nov 19, 2019 2:02 pm
by Marc56us
It's great that you want do it yourself to learn rather than using a ready-made product.
So we're not going to do it for you, but give you the method.

A good point is to make a progressbar and to do it, you musk know how many files need to be treated
To make a progress bar, you make a first pass of copy simulation (parameter /L) which allows you to count all the programs that need to be added, modified or deleted.
Then, you run Robocopy in the background and for each displayed line (updated, added, del), you advance the progress bar.

I think Robocopy can copy open files using the Volume Shadows Copy system (I don't remember how it works anymore)
That being said, the principle of a file backup is to make it run off-connection (users) for users and otherwise we inform them that they must close their files at such time and that otherwise they will not be backed up.
For some files such as those in databases this is not a problem because the copy is made using replication system or use Dump file.

:wink:

Re: CopyFileEx API call

Posted: Tue Nov 19, 2019 2:27 pm
by gonpublic2k
Marc56us wrote:It's great that you want do it yourself to learn rather than using a ready-made product.
So we're not going to do it for you, but give you the method.

A good point is to make a progressbar and to do it, you musk know how many files need to be treated
To make a progress bar, you make a first pass of copy simulation (parameter /L) which allows you to count all the programs that need to be added, modified or deleted.
Then, you run Robocopy in the background and for each displayed line (updated, added, del), you advance the progress bar.

I think Robocopy can copy open files using the Volume Shadows Copy system (I don't remember how it works anymore)
That being said, the principle of a file backup is to make it run off-connection (users) for users and otherwise we inform them that they must close their files at such time and that otherwise they will not be backed up.
For some files such as those in databases this is not a problem because the copy is made using replication system or use Dump file.

:wink:
That's correct Marcus. Thank you all for your support and feedback. I'm not sure if the progressbar method of calculating what files are going to be copied and parsing that
information to ROBOCOPY is a efficient method of doing it. What about a job that you have no information of what folders, files or otherwise is going to be copied? I believe
that the program should take whatever parameters you throw at it and use robocopy in the background to perform the copy process and somehow capture the information
and display it using a progressbar or showing it on the screen as it copies it, or both. Getting that to work together is the major task that I have in front of me now, I'll have
to study a lot of code in order to get me started. Thank God there are plenty of examples and code snippets in this forum to help me get started and that I have the support
of people like yourselves. Thank you.

Re: CopyFileEx API call

Posted: Tue Nov 19, 2019 2:33 pm
by infratec
A progressbar needs always an end value.
If you don't have one, you end up with progressbars which are starting again at 0 :mrgreen: