Jump to content
Sign in to follow this  
Steven_Cleary

FOF constants for _filecopy

Recommended Posts

Hello,

I am trying to copy files from a directory, but I don't want any subdirectories/files.  I found a list of FOF constants in another post, but there wasn't any reference to the syntax for them (the format of the constant itself).

See below, in the original function I copied there is the FOF_* and the value expected (for example FOF_RESPOND_YES=16).  I need the complete list.

Is there a reference available for them/proper format?

;~ 4 Do not display a progress dialog box.

;~ 8 Give the file being operated on a new name in a move, copy, or rename operation if a file with the target name already exists.

;~ 16 Respond with "Yes to All" for any dialog box that is displayed.

;~ 64 Preserve undo information, if possible.

;~ 128 Perform the operation on files only if a wildcard file name (*.*) is specified.

;~ 256 Display a progress dialog box but do not show the file names.

;~ 512 Do not confirm the creation of a new directory if the operation requires one to be created.

;~ 1024 Do not display a user interface if an error occurs.

;~ 2048 Version 4.71. Do not copy the security attributes of the file.

;~ 4096 Only operate in the local directory. Don't operate recursively into subdirectories. (I need the FOF for this one, FOF_?_?=4096)

;~ 9182 Version 5.0. Do not copy connected files as a group. Only copy the specified files.

 

FileCopy("C:\Windows\temp\test3.tmp","C:\windows\temp\peter1.pjf")

 

Func _FileCopy($fromFile,$tofile)

Local $FOF_RESPOND_YES = 16

Local $FOF_SIMPLEPROGRESS = 256

$winShell = ObjCreate("shell.application")

$winShell.namespace($tofile).CopyHere($fromFile,$FOF_RESPOND_YES)

EndFunc

Share this post


Link to post
Share on other sites

Not exactly clear what you want to achieve.  What is the problem you are facing ?  Why do you need to go with object instead of using one of the multiple function that already exists ?

Share this post


Link to post
Share on other sites
2 hours ago, Steven_Cleary said:

Is there a reference available for them/proper format?

Yes. It's mentioned in the _WinAPI_ShellFileOperation page

The constants you are interested in are referenced in the include  APIShellExConstants.au3 :

Global Const $FOF_ALLOWUNDO = 0x0040
Global Const $FOF_CONFIRMMOUSE = 0x0002
Global Const $FOF_FILESONLY = 0x0080
Global Const $FOF_MULTIDESTFILES = 0x0001
Global Const $FOF_NOCONFIRMATION = 0x0010
Global Const $FOF_NOCONFIRMMKDIR = 0x0200
Global Const $FOF_NO_CONNECTED_ELEMENTS = 0x2000
Global Const $FOF_NOCOPYSECURITYATTRIBS = 0x0800
Global Const $FOF_NOERRORUI = 0x0400
Global Const $FOF_NORECURSEREPARSE = 0x8000
Global Const $FOF_NORECURSION = 0x1000
Global Const $FOF_RENAMEONCOLLISION = 0x0008
Global Const $FOF_SILENT = 0x0004
Global Const $FOF_SIMPLEPROGRESS = 0x0100
Global Const $FOF_WANTMAPPINGHANDLE = 0x0020
Global Const $FOF_WANTNUKEWARNING = 0x4000
Global Const $FOF_NO_UI = BitOR($FOF_NOCONFIRMATION, $FOF_NOCONFIRMMKDIR, $FOF_NOERRORUI, $FOF_SILENT)

 

Share this post


Link to post
Share on other sites

We deploy images via USB, when we build the USB's we use an autoit .exe to format the USB, copy winpe files onto it, then go out to a network share and grab the appropriate image (~50GB worth of ghost image files).  The directory structure for where the images are stored was originally only 1 level deep, so this was working fine.  We've since added subdirectories (different images) and the autoit .exe is now trying to grab the files we want plus all the subdirectory files we don't. 

Since I posted my question, I found a reference for shell32 that lists all the constants.  I have updated my script with the following, still no good...no matter what I do it continues to grab recursively.  From the suggestion above, I researched a bit more and tried substituting the total value of the options in decimal and hex (ie set $FOF_RESPOND_YES = 4496, and also $FOF_RESPOND_YES = 0x1190.  I believe windows does it's own check before the operation begins and it determines there isn't enough room on the destination because it knows the copy is recursive, so we get a popup that says there is insufficient space on the destination.  If we remove the subdirectory(s) it works fine:

I have these includes:

#include <GUIConstants.au3>
#include <GUIConstantsEx.au3>
#include <ComboConstants.au3>
#include <File.au3>
#include <APIShellExConstants.au3>

Func _FileCopy($fromFile,$tofile)
    ; msgbox(0,"test", $fromFile & "," & $tofile)
    Local $FOF_RESPOND_YES = 16 (i set this value to dec 4496 and hex 1190, but it still recursively copies)
    Local $FOF_FILESONLY = 128
    Local $FOF_SIMPLEPROGRESS = 256
    Local $FOF_NORECURSION = 4096
    $winShell = ObjCreate("shell.application")
    $winShell.namespace($tofile).CopyHere($fromFile,$FOF_RESPOND_YES)
EndFunc

We need a progress bar, non-recursive copy, as there are nearly 50GB worth of files to copy over.

I'm running a test now with FileCopy, it appears to work (it will take a couple of hours to run), but for obvious reasons this isn't a good option.

 

Share this post


Link to post
Share on other sites

I ended up finding this function during my searching for a solution.  I added the "$FOF_NORECURSION" argument, it is working correctly.  I appreciate the input/assistance.

Func _CopyWithProgress($sFrom, $sTo)
    Local $SHFILEOPSTRUCT, $pFrom, $pTo, $aDllRet, $nError = 0

    $SHFILEOPSTRUCT = DllStructCreate("hwnd hwnd;uint wFunc;ptr pFrom;ptr pTo;int fFlags;int fAnyOperationsAborted;ptr hNameMappings;ptr lpszProgressTitle")
    DllStructSetData($SHFILEOPSTRUCT, "hwnd", 0)
    DllStructSetData($SHFILEOPSTRUCT, "wFunc", $FO_COPY)

    $pFrom = DllStructCreate("char[" & StringLen($sFrom)+2 & "]")
    DllStructSetData($pFrom, 1, $sFrom)
    DllStructSetData($pFrom, 1, Chr(0), StringLen($sFrom)+2) ; second null at the end
    DllStructSetData($SHFILEOPSTRUCT, "pFrom", DllStructGetPtr($pFrom))

    $pTo = DllStructCreate("char[" & StringLen($sTo)+2 & "]")
    DllStructSetData($pTo, 1, $sTo)
    DllStructSetData($pTo, 1, Chr(0), StringLen($sTo)+2) ; second null at the end
    DllStructSetData($SHFILEOPSTRUCT, "pTo", DllStructGetPtr($pTo))

    DllStructSetData($SHFILEOPSTRUCT, "fFlags", BitOR($FOF_NOCONFIRMATION, $FOF_NOERRORUI, $FOF_NORECURSION))
    DllStructSetData($SHFILEOPSTRUCT, "fAnyOperationsAborted", 0)
    DllStructSetData($SHFILEOPSTRUCT, "hNameMappings", 0)
    DllStructSetData($SHFILEOPSTRUCT, "lpszProgressTitle", 0)

    $aDllRet = DllCall("shell32.dll", "int", "SHFileOperation", "ptr", DllStructGetPtr($SHFILEOPSTRUCT))
    If @error Or $aDllRet[0] <> 0 Then
        $aDllRet = DllCall("kernel32.dll", "long", "GetLastError")
        If Not @error Then $nError = $aDllRet[0]
    EndIf

    ; test if button Abort was pressed
    If DllStructGetData($SHFILEOPSTRUCT, "fAnyOperationsAborted") Then $nError = -1

    $pFrom = 0
    $pTo = 0
    $SHFILEOPSTRUCT = 0

    If $nError <> 0 Then
        SetError($nError)
        Return False
    EndIf
    Return True
EndFunc

Share this post


Link to post
Share on other sites

Here something simple (tested) :

Func _Dir_Copy_Progress_NonRecursive ($sSourceFolder, $sDestFolder)
Local $ipct, $iDestSize

    DirRemove ($sDestFolder, $DIR_REMOVE)
    DirCreate ($sDestFolder)
    Local $iSourceSize = DirGetSize($sSourceFolder,$DIR_NORECURSE)
    Local $pid = Run(@comspec & ' /c copy "' & $sSourceFolder & '\*.*" "' & $sDestFolder & '\*.*"', "", @SW_HIDE)
    ProgressOn("Copy in Progress", "Please Wait...")
    Do
        $iDestSize = DirGetSize($sDestFolder)
        $ipct = Int(($iDestSize / $iSourceSize) * 100)
        ProgressSet($ipct, $ipct & ' percent complete')
        Sleep(20)
    Until Not ProcessExists($pid)
    ProgressSet(100, "Completed !")
    Sleep (1000)
    ProgressOff()

EndFunc

 

Share this post


Link to post
Share on other sites

Update-

Fooled again!  What the function in my last post did was copy recursively until it ran out of space.  It didn't check for enough space and prevent the entire copy like the original function was doing...When I checked the USB after the copy finished, it had brought over all the desired files, as well as the subdirectory and its contents until it ran out of space on the USB.  I've been running this on a dedicated PC we had for this process that happens to be running Vista (that should give you an idea of how long we've been using it :)).  I'm going to try it on a windows 10 machine or a 2016 server to see if the behavior changes (just for my own sanity) as well as trying the above (thanks for putting that together).

Steve

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  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...