Sign in to follow this  
Followers 0
Belini

DirMove Why not mix one with another folder?

25 posts in this topic

Whenever I try to move a folder from one drive to another it enters inside the other if the name is equal, why not mix Dirmove folders if their name is the same?

Share this post


Link to post
Share on other sites



I think because internaly use MoveFile or MoveFileEx.

Share this post


Link to post
Share on other sites

I already use the FileMove to make it more would be even better if I could move and merge folders at once using the DirMove.

Share this post


Link to post
Share on other sites

I already use the FileMove to make it more would be even better if I could move and merge folders at once using the DirMove.

 

maybe try DirCopy with a flag of 1

DirCopy("C:\test1", "C:\test2", 1) 

be sure to create some mock directories with test files in them to be sure that it merges the files and doesnt just replace them before using on your important files.

:alien:


if @error Then
	MsgBox(262192,"",@ComputerName&" slaps "&@UserName&" around a bit with a large trout!")
	EndIf

>Exit code: 0

REAL search results

"Yeah yeah yeah, patience. How long will that take?"  -Ed Gruberman

Share this post


Link to post
Share on other sites

maybe try DirCopy with a flag of 1

DirCopy("C:\test1", "C:\test2", 1) 

be sure to create some mock directories with test files in them to be sure that it merges the files and doesnt just replace them before using on your important files.

:alien:

Just do a DirRemove after you've copied it and it will essentially have moved it.


Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Share this post


Link to post
Share on other sites

Just do a DirRemove after you've copied it and it will essentially have moved it.

make sure the directory actually got copied before removing it.

$sizebefore = DirGetSize("C:\test2")
Dirmove("C:\test1", "C:\test2", 1)
$sizeafter = DirGetSize("C:\test2")
if $sizeafter <> $sizebefore Then
    DirRemove("C:\test1")
Else
    MsgBox(0,"","Directory did not move")
    EndIf

:alien:


if @error Then
	MsgBox(262192,"",@ComputerName&" slaps "&@UserName&" around a bit with a large trout!")
	EndIf

>Exit code: 0

REAL search results

"Yeah yeah yeah, patience. How long will that take?"  -Ed Gruberman

Share this post


Link to post
Share on other sites

make sure the directory actually got copied before removing it.

$sizebefore = DirGetSize("C:\test2")
Dirmove("C:\test1", "C:\test2", 1)
$sizeafter = DirGetSize("C:\test2")
if $sizeafter <> $sizebefore Then
    DirRemove("C:\test1")
Else
    MsgBox(0,"","Directory did not move")
    EndIf

:alien:

Good idea ;)


Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Share this post


Link to post
Share on other sites

Works well if the folder name is different if the name is more equal and are in the same unit both folders are not merged

DirMove("C:\TEST 1", "C:\TEST 2", 1); Works perfectly why the folders have different name

DirMove("C:\New dir\TEST", "C:\TEST", 1); The moved folder is inside another instead of being merged

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

 

Works well if the folder name is different if the name is more equal and are in the same unit both folders are not merged

DirMove("C:\TEST 1", "C:\TEST 2", 1); Works perfectly why the folders have different name

DirMove("C:\New dir\TEST", "C:\TEST", 1); The moved folder is inside another instead of being merged

oops, sorry about that, i meant DirCopy, not DirMove.

the directories will merge, but if there are any files with the same name they will be overwritten.

also if the files in each directory just so happen to equal the size, the If...Else...Endif wont work.

:alien:

$sizebefore = DirGetSize("C:\Users\flip\Google Drive\work\Desktop\test")

DirCopy("C:\Users\flip\Google Drive\work\Desktop\icons\test", "C:\Users\flip\Google Drive\work\Desktop\test", 1)

$sizeafter = DirGetSize("C:\Users\flip\Google Drive\work\Desktop\test")

if $sizeafter <> $sizebefore Then
    DirRemove("C:\Users\flip\Google Drive\work\Desktop\icons\test",1)
Else
    MsgBox(0,"","Directory did not move")
    EndIf
Edited by alienclone

if @error Then
	MsgBox(262192,"",@ComputerName&" slaps "&@UserName&" around a bit with a large trout!")
	EndIf

>Exit code: 0

REAL search results

"Yeah yeah yeah, patience. How long will that take?"  -Ed Gruberman

Share this post


Link to post
Share on other sites

The way you showed works but for each file you will need a time to copy even if they have the same name and if you merge will replace without spending more time copying the file.

Share this post


Link to post
Share on other sites

The way you showed works but for each file you will need a time to copy even if they have the same name and if you merge will replace without spending more time copying the file.

 

it sounds like you are saying the computer needs time to finish copying the files before deleting them. if so then something like this should help.

:alien:

$sizebefore = DirGetSize("C:\Users\flip\Google Drive\work\Desktop\test")
$sizebefore2 = DirGetSize("C:\Users\flip\Google Drive\work\Desktop\icons\test")

$sizetotal=$sizebefore + $sizebefore2

DirCopy("C:\Users\flip\Google Drive\work\Desktop\icons\test", "C:\Users\flip\Google Drive\work\Desktop\test", 1)

Do
$sizeafter = DirGetSize("C:\Users\flip\Google Drive\work\Desktop\test")
Until $sizeafter = $sizetotal

DirRemove("C:\Users\flip\Google Drive\work\Desktop\icons\test",1)

if @error Then
	MsgBox(262192,"",@ComputerName&" slaps "&@UserName&" around a bit with a large trout!")
	EndIf

>Exit code: 0

REAL search results

"Yeah yeah yeah, patience. How long will that take?"  -Ed Gruberman

Share this post


Link to post
Share on other sites

maybe IFileOperation Interface solves your problem.

 

Saludos

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

@alienClone I can even move files, folders and subfolders using FileMove more thought I had a way to move and merge entire directory at once without using FileMove.

move_directory()

Func move_directory()
    Local $home_directory = "C:\Dir source"
    Local $source = $home_directory
    Local $target = "C:\Test"
    Local $flag = 9
    move_files($home_directory, $source, $target, $flag, 0)
    If DirGetSize($source) = 0 Then DirRemove(StringMid($source, 1, StringInStr($source, "\", 2, 2) - 1), 1)
EndFunc   ;==>move_directory

Func move_files($home_directory = "", $source = "", $target = "", $flag = "", $counter = 0)
    $counter = 0
    $source &= '\'
    Local $file, $demand = FileFindFirstFile($source & '*')
    If $demand = -1 Then Return ''
    While 1
        $file = FileFindNextFile($demand)
        If @error Then ExitLoop
        If @extended Then
            If $counter >= 10 Then ContinueLoop
            move_files($home_directory, $source & $file, $target, $flag, $counter + 1)
        Else
            $address_changes = StringReplace($source & $file, $home_directory, $target)
            FileMove($source & $file, $address_changes, $flag)
            ;MsgBox(4096, "Moving", $source & $file & @CRLF & $address_changes, 1)
        EndIf
    WEnd
    FileClose($demand)
EndFunc   ;==>move_files

@Danyfirex  Can you give an example of how to use IFileOperation Interface?

Edited by Belini

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

Look:

Global Const $FOF_ALLOWUNDO = 0x40
Global Const $FOF_CONFIRMMOUSE = 0x2
Global Const $FOF_FILESONLY = 0x80
Global Const $FOF_MULTIDESTFILES = 0x1
Global Const $FOF_NO_CONNECTED_ELEMENTS = 0x2000
Global Const $FOF_NOCONFIRMATION = 0x10
Global Const $FOF_NOCONFIRMMKDIR = 0x200
Global Const $FOF_NOCOPYSECURITYATTRIBS = 0x800
Global Const $FOF_NOERRORUI = 0x400
Global Const $FOF_NORECURSION = 0x1000
Global Const $FOF_RENAMEONCOLLISION = 0x8
Global Const $FOF_SILENT = 0x4
Global Const $FOF_SIMPLEPROGRESS = 0x100
Global Const $FOF_WANTMAPPINGHANDLE = 0x20
Global Const $FOF_WANTNUKEWARNING = 0x4000
Global Const $FOFX_SHOWELEVATIONPROMPT = 0x00040000
Global Const $FOFX_NOCOPYHOOKS = 0x00800000
Global Const $FOFX_REQUIREELEVATION = 0x10000000

Global Const  $IID_IShellItem = "{43826d1e-e718-42ee-bc55-a1e261c37bfe}"
Global Const  $CLSID_IFileOperation = "{3AD05575-8857-4850-9277-11B85BDB8E09}"
Global Const  $IID_IFileOperation = "{947AAB5F-0A5C-4C13-B4D6-4BF7836FC9F8}"

Global Const $sTagIFileOperation = "Advise hresult(ptr;dword*);" & _
        "Unadvise hresult(dword);" & _
        "SetOperationFlags hresult(dword);" & _
        "SetProgressMessage hresult(wstr);" & _
        "SetProgressDialog hresult(ptr);" & _
        "SetProperties hresult(ptr);" & _
        "SetOwnerWindow hresult(hwnd);" & _
        "ApplyPropertiesToItem hresult(ptr);" & _
        "ApplyPropertiesToItems hresult(ptr);" & _
        "RenameItem hresult(ptr;wstr;ptr);" & _
        "RenameItems hresult(ptr;wstr);" & _
        "MoveItem hresult(ptr;ptr;wstr;ptr);" & _
        "MoveItems hresult(ptr;ptr);" & _
        "CopyItem hresult(ptr;ptr;wstr;ptr);" & _
        "CopyItems hresult(ptr;ptr);" & _
        "DeleteItem hresult(ptr;ptr);" & _
        "DeleteItems hresult(ptr);" & _
        "NewItem hresult(ptr;dword;wstr;wstr;ptr);" & _
        "PerformOperations hresult();" & _
        "GetAnyOperationsAborted hresult(ptr*);"

Local $oIFileOperation = ObjCreateInterface($CLSID_IFileOperation, $IID_IFileOperation, $sTagIFileOperation)

If IsObj($oIFileOperation) Then ConsoleWrite("Interface: " & IsObj($oIFileOperation) & @CRLF)


Local $sSource = "here source"
Local $sDestination = "here destination"

Local $tIIDIShellItem = CLSIDFromString($IID_IShellItem)


Local $pIShellItemSource = 0
Local $pIShellItemDestination = 0


_SHCreateItemFromParsingName($sSource, 0, DllStructGetPtr($tIIDIShellItem), $pIShellItemSource)
_SHCreateItemFromParsingName($sDestination, 0, DllStructGetPtr($tIIDIShellItem), $pIShellItemDestination)

ConsoleWrite("Pointer 1: " & $pIShellItemSource & @CRLF)
ConsoleWrite("Pointer 2: " & $pIShellItemDestination & @CRLF)

$oIFileOperation.SetOperationFlags($FOF_ALLOWUNDO + $FOF_NOCONFIRMMKDIR)

$oIFileOperation.CopyItems($pIShellItemSource, $pIShellItemDestination)

$oIFileOperation.PerformOperations()

$oIFileOperation = 0




Func _SHCreateItemFromParsingName($szPath, $pbc, $riid, ByRef $pv)
    Local $aRes = DllCall("shell32.dll", "long", "SHCreateItemFromParsingName", "wstr", $szPath, "ptr", $pbc, "ptr", $riid, "ptr*", 0)
    If @error Then Return SetError(1, 0, 0)
    $pv = $aRes[4]
    Return $aRes[0]
EndFunc   ;==>_SHCreateItemFromParsingName

Func CLSIDFromString($sString)
    Local $tCLSID = DllStructCreate("dword;word;word;byte[8]")
    Local $aRet = DllCall("Ole32.dll", "long", "CLSIDFromString", "wstr", $sString, "ptr", DllStructGetPtr($tCLSID))
    If @error Then Return SetError(1, @error, 0)
    If $aRet[0] <> 0 Then Return SetError(2, $aRet[0], 0)
    Return $tCLSID
EndFunc   ;==>CLSIDFromString

Saludos

Edited by Danyfirex

Share this post


Link to post
Share on other sites

I tried to run and got this error:

==> Variable must be of type "Object".:
$oIFileOperation.SetOperationFlags($FOF_ALLOWUNDO + $FOF_NOCONFIRMMKDIR)
$oIFileOperation^ ERROR

Share this post


Link to post
Share on other sites

Are you on windows 7?

Share this post


Link to post
Share on other sites

if you are on XP use:

#include <APIShellExConstants.au3>
#include <WinAPIFiles.au3>
#include <WinAPIShellEx.au3>


_WinAPI_ShellFileOperation("from", "to", $FO_MOVE, BitOR($FOF_ALLOWUNDO, $FOF_NOCONFIRMMKDIR))

Saludos

Share this post


Link to post
Share on other sites

Yes I use Windows Xp more could not test what you posted why need includes several I have not.

Share this post


Link to post
Share on other sites

Update your autoit version.

Global Const $FO_COPY = 2
Global Const $FO_DELETE = 3
Global Const $FO_MOVE = 1
Global Const $FO_RENAME = 4
Global Const $UBOUND_DIMENSIONS = 0
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)
Global Const $tagSHFILEOPSTRUCT = 'hwnd hWnd;uint Func;ptr From;ptr To;dword Flags;int fAnyOperationsAborted;ptr hNameMappings;ptr ProgressTitle'


_WinAPI_ShellFileOperation("C:\Users\CENTRAL-3\Nueva carpeta", "C:\Users\CENTRAL-3\Desktop", $FO_MOVE, BitOR($FOF_ALLOWUNDO, $FOF_NOCONFIRMMKDIR))


Func _WinAPI_ShellFileOperation($sFrom, $sTo, $iFunc, $iFlags, $sTitle = '', $hParent = 0)
    Local $iData
    If Not IsArray($sFrom) Then
        $iData = $sFrom
        Dim $sFrom[1] = [$iData]
    EndIf
    Local $tFrom = _WinAPI_ArrayToStruct($sFrom)
    If @error Then Return SetError(@error + 20, @extended, 0)

    If Not IsArray($sTo) Then
        $iData = $sTo
        Dim $sTo[1] = [$iData]
    EndIf
    Local $tTo = _WinAPI_ArrayToStruct($sTo)
    If @error Then Return SetError(@error + 30, @extended, 0)

    Local $tSHFILEOPSTRUCT = DllStructCreate($tagSHFILEOPSTRUCT)
    DllStructSetData($tSHFILEOPSTRUCT, 'hWnd', $hParent)
    DllStructSetData($tSHFILEOPSTRUCT, 'Func', $iFunc)
    DllStructSetData($tSHFILEOPSTRUCT, 'From', DllStructGetPtr($tFrom))
    DllStructSetData($tSHFILEOPSTRUCT, 'To', DllStructGetPtr($tTo))
    DllStructSetData($tSHFILEOPSTRUCT, 'Flags', $iFlags)
    DllStructSetData($tSHFILEOPSTRUCT, 'ProgressTitle', $sTitle)

    Local $aRet = DllCall('shell32.dll', 'int', 'SHFileOperationW', 'struct*', $tSHFILEOPSTRUCT)
    If @error Then Return SetError(@error, @extended, 0)
    If $aRet[0] Then Return SetError(10, $aRet[0], 0)

    Return $tSHFILEOPSTRUCT
EndFunc   ;==>_WinAPI_ShellFileOperation

Func _WinAPI_ArrayToStruct(Const ByRef $aData, $iStart = 0, $iEnd = -1)
    If __CheckErrorArrayBounds($aData, $iStart, $iEnd) Then Return SetError(@error + 10, @extended, 0)

    Local $tagStruct = ''
    For $i = $iStart To $iEnd
        $tagStruct &= 'wchar[' & (StringLen($aData[$i]) + 1) & '];'
    Next
    Local $tData = DllStructCreate($tagStruct & 'wchar[1]')

    Local $iCount = 1
    For $i = $iStart To $iEnd
        DllStructSetData($tData, $iCount, $aData[$i])
        $iCount += 1
    Next
    DllStructSetData($tData, $iCount, ChrW(0))
    Return $tData
EndFunc   ;==>_WinAPI_ArrayToStruct

Func __CheckErrorArrayBounds(Const ByRef $aData, ByRef $iStart, ByRef $iEnd, $nDim = 1, $iDim = $UBOUND_DIMENSIONS)
    ; Bounds checking
    If Not IsArray($aData) Then Return SetError(1, 0, 1)
    If UBound($aData, $iDim) <> $nDim Then Return SetError(2, 0, 1)

    If $iStart < 0 Then $iStart = 0

    Local $iUBound = UBound($aData) - 1
    If $iEnd < 1 Or $iEnd > $iUBound Then $iEnd = $iUBound

    If $iStart > $iEnd Then Return SetError(4, 0, 1)

    Return 0
EndFunc   ;==>__CheckErrorArrayBounds

Saludos

Share this post


Link to post
Share on other sites

Using the example you posted is the same as using the DirMove function ie as the source folder and the destination have the same name as the source folder comes within the destination rather than merge with with folder, do the test using the same name in the source and destination folder.

 

_WinAPI_ShellFileOperation("C:Dir sourcetest", "C:Test", $FO_MOVE, BitOR($FOF_ALLOWUNDO, $FOF_NOCONFIRMMKDIR))

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