Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Directory Compare


  • Please log in to reply
13 replies to this topic
jaco0646
  • Moderators
  • 3165 posts
  • Last active: Apr 01 2014 01:46 AM
  • Joined: 07 Oct 2006
This is a script that I use to check whether or not the files from my laptop are backed up onto my desktop PC and vice versa. It compares the contents of two folders based on file names and sizes. Other comparisons could easily be added as well, such as time stamps.

Update1: I discovered that when comparing files on two drives with different cluster sizes, the size reported for identical files will be slightly different between the two. To solve this, I incorporated a ratio into the comparison procedure, so that files with identical names and almost identical sizes are considered equal.

● Several minor changes were also made: most notably, files with unique sizes are now separated from files with unique names in the final list view (unique sizes come first).Update2: I've created a new GUI frontend for the program, with support for drag-and-drop.

● It now has error checking.Here is the newest script: >DOWNLOAD<

Posted Image

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
Dear jaco0646, :)

Nice! :D ..

This has only been tested on WinXP. For another OS, the "Static9" control will likely be something else


The script runs fine in Windows 2000.

I compared between AutoHotkey versions 1.0.44.00 & 1.0.44.13.
Here is a snapshot: https://ahknet.autoh... ... ompare.png

Regards, :)
kWo4Lk1.png

Directory
  • Guests
  • Last active:
  • Joined: --
I try in XP Pro:

path1 = C:\LP\
path2 = D:\Backup\LP\

But doing nothing, whats wrong please?

ChrisM
  • Members
  • 58 posts
  • Last active: Oct 25 2006 05:56 PM
  • Joined: 28 Nov 2004

path1 = C:\LP\
path2 = D:\Backup\LP\

But doing nothing, whats wrong please?

I've added basic directory checking to this version. The original gives no warning if the paths are not exactly correct.

#SingleInstance force
#NoTrayIcon
;__________________________________________________________
path1 = ;<-- Enter a folder path here
path2 = ;<-- Enter a second folder path here
;__________________________________________________________

; Check if paths exists, if not - warn.
FileGetAttrib, attrib, %path1%
IfNotInString, attrib, D
  {
    MsgBox, 4096, Warning, Could not open: %path1%, 30
    Return
  }
FileGetAttrib, attrib, %path2%
IfNotInString, attrib, D
  {
    MsgBox, 4096, Warning, Could not open: %path2%, 30
    Return
  }

Gui, Add, ListView, w640 h400 Grid
        , %path1%|Size(KB)|%path2%|Size(KB)
Count := Count(path1) + Count(path2)
Progress, fs14 b2 r0-%Count%, Checking files`, please wait.
Compare(path1, path2, 1)
Compare(path2, path1, 3)
Progress, Off
If LV_GetCount() = 0
  {
    MsgBox, 4160, Equal, All files are backed up.
    ExitApp
  }
LV_ModifyCol()
LV_ModifyCol(2, "Float")
LV_ModifyCol(4, "Float")
Gui, Show,, Directory Compare
Return
GuiClose:
  ExitApp
  Count(path)
  {
    SetTitleMatchMode, 2
    Run, properties %path%, %path%, Hide
    WinWait, Properties ahk_class #32770
    Loop
      {
        ControlGetText, Count, static9
        If Count !=
            Break
      }
    WinClose
    StringGetPos, num, Count, %A_Space%
    StringLeft, Count, Count, num
    Return, Count
  }
Compare(path1, path2, num)
  {
    static Count
    Loop, %path1%\*.*,,1
      {
        Count++
        Progress, %Count%
        FileGetSize, size1, %A_LoopFileLongPath%
        StringReplace, name, A_LoopFileLongPath, %path1%\
        IfExist, %path2%\%name%
          {
            FileGetSize, size2, %path2%\%name%
            If (size1 = size2)
                Continue
          }
        i++
        If name Contains \
            name = \%name%
        SetFormat, Float, 0.2
        If (LV_GetCount() < i)
            LV_Add("Col" num, name, size1/1024)
        Else LV_Modify(i, "Col" num, name, size1/1024)
      }
  }

ChrisM

jaco0646
  • Moderators
  • 3165 posts
  • Last active: Apr 01 2014 01:46 AM
  • Joined: 07 Oct 2006
@ Directory:
You don't need to add the final backslash: " \ " to the paths. The script already does that for you. I didn't think to mention that before, but removing those should correct the problem.
path1 = C:\LP 
path2 = D:\Backup\LP

@ ChrisM
Directory checking is a good idea. The only reason I didn't add it is that I always compare the same two folders and rarely any others. Perhaps the best method would be to add two FileSelectFolder commands for picking the directories. This would ensure that there are no trailing backslashes as well, eliminating the problem that Directory encountered.

Directory
  • Guests
  • Last active:
  • Joined: --

@ Directory:
You don't need to add the final backslash: " \ " to the paths. The script already does that for you. I didn't think to mention that before, but removing those should correct the problem.

path1 = C:\LP 
path2 = D:\Backup\LP

Thank you, but I was try with and without " \ ", same thing with the add of ChrisM (Tank you too)
maybe is my sistem problem... :oops:

jaco0646
  • Moderators
  • 3165 posts
  • Last active: Apr 01 2014 01:46 AM
  • Joined: 07 Oct 2006
I can't think of what the problem could be. If you don't see anything after running the script, it might be stuck in the count() function at WinWait, or in the loop thereafter. You could try limiting the loop to a number of iterations and see if that helps.

If you do find a solution, please post it.

ChrisM
  • Members
  • 58 posts
  • Last active: Oct 25 2006 05:56 PM
  • Joined: 28 Nov 2004
Here's a version that has file selection built into the GUI. Basic functionality is still the same.

One thing I can't figure out is how to get the FileSelectFolder dialogue to appear in the middle of the page. For me it's always too low and to the right so the ok and cancel buttons are off the screen.

; This is a script that I use to check whether or not the files from my laptop
; are backed up onto my desktop PC and vice versa. It compares the contents of
; two folders based on file names and sizes. Other comparisons could easily be
; added as well, such as time stamps.

; Simply start the script and type in or select the folders to compare,
; and it will show which files are unique to each.
; This has only been tested on WinXP. For another OS, the "Static9" control
; will likely be something else.

#SingleInstance force
#NoTrayIcon
#NoEnv  ; Must have this so path vars below don't resolve to env path.

; Default path start points
path1 =
path2 =

; Read paths in from ini file
SplitPath, A_ScriptFullPath, , dir, , iniFile
iniFile = %dir%\%iniFile%.ini

i = 0
Loop
  {
    i++
    FileReadLine, tmp, %iniFile%, %i%
    If ErrorLevel
        Break
    path%i% := tmp
    GuiControl,, path%i%, %tmp%
  }

Gui, Add, Edit, x16 y20 w350 h20 vpath1
Gui, Add, Edit, x446 y20 w350 h20 vpath2

Gui, Add, Button, x370 y20 w60 h20 gSelectPath1, Browse
Gui, Add, Button, x800 y20 w60 h20 gSelectPath2, Browse
Gui, Add, Button, x16 y50 w160 h30 gCompareDirs, Compare

Gui, Add, ListView, x16 y90 w840 h540 Grid
        , %path1%|Size(KB)|%path2%|Size(KB)

wCol1 = 330
wCol2 = 80
wCol3 = 330
wCol4 = 80
LV_ModifyCol()
LV_ModifyCol(2, "Float")
LV_ModifyCol(4, "Float")
LV_ModifyCol( 1, wCol1)
LV_ModifyCol( 2, wCol2)
LV_ModifyCol( 3, wCol3)
LV_ModifyCol( 4, wCol4)

Gui, Show, x82 y35 h646 w880, Directory Compare

i = 0
Loop, 2
  {
    i++
    tmp := path%i%
    GuiControl,, path%i%, %tmp%
  }

Return

GuiClose:
  ExitApp
Return

SaveToIni()
  {
    global
    ; Save paths to ini file
    FileDelete, %iniFile%
    i = 0
    Loop, 2
      {
        i++
        tmp := path%i%
        FileAppend, %tmp%`n, %iniFile%
      }
  }

SelectPath1:
  {
    path1 := SelectFolder( path1 )
    GuiControl,, path1, %path1%
    Return
  }

SelectPath2:
  {
    path2 := SelectFolder( path2 )
    GuiControl,, path2, %path2%
    Return
  }

SelectFolder( path )
  {
    Gui +OwnDialogs
    tmp = %path%
    FileSelectFolder, path, *%path%, 2
    If ErrorLevel
        path = %tmp%
    CheckDir( path )
    Return path
  }

CheckDir( path )
  {
    ; Check if paths exists, if not - warn.
    FileGetAttrib, attrib, %path%
    IfNotInString, attrib, D
      {
        MsgBox, 4096, Warning, Could not open: %path%, 30
        Return 1
      }
    Return 0
  }

CompareDirs:
  {
    LV_Delete()
    LV_ModifyCol( 1, wCol1, path1)
    LV_ModifyCol( 3, wCol3, path2)
    Gui Submit, NoHide

    SaveToIni()

    If ( CheckDir( path1 ) )
        Return
    If ( CheckDir( path2 ) )
        Return

    Count := Count(path1) + Count(path2)
    Progress, fs14 b2 r0-%Count%, Checking files`, please wait.
    Compare(path1, path2, 1)
    Compare(path2, path1, 3)
    Progress, Off
    If LV_GetCount() = 0
      {
        MsgBox, 4160, Equal, All files are backed up.
      }
    Return
  }

Count(path)
  {
    SetTitleMatchMode, 2
    Run, properties %path%, %path%, Hide
    WinWait, Properties ahk_class #32770
    Loop
      {
        ControlGetText, Count, static9
        If Count !=
            Break
      }
    WinClose
    StringGetPos, num, Count, %A_Space%
    StringLeft, Count, Count, num
    Return, Count
  }


Compare(path1, path2, num)
  {
    static Count
    Loop, %path1%\*.*,,1
      {
        Count++
        Progress, %Count%
        FileGetSize, size1, %A_LoopFileLongPath%
        StringReplace, name, A_LoopFileLongPath, %path1%\
        IfExist, %path2%\%name%
          {
            FileGetSize, size2, %path2%\%name%
            If (size1 = size2)
                Continue
          }
        i++
        If name Contains \
            name = \%name%
        SetFormat, Float, 0.2
        If (LV_GetCount() < i)
            LV_Add("Col" num, name, size1/1024)
        Else LV_Modify(i, "Col" num, name, size1/1024)
      }
    Return
  }

ChrisM

ChrisM
  • Members
  • 58 posts
  • Last active: Oct 25 2006 05:56 PM
  • Joined: 28 Nov 2004
The above code was just edited to fix a bug that wasn't storing the ini file to the same dir as the script.
ChrisM

  • Guests
  • Last active:
  • Joined: --
I know it is a VERY old post, but jaco, can you update this with the option to copy missing folder between a directory automatically?

jaco0646
  • Moderators
  • 3165 posts
  • Last active: Apr 01 2014 01:46 AM
  • Joined: 07 Oct 2006
I probably won't get time to do anything with it this weekend, but I'll see if the mood strikes me next week. In the meantime, have you seen Microsoft's free SyncToy v2.0?

ruespe
  • Members
  • 567 posts
  • Last active: Dec 01 2014 07:59 PM
  • Joined: 17 Jun 2008

I know it is a VERY old post, but jaco, can you update this with the option to copy missing folder between a directory automatically?

Have you ever tried TotalCommander? http://www.ghisler.com/index.htm

  • Guests
  • Last active:
  • Joined: --
Thanks guys, I will try those

bruno
  • Members
  • 635 posts
  • Last active: Nov 04 2015 02:26 PM
  • Joined: 07 Mar 2011

Here's a version that has file selection built into the GUI. Basic functionality is still the same.

One thing I can't figure out is how to get the FileSelectFolder dialogue to appear in the middle of the page. For me it's always too low and to the right so the ok and cancel buttons are off the screen.
 

; This is a script that I use to check whether or not the files from my laptop
; are backed up onto my desktop PC and vice versa. It compares the contents of
; two folders based on file names and sizes. Other comparisons could easily be
; added as well, such as time stamps.

; Simply start the script and type in or select the folders to compare,
; and it will show which files are unique to each.
; This has only been tested on WinXP. For another OS, the "Static9" control
; will likely be something else.

#SingleInstance force
#NoTrayIcon
#NoEnv  ; Must have this so path vars below don't resolve to env path.

; Default path start points
path1 =
path2 =

; Read paths in from ini file
SplitPath, A_ScriptFullPath, , dir, , iniFile
iniFile = %dir%\%iniFile%.ini

i = 0
Loop
  {
    i++
    FileReadLine, tmp, %iniFile%, %i%
    If ErrorLevel
        Break
    path%i% := tmp
    GuiControl,, path%i%, %tmp%
  }

Gui, Add, Edit, x16 y20 w350 h20 vpath1
Gui, Add, Edit, x446 y20 w350 h20 vpath2

Gui, Add, Button, x370 y20 w60 h20 gSelectPath1, Browse
Gui, Add, Button, x800 y20 w60 h20 gSelectPath2, Browse
Gui, Add, Button, x16 y50 w160 h30 gCompareDirs, Compare

Gui, Add, ListView, x16 y90 w840 h540 Grid
        , %path1%|Size(KB)|%path2%|Size(KB)

wCol1 = 330
wCol2 = 80
wCol3 = 330
wCol4 = 80
LV_ModifyCol()
LV_ModifyCol(2, "Float")
LV_ModifyCol(4, "Float")
LV_ModifyCol( 1, wCol1)
LV_ModifyCol( 2, wCol2)
LV_ModifyCol( 3, wCol3)
LV_ModifyCol( 4, wCol4)

Gui, Show, x82 y35 h646 w880, Directory Compare

i = 0
Loop, 2
  {
    i++
    tmp := path%i%
    GuiControl,, path%i%, %tmp%
  }

Return

GuiClose:
  ExitApp
Return

SaveToIni()
  {
    global
    ; Save paths to ini file
    FileDelete, %iniFile%
    i = 0
    Loop, 2
      {
        i++
        tmp := path%i%
        FileAppend, %tmp%`n, %iniFile%
      }
  }

SelectPath1:
  {
    path1 := SelectFolder( path1 )
    GuiControl,, path1, %path1%
    Return
  }

SelectPath2:
  {
    path2 := SelectFolder( path2 )
    GuiControl,, path2, %path2%
    Return
  }

SelectFolder( path )
  {
    Gui +OwnDialogs
    tmp = %path%
    FileSelectFolder, path, *%path%, 2
    If ErrorLevel
        path = %tmp%
    CheckDir( path )
    Return path
  }

CheckDir( path )
  {
    ; Check if paths exists, if not - warn.
    FileGetAttrib, attrib, %path%
    IfNotInString, attrib, D
      {
        MsgBox, 4096, Warning, Could not open: %path%, 30
        Return 1
      }
    Return 0
  }

CompareDirs:
  {
    LV_Delete()
    LV_ModifyCol( 1, wCol1, path1)
    LV_ModifyCol( 3, wCol3, path2)
    Gui Submit, NoHide

    SaveToIni()

    If ( CheckDir( path1 ) )
        Return
    If ( CheckDir( path2 ) )
        Return

    Count := Count(path1) + Count(path2)
    Progress, fs14 b2 r0-%Count%, Checking files`, please wait.
    Compare(path1, path2, 1)
    Compare(path2, path1, 3)
    Progress, Off
    If LV_GetCount() = 0
      {
        MsgBox, 4160, Equal, All files are backed up.
      }
    Return
  }

Count(path)
  {
    SetTitleMatchMode, 2
    Run, properties %path%, %path%, Hide
    WinWait, Properties ahk_class #32770
    Loop
      {
        ControlGetText, Count, static9
        If Count !=
            Break
      }
    WinClose
    StringGetPos, num, Count, %A_Space%
    StringLeft, Count, Count, num
    Return, Count
  }


Compare(path1, path2, num)
  {
    static Count
    Loop, %path1%\*.*,,1
      {
        Count++
        Progress, %Count%
        FileGetSize, size1, %A_LoopFileLongPath%
        StringReplace, name, A_LoopFileLongPath, %path1%\
        IfExist, %path2%\%name%
          {
            FileGetSize, size2, %path2%\%name%
            If (size1 = size2)
                Continue
          }
        i++
        If name Contains \
            name = \%name%
        SetFormat, Float, 0.2
        If (LV_GetCount() < i)
            LV_Add("Col" num, name, size1/1024)
        Else LV_Modify(i, "Col" num, name, size1/1024)
      }
    Return
  }

this script works for all directories (running XP) EXCEPT C:\Documents and Settings\HP_Administrator\My Documents. any reasons?