Funktionreferenz


_WinAPI_MoveFileEx


Moves a file or directory, notifying the application of its progress through a callback function

#include <WinAPIFiles.au3>
_WinAPI_MoveFileEx ( $sExistingFile, $sNewFile [, $iFlags = 0 [, $pProgressProc = 0 [, $pData = 0]]] )

Parameter

$sExistingFile The name of the existing file or directory on the local computer.

If $iFlags specifies $MOVE_FILE_DELAY_UNTIL_REBOOT, the file cannot exist on a remote share because delayed operations are performed before the network is available.
$sNewFile The new name of the file or directory on the local computer.

When moving a file, $sNewFile can be on a different file system or volume.
If $sNewFile is on another drive, you must set the $MOVE_FILE_COPY_ALLOWED flag in $iFlags parameter.

When moving a directory, $sExistingFile and $sNewFile must be on the same drive.

If $iFlags specifies $MOVE_FILE_DELAY_UNTIL_REBOOT the $sNewFile must be 0, _WinAPI_MoveFileEx() registers $sExistingFile to be deleted when the system restarts.
If $sExistingFile refers to a directory, the system removes the directory at restart only if the directory is empty.
$iFlags [optional] The move options. This parameter can be one or more of the following values:
    $MOVE_FILE_COPY_ALLOWED (0x0002) cannot be used with $MOVE_FILE_DELAY_UNTIL_REBOOT
    $MOVE_FILE_CREATE_HARDLINK (0x0010)
    $MOVE_FILE_DELAY_UNTIL_REBOOT (0x0004) cannot be use with $MOVE_FILE_COPY_ALLOWED
    $MOVE_FILE_FAIL_IF_NOT_TRACKABLE (0x0020)
    $MOVE_FILE_REPLACE_EXISTING (0x0001)
    $MOVE_FILE_WRITE_THROUGH (0x0008)
$pProgressProc [optional] The address of a callback function that is called each time another portion of the file has been moved.
(See MSDN for more information)
$pData [optional] Pointer to the argument to be passed to the callback function.

Rückgabewert

Success: True.
Failure: False, call _WinAPI_GetLastError() to get extended error information

Bemerkungen

$MOVE_* , $PROGRESS_* constants require #include <APIFilesConstants.au3>

If the $iFlags parameter specifies $MOVE_FILE_DELAY_UNTIL_REBOOT, _WinAPI_MoveFileEx() fails if it cannot access the registry (you can use #RequireAdmin).
The function stores the locations of the files to be renamed at restart in the following registry value:
    "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager", "PendingFileRenameOperations"

The callback function as reference by $pProgressProc should define a function as :
    Func _ProgressProc($iTotalFileSize, $iTotalBytesTransferred, $iStreamSize, $iStreamBytesTransferred, $iStreamNumber, $iCallbackReason, $hSourceFile, $hDestinationFile, $pData)
        ; ...
    EndFunc

Siehe auch

Suche nach MoveFileWithProgress in der MSDN Bibliothek.

Beispiel

Beispiel 1

#include <APIFilesConstants.au3>
#include <Misc.au3>
#include <WinAPIError.au3>
#include <WinAPIFiles.au3>

Opt('TrayAutoPause', 0)

Local $hProgressProc = DllCallbackRegister('_ProgressProc', 'bool', 'uint64;uint64;uint64;uint64;dword;dword;handle;handle;ptr')

FileDelete(@TempDir & '\Test*.tmp')

ProgressOn('_WinAPI_MoveFileEx()', 'Erstellung einer großen Datei...', '')
Local $sFile = @TempDir & '\Test.tmp'
Local $hFile = FileOpen($sFile, 2)
For $i = 1 To 1000000
    FileWriteLine($hFile, "                                                     ")
Next
FileClose($hFile)

ProgressOn('_WinAPI_MoveFileEx()', 'Verschieben...', '0%')
Sleep(500) ; Um anzuzeigen, dass sich die Änderung auf demselben Gerät befindet, ist die Datei einfach umzubenennen

If Not _WinAPI_MoveFileEx($sFile, @TempDir & '\Test1.tmp', $MOVE_FILE_COPY_ALLOWED, DllCallbackGetPtr($hProgressProc)) Then
    _WinAPI_ShowLastError('Fehler beim verschieben ' & $sFile)
EndIf

DllCallbackFree($hProgressProc)

ProgressOff()

FileDelete(@TempDir & '\Test*.tmp')

Func _ProgressProc($iTotalFileSize, $iTotalBytesTransferred, $iStreamSize, $iStreamBytesTransferred, $iStreamNumber, $iCallbackReason, $hSourceFile, $hDestinationFile, $pData)
    #forceref $iStreamSize, $iStreamBytesTransferred, $iStreamNumber, $iCallbackReason, $hSourceFile, $hDestinationFile, $pData

    Local $iPercent = Round($iTotalBytesTransferred / $iTotalFileSize * 100)
    If $iPercent = 100 Then
        ProgressSet($iPercent, $iPercent & "%", 'Fertig')
        Sleep(2000)
    Else
        ProgressSet($iPercent, $iPercent & "%")
    EndIf
    Sleep(100)

    If _IsPressed('1B') Then
        Return $PROGRESS_CANCEL
    Else
        Return $PROGRESS_CONTINUE
    EndIf
EndFunc   ;==>_ProgressProc

Example 2 Running in Admin Mode to use $MOVE_FILE_DELAY_UNTIL_REBOOT to delete the file

#RequireAdmin

#include <APIFilesConstants.au3>
#include <Misc.au3>
#include <WinAPIError.au3>
#include <WinAPIFiles.au3>

Opt('TrayAutoPause', 0)

Example()

Func Example()
    Local $hProgressProc = DllCallbackRegister('_ProgressProc', 'bool', 'uint64;uint64;uint64;uint64;dword;dword;handle;handle;ptr')

    FileDelete(@TempDir & '\Test*.tmp')

    ProgressOn('_WinAPI_MoveFileEx()', 'Bigfile Creation...', '')
    Local $sFile = @TempDir & '\Test.tmp'
    Local $hFile = FileOpen($sFile, 2)
    For $i = 1 To 1000000
        FileWriteLine($hFile, "                                                     ")
    Next
    FileClose($hFile)

    ProgressOn('_WinAPI_MoveFileEx()', 'Moving...', '0%')
    Sleep(500) ; to show the change as moving on same device just rename

;~  If Not _WinAPI_MoveFileEx($sFile, @TempDir & '\Test1.tmp', $MOVE_FILE_DELAY_UNTIL_REBOOT, DllCallbackGetPtr($hProgressProc)) Then ; does not rename !!!

    ; suppression of the file at the next reboot
    If Not _WinAPI_MoveFileEx($sFile, 0, $MOVE_FILE_DELAY_UNTIL_REBOOT, DllCallbackGetPtr($hProgressProc)) Then
        _WinAPI_ShowLastError('Error moving ' & $sFile)
        Exit
    EndIf

    DllCallbackFree($hProgressProc)

    ProgressOff()

    MsgBox(0, '_WinAPI_MoveFileEx()', $sFile & @CRLF & @CRLF & 'Will be deleted at the next reboot')

EndFunc   ;==>Example

Func _ProgressProc($iTotalFileSize, $iTotalBytesTransferred, $iStreamSize, $iStreamBytesTransferred, $iStreamNumber, $iCallbackReason, $hSourceFile, $hDestinationFile, $pData)
    #forceref $iStreamSize, $iStreamBytesTransferred, $iStreamNumber, $iCallbackReason, $hSourceFile, $hDestinationFile, $pData

    Local $iPercent = Round($iTotalBytesTransferred / $iTotalFileSize * 100)
    If $iPercent = 100 Then
        ProgressSet($iPercent, $iPercent & "%", 'Complete')
        Sleep(2000)
    Else
        ProgressSet($iPercent, $iPercent & "%")
    EndIf
    Sleep(100)

    If _IsPressed('1B') Then
        Return $PROGRESS_CANCEL
    Else
        Return $PROGRESS_CONTINUE
    EndIf
EndFunc   ;==>_ProgressProc