[FIX] How to preserve file and folder TIMESTAMPS!

Discuss new features and functions
Posts: 4
Joined: 17 Nov 2021

SonicRings

I just signed up so I can make this post.

I know this has been asked a lot, and is a feature I have been wishing for myself for the longest time.

Seeing that it hasn't been implemented yet, I decided to finally take matters into my own hands.

For each job, you can assign a command to be run on completion:

Image

So, I wrote a Robocopy script that would update the destination's file and folder timestamps based on the source's. The batch file (which you can use outside of FreeFileSync) is below:
ROBOCOPY "Source" "Destination" /S /COPY:AT /DCOPY:T /TIMFIX

:: Copy timestamps and attributes from files in source to destination without actually copying any files or folders

:: /S copies non-empty subfolders

:: /COPY:AT only copies attributes and timestamps, not data
:: Since no data is being copied, all subfolders are therefore empty

:: Using /E would still copy empty subfolders, but since the goal is to
:: simply sync attributes and, more importantly, timestamps, after a
:: FreeFileSync job, /S is used so it only runs on files that have been copied
:: to prevent possible exclusions from having their folders copied over anyway

:: /DCOPY:T copies timestamps of directories

:: /TIMFIX fixes file times on all files, even skipped files

pause
The comments describe what each command does.

I'm a noob with robocopy, so if this can be improved upon, please let me know. I would prefer not having to hardcode the source and destination folders in the command itself for use with FFS, but I'm not sure how to go about doing that. It's obviously mandatory to have those when running this as a batch file however.

Anyway, what you need to paste in the command box in FFS is the following:
ROBOCOPY "Source" "Destination" /S /COPY:AT /DCOPY:T /TIMFIX
Make sure the source and destination matches that of the actual job.

I currently don't know how to go about doing this for jobs with multiple directories in an elegant way, but hopefully this is useful for those wishing for this functionality.

And hey, if this can finally be implemented in FFS itself so we wouldn't even need to do this, that would be great. :)
Posts: 941
Joined: 8 May 2006

therube

I would prefer not having to hardcode the source and destination folders in the command itself for use with FFS
If FFS could pass the Left/Right directory names (as "Macros", say %LeftDir%, %RightDir%), you could then pass them to your batch file.
ROBOCOPY  %1  %2...
And for multiple pairs, you could set up a loop... (pseudo-code):
for %%i in %1 %2
do ROBOCOPY %1 %2...
-cut- %1 %2, such that the next set of pairs, coinciding with the next %i, what were, say, %3 %4, become %1 %2...
next %%i
(That "-cut-" part, can't recall how to do that offhand. Maybe it was in UNIX where it was easy, but still should be able to be done in Windows.)
Posts: 4
Joined: 17 Nov 2021

SonicRings

I would prefer not having to hardcode the source and destination folders in the command itself for use with FFS
If FFS could pass the Left/Right directory names (as "Macros", say %LeftDir%, %RightDir%), you could then pass them to your batch file.
ROBOCOPY  %1  %2...
therube, 17 Nov 2021, 17:30
I was wondering about that. Is that actually possible?
Posts: 4
Joined: 17 Nov 2021

SonicRings

Another improvement I'd like to see made to my solution, if possible, is to only run the command on the files that have actually transferred.

As it stands, it runs on every single file that is available in the source, even if only one folder was added to the destination. In my case, I'm backing up my music library with over 130,000 files. This takes several minutes to complete.

I do appreciate very how the task will continue running even after FFS is fully closed, but I feel that if this were to be implemented in FFS in the first place, it would be a lot more refined as it would be trivial to make it only run on the exact files that were transferred, not on everything.
Posts: 3
Joined: 30 Nov 2022

time305s

Hey, thanks for bringing up the use of Robocopy. I followed the documentation (https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/robocopy) and tried as many command/flag combinations as possible but could not get date accessed to copy from a folder in the source folder to the copied folder. Do you have any tips or is this just not possible? I have also made my own post recently about another small program that can copy over date created, date modified, and date accessed. In terms of performance consistency, it has some very minor limitations but at least it can do date accessed for folders better than Robocopy (viewtopic.php?t=9842).
Posts: 1
Joined: 23 May 2023

StefanM

Robocopy cannot copy Timestamps without Data.

I had the following issue.
A is a Local Drive by me.
B is a webdav Drive which dosnt support Timestamps settings.

After FileSync does its job, by the next run, it can see many "new" files on the B: (WebDav) as the datetimes was not set correctly. I cant change thenm at all, as WEbdav doesnt support it.

Therefor I use the Powershell script to set time Timestamps according to the latest sync on the local site.
After that, FileSyanc sees on both sites the same timestamp and can sync perfectly.

BUT:
- The Filedate doesn't show then the "Last modified" date, but the "Last modified/synced" date

I dont care about that, as I need a working sync at least.

But the solution....
I did it with powershell:
$sourceDirectory = "B:\your_daten\source\"
$destinationDirectory = "A:\your_daten\destination\"

$sourceFiles = Get-ChildItem -Path $sourceDirectory -File -Recurse

foreach ($file in $sourceFiles) {
    $destinationFilePath = $file.FullName.Replace($sourceDirectory, $destinationDirectory)
    if (Test-Path $destinationFilePath) {
        $destinationFile = Get-Item -Path $destinationFilePath

        $updateRequired = $false

        if ($destinationFile.LastWriteTime -ne $file.LastWriteTime) {
            $destinationFile.LastWriteTime = $file.LastWriteTime
            $updateRequired = $true
        }
        if ($destinationFile.CreationTime -ne $file.CreationTime) {
            $destinationFile.CreationTime = $file.CreationTime
            $updateRequired = $true
        }
        if ($destinationFile.LastAccessTime -ne $file.LastAccessTime) {
            $destinationFile.LastAccessTime = $file.LastAccessTime
            $updateRequired = $true
        }

        if ($updateRequired) {
            Write-Host "- File: $($file.FullName) B: $($file.LastWriteTime) A: $($destinationFile.LastWriteTime)"
            $destinationFile.SetAttributes($file.Attributes)
        }
    }
}

Write-Host "File times synchronized successfully!"
save that as ps1 file.

within the FreeFileSync you can add the following command:
powershell.exe -ExecutionPolicy Bypass -File "A:\where\filesync_dates.ps1"