Sign in to follow this  
Followers 0
ssubirias3

Shell Obj - CopyHere Method help please!

6 posts in this topic

Hi guys, here's the short story. Moving large amounts or sized files, an autoit script can leave people wondering if the script is dead or still working. I found that unlike InetGet() that offers a background parameter, other functions like DirCopy, FileCopy, etc do not offer this parameter. Searching the forum I found a couple of good reads including ezzetabi's _CopyDirWithProgress UDF and also Jos' short and sweet _FileCopy UDF. I elected to try Jos' UDF since that's exactly what i was looking for, the animated dialog box Windows uses.

Since Jos' UDF needs the destination folder to exist or nothing happens (including no error reporting), I modified the UDF for my needs. This is after reading Microsoft's articles on the topic, KB151799 and CopyHere Method.

Func _FileCopy($pFrom,$pTo)
    Local $FOF_NOCONFIRMMKDIR = 512
    Local $FOF_NOCONFIRMATION = 16
    MsgBox(0,"",$pTo)   ;; <--- Debug correct destination path
    If Not FileExists($pTo) Then DirCreate($pTo)  ;; <--- Create destination folder if needed
    $winShell = ObjCreate("shell.application")
    $winShell.namespace($pTo).CopyHere($pFrom, $FOF_NOCONFIRMATION)
EndFunc

My immediate problem is that if $pFrom = D:\ (DVD Drive) and $pTo = C:\MyNEWFolder, the function prompts me to create "C:\MyNEWFolder\DVD Drive (D:)" since that folder doesn't exist. HuH?? WHAT???

Yeah I don't want the function or my script to (i) offer creating such crazy folders nor (ii) create said crazy folder. And isn't it odd that had I not used DirCreate() to make the missing folder, this function would have ended without reporting an error (per Microsoft; bottom of CopyHere Method page). So how do I modify the _FileCopy() UDF so that it doesn't want to create the extra folder. Also, does anyone know why $FOF_NOCONFIRMMKDIR not work as it seems it should. If it did, I wouldn't need the DirCreate() line and I wouldn't be prompted to create the crazy DVD Drive (D:) folder.

Thanks in advance!

Share this post


Link to post
Share on other sites



Try something like:

$file = FileOpenDialog("Test", ".", "All (*.*)")


_FileCopy($file, "c:\test")

Func _FileCopy($pFrom,$pTo)
    Local $FOF_NOCONFIRMMKDIR = 512
    Local $FOF_NOCONFIRMATION = 16
    MsgBox(0,"",$pTo)   ;; <--- Debug correct destination path
    If Not FileExists($pTo) Then DirCreate($pTo)  ;; <--- Create destination folder if needed
    $winShell = ObjCreate("shell.application")
    $winShell.namespace($pTo).CopyHere($pFrom, BitOR($FOF_NOCONFIRMATION, $FOF_NOCONFIRMMKDIR))
EndFunc

Be careful when not showing confirmation, use at your own risk.


SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites

This is just a weird windows behavior. When you copy DVD Drives, windows likes to create folders with the name of the DVD drive as well as its drive letter. In your case it was "DVD Drive (D:)". This means the DVD in the drive didn't have a specified name. Some discs are named and their names appear next to the drive letter.

This just means you have to use the _FileCopy function differently:

_FileCopy("D:\*.*","C:\MyNEWFolder\")


Func _FileCopy($pFrom,$pTo)
    ;Forget the flags.  They don't appear to work at all
    Local $FOF_NOCONFIRMMKDIR = 512
    Local $FOF_NOCONFIRMATION = 16
    If FileExists($pTo) Then DirRemove($pTo,1);This removes the directory and all its file to prevent the annoying overwrite file confirmation message
    DirCreate($pTo)
    $winShell = ObjCreate("shell.application")
    $winShell.namespace($pTo).CopyHere($pFrom)
EndFunc

I also found that the flags don't work at all. I have no idea why, I tried over a dozen times to get the flags to work, but they don't appear to work at all. As a result, it still prompts you if you would like to overwrite files that already exist. To get rid of this annoyance, I simply have the function remove the entire directory that it is going to copy to prior to copying to it to make sure they are no files in there that are duplicates that will throw that annoying confirmation message.

Even Gary's example didn't work correctly for me because it still prompted whether or not to overwrite the files that already existed in the destination directory.

Not sure why this is happening, any ideas on why the flags don't appear to be working?

- The Kandie Man ;-)


"So man has sown the wind and reaped the world. Perhaps in the next few hours there will no remembrance of the past and no hope for the future that might have been." & _"All the works of man will be consumed in the great fire after which he was created." & _"And if there is a future for man, insensitive as he is, proud and defiant in his pursuit of power, let him resolve to live it lovingly, for he knows well how to do so." & _"Then he may say once more, 'Truly the light is sweet, and what a pleasant thing it is for the eyes to see the sun.'" - The Day the Earth Caught Fire

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

@Gary - Thanks and I appreciate your input and all you've done for AutoIt! The BitOr() logic makes perfect sense to me and is something I tried (exactly as you have it outlined) earlier this afternoon to no avail. I've PM Jos him asking some of these questions about the function and how to make better sense of it from my inexperienced perspective.

I did try your suggestion of using $file = FileOpenDialog("Test", "D:\", "All (*.*)"). This works as expected by opening up the FileOpenDialog. However it doesn't suit my needs since (i) its not unattended and (ii) it does not support CTRL+A or SHIFT+CLICK or select all. :)

@Kandie Man - I've been playing with this longer than I should, but I'm doing so in the name of education :). I think you're right about the flags not working, but I wouldn't say they don't work completely. In the CopyHere Method article I linked to previously, it says you can use the Int value without the flags. When I used $winShell.namespace($pTo).CopyHere($pFrom, 4) the dialog box was surpressed as option 4 intends. I like your workaround of DirRemove() followed by DirCreate(), nice! But there's a different problem keeping us from testing your idea. Here are some further background that i didn't provide previously that may help us land on a better understanding on this "feature".

In the original thread where I found the _FileCopy() UDF, it was asked if this would work like DirCopy(). Jos' response was yes if you use [drive:\][Folder\]*.* In my testing I've found this does not work. Likewise using the same CDRom that doesn't have a name (good catch Kandie Man!), and where $pFrom = D:\setup.exe and $pTo = C:\Test\123 ... my modified _FileCopy() worked WITHOUT asking if I wanted to create C:\Test\123\DVD Drive (D:\). Now how odd is that?? It seems that the _FileCopy() UDF only offers that prompt if $pFrom = D:\. And are you ready for this??? After you say yes to that stupid prompt of creating the extra crazy directory... the damn thing works beautifully! It actually copies the entire CD from $pFrom to $pTo\DVD Drive (D:\).

So before we go chasing too many wild geese, remember the UDF works 98% as I want it to. I want to know how to modify it so that it doesn't

... (i) offer creating such crazy folders nor (ii) create said crazy folder. And isn't it odd that had I not used DirCreate() to make the missing folder...

I appreciate the good ideas and better conversation! Edited by ssubirias3

Share this post


Link to post
Share on other sites

Update: Ok I think I've got it figured out after more testing and Gary's and Kandie Man's posts; thanks again guys!! This is what I've come to understand and accept for the moment. For anyone lacking a "programmer/developers" background, its not very clear what or how the flags are to be used exactly. Buy using BitOr() and the two flags, I was able to bypass the prompt to create the crazy directory. Further evidence the flags do in fact work.

Earlier when I was using BitOR($FOF_NOCONFIRMMKDIR,$FOF_NOCONFIRMATION)) I was under the impression that if $pTo did not exist that the function would create it. In reality the $FOF_NOCONFIRMMKDIR isnt' about the $pTo directory but the "crazy directory." Kandie Man suspected this was happening because my CD did not have a name. But that's not exactly true since my test CD has a Vol Label per dir at the cmd line. In Explorer the CD Vol Lable doesn't show up. Hmmmm.. what's up with that??

Now I'll need to modify my script to account for this extra directory the CD contents are copied to. Also note that this only occurs if you try to copy the contents of a root drive as in D:\. If its not the Volume Lable, what is this that's being created as the "extra crazy directory"???

So the working function that does what I want is as follows:

;===============================================================================
;
; Function Name:    _FileCopy()
; Description:      Copies Files and/or Folders with optional animated Windows dialog box
; Parameter(s):     $pFrom - Source files/folders to copy from
;                           $pTo - Destination folder to copy to
;                           $fFlags - [optional] Defines the flag for CopyHere action
;
; Option Flags:        $FOF_DEFAULT = 0          Default. No options specified.  
;                       $FOF_SILENT = 4              Do not display a progress dialog box.  
;                       $FOF_RENAMEONCOLLISION = 8 Rename the target file if a file exists at the target location with the same name.  
;                       $FOF_NOCONFIRMATION = 16    Click "Yes to All" in any dialog box displayed.  
;                       $FOF_ALLOWUNDO = 64          Preserve undo information, if possible.  
;                       $FOF_FILESONLY = 128          Perform the operation only if a wildcard file name (*.*) is specified.  
;                       $FOF_SIMPLEPROGRESS = 256   Display a progress dialog box but do not show the file names.  
;                       $FOF_NOCONFIRMMKDIR = 512   Do not confirm the creation of a new directory if the operation requires one to be created.  
;                       $FOF_NOERRORUI = 1024          Do not display a user interface if an error occurs.  
;                       $FOF_NORECURSION = 4096     Disable recursion.  
;                       $FOF_SELECTFILES = 9182 Do not copy connected files as a group. Only copy the specified files.  
;
; Requirement(s):   None.
; Return Value(s):  No return values per MSDN article.
; Author(s):        Jos, commented & modified by ssubirias3 to create $pTo if not present
; Note(s):          Must declare $fFlag variables or use their numeric equivalents without declaration. Use BitOR() to combine
;                       Flags. See http://support.microsoft.com/kb/151799 & 
;                       http://msdn2.microsoft.com/en-us/library/ms723207.aspx for more details
;
;===============================================================================
;; Example to copy contents of CD on D: to C:\Temp
_FileCopy("D:\", "C:\Temp")

;; Example to copy files and folders of C:\Windows\System32 to C:\Temp without a dialog box
_FileCopy("C:\Windows\System32","C:\Temp", 4)

Func _FileCopy($pFrom, $pTo, $fFlags = 0) 
    Local $FOF_NOCONFIRMMKDIR = 512
    Local $FOF_NOCONFIRMATION = 16
    If Not FileExists($pTo) Then DirCreate($pTo)
    $winShell = ObjCreate("shell.application")
    $winShell.namespace($pTo).CopyHere($pFrom, BitOR($FOF_NOCONFIRMMKDIR,$FOF_NOCONFIRMATION))  ;; or BitOR(16,512)) without declaration
EndFunc

Hopefully this post and my comments for the UDF makes it less confusing for others who are interested in this UDF. If nothing else I've certainly learned a few things working on this small piece of my current project. Enjoy!

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

can you tell me, how to check,

1) if copyprogress was sucessfull ?

2) if someone uses the cancel button to cancel the copyprogress ?

Edited by memnon

das beste Windows Support Forum: Windows 2000 Helpline und tschüss den WindowsfehlernProgrammieren: Autoit 3 - wer braucht noch VBS ?!Programmieren: Autoit 3 Forum?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0