Make the folder's modified date synchronizes with its subfolders' modified dates

Have a suggestion for "Everything"? Please post it here.
Post Reply
iG0R
Posts: 6
Joined: Sun Aug 18, 2024 6:11 pm

Make the folder's modified date synchronizes with its subfolders' modified dates

Post by iG0R »

Is there a way to make Everything keep the modified date of a parent folder in sync with changes in its subfolders, maintaining accurate modification timestamps throughout the directory tree?

For example, here's a folder and file structure:

Code: Select all

root
└── A/
    └── B/
        └── abcd.txt
Modifying the "abcd.txt" file updates the modified date of folder "B", but this change in the modified date of folder "B" is not reflected in the modified date of folder "A".
void
Developer
Posts: 16723
Joined: Fri Oct 16, 2009 11:31 pm

Re: Make the folder's modified date synchronizes with its subfolders' modified dates

Post by void »

This is by design.

The OS doesn't update the date modified timestamp all the way to the root. (grand parents)
Only the direct parent is updated.
Everything reads the date modified timestamp from the OS.



There is a always_update_folder_recent_change advanced setting.
When enabled, all parents to the root are updated for the Date Recently Changed property..
However, grand parents will only update when a child file size changes.



What are you trying to do with this information?
A script to update the timestamp from child folders (and grand child folders) might be the way to go..
iG0R
Posts: 6
Joined: Sun Aug 18, 2024 6:11 pm

Re: Make the folder's modified date synchronizes with its subfolders' modified dates

Post by iG0R »

void wrote: Sun Aug 18, 2024 11:48 pm This is by design.
Yes, by design, but not by logic.
If I want to know if there have been any changes inside folder "A" - how can I do that?
Folder "A" contains folder "B", which belongs to folder "A", so all changes that have occurred to folder "B" must be synchronized with folder "A", since changes to folder "B" occur inside folder "A".
The same logic as with files inside folder "A" - at the moment, if any changes happen to files inside folder "A", these changes will be reflected in folder "A" itself.
What is the difference between files and folders, in terms of semantics?
Semantically, they are the same - files contain data (raw data) that is modified as well as folders also contain data (files - raw data sources) that is also modified.
void wrote: Sun Aug 18, 2024 11:48 pm The OS doesn't update the date modified timestamp all the way to the root. (grand parents)
Only the direct parent is updated.
Everything reads the date modified timestamp from the OS.
Yeah, and it is a very frustrating situation. Because, maybe it follows some computer logic of its own, but from a human logic point of view, as I described above, it's just too weird.
void wrote: Sun Aug 18, 2024 11:48 pm There is a always_update_folder_recent_change advanced setting.
When enabled, all parents to the root are updated for the Date Recently Changed property..
However, grand parents will only update when a child file size changes.
Oh. I already tried this option before writing my post, but didn't get what I wanted, and now I understand why - despite the fact the modified dates of the child files were changed, their sizes remained the same.
void wrote: Sun Aug 18, 2024 11:48 pm What are you trying to do with this information?
A script to update the timestamp from child folders (and grand child folders) might be the way to go..
When I try to sort files and folders in Total Commander or Windows Explorer by Date modified, I want to see the correct sorting order in whch the changes in the modified date of all files and folders would be reflected properly, but not like at the moment, when folder "A", which contains subfolder "B" with a younger modified date than folder "A", is at the end of the sorting list.

I have already written such a script, but it has the biggest drawback - it needs manual control.

Code: Select all

#Set-PSDebug -Trace 2

# Print the full command line used to run the script
Write-Host "Script was run with the following command:"
Write-Host $MyInvocation.Line
Write-Host ""

# Function to split the input string based on the pattern "space followed by drive letter and a path"
function Split-ArgumentsByPattern {
    param (
        [string]$inputString
    )

    # Regular expression pattern to match space followed by drive letter and path
    $pattern = '(?<=\s|"|^)([A-Za-z]:\\[^\/\:\*\?\"\<\>\|]+(?= [A-Za-z]:|"|$))'

    # Split the string by the pattern
    $folders = [regex]::Matches($inputString, $pattern) | ForEach-Object { $_.Value }

    # Remove any leading or trailing whitespace from each folder path
    $folders = $folders | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne "" }

    return $folders
}

# Combine all arguments into a single string
Write-Host "Arguments         : $args"
Write-Host ""
#$combinedArgs = $args -join " "
#Write-Host "Combined Arguments: $combinedArgs"
#Write-Host ""

# Split the combined string into individual folder paths
$rootFolders = Split-ArgumentsByPattern -inputString $args #$combinedArgs

# Print each folder path passed in the array
Write-Host "RootFolders from arguments:"
foreach ($folder in $rootFolders) {
    Write-Host "- $folder"
}

# Function to update the parent folder's LastWriteTime
function Update-ParentFolderTime {
    param (
        [string]$folderPath
    )

    # Get all items (files and subfolders) in the current folder
    $items = Get-ChildItem -Path $folderPath -Recurse

    # Find the item with the most recent LastWriteTime
    $mostRecentItem = $items | Sort-Object LastWriteTime -Descending | Select-Object -First 1

    # If there's a most recent item, compare its LastWriteTime with the parent folder
    if ($mostRecentItem) {
        $parentFolder = Get-Item -Path $folderPath

        if ($parentFolder.LastWriteTime -lt $mostRecentItem.LastWriteTime) {
            # Update the parent folder's LastWriteTime to the most recent item's LastWriteTime
            Write-Host "6. Updating LastWriteTime of the folder '$folderPath' from $($parentFolder.LastWriteTime) to $($mostRecentItem.LastWriteTime)" -ForegroundColor Red
            $parentFolder.LastWriteTime = $mostRecentItem.LastWriteTime            
        } else {
            Write-Host "7. The folder '$folderPath' has the most recent LastWriteTime than its child files and subfolders" -ForegroundColor DarkGreen
        }
    }
}

# Function to recursively process all folders starting from the bottom level
function Process-Folders {
    param (
        [string]$rootFolder
    )

    # Get all subfolders
    $subfolders = Get-ChildItem -Path $rootFolder -Directory
    Write-Host "1. $subfolders = Get-ChildItem -Path $rootFolder -Directory"
    Write-Host "2. $subfolders"

    foreach ($subfolder in $subfolders) {
        # Recursively process subfolders
        Write-Host "3. Process-Folders -rootFolder $($subfolder.FullName)"
        Process-Folders -rootFolder $subfolder.FullName
    }

    # Update the currently processed root folder
    Write-Host "5. Update-ParentFolderTime -folderPath $rootfolder"
    Update-ParentFolderTime -folderPath $rootFolder
}


# Validate that at least one folder is provided as argument
if (-not $rootFolders) {
    Write-Host '
--------------------------------------------------------
Please provide one or more root folder paths as arguments.

For example:
.\UpdateFolderModifiedDate.ps1 "C:\path\to\folder"
or
.\UpdateFolderModifiedDate.ps1 C:\path\to\folder
or
.\UpdateFolderModifiedDate.ps1 "C:\path\to\folder" "C:\path\to\another\folder" "C:\path\to\yet\another\folder"
or
.\UpdateFolderModifiedDate.ps1 C:\path\to\folder C:\path\to\another\folder C:\path\to\yet\another\folder
--------------------------------------------------------

'
    
    # If no arguments were provided, prompt the user to enter one or more folder paths
    $input = Read-Host 'Or please enter the paths of the folders you want to process (without/with quotes, just separate multiple paths with the space/s).

For example:
"C:\path\to\folder" "C:\path\to\another\folder"
C:\path\to\folder C:\path\to\another\folder
'
    
    # If the user provided folder paths, split them into an array
    if ($input) {
        $rootFolders = Split-ArgumentsByPattern -inputString $input # -split ",\s*"  # Split by comma, allowing for optional spaces
        Write-Host "Input: $input"
        Write-Host "RootFolders from input: $rootFolders"
    } else {
        Write-Host "No folder paths provided. Exiting script."
        Set-PSDebug -Trace 0
        exit 1
    }
}

# Loop through each provided folder and process it
foreach ($rootFolder in $rootFolders) {
    if (Test-Path $rootFolder) {
        Write-Host "RootFolders from arguments: $rootFolders"
        Write-Host "Processing folder: $rootFolder"
        Process-Folders -rootFolder $rootFolder
    } else {
        Write-Host "Folder not found: $rootFolder"
    }
}

Set-PSDebug -Trace 0
And here is the button for TC.

Code: Select all

TOTALCMD#BAR#DATA
powershell.exe -noexit -ExecutionPolicy Bypass "X:\path\to\the\script\UpdateFolderModifiedDate.ps1"
'%X%Y%P%S%T%R'
C:\Program Files (x86)\Total Commander\Wcmicons.dll,51
Change the modification date of folders to match the most recent modification date of their child files or subfolders.


-1
Last edited by iG0R on Mon Aug 19, 2024 10:36 am, edited 2 times in total.
therube
Posts: 4972
Joined: Thu Sep 03, 2009 6:48 pm

Re: Make the folder's modified date synchronizes with its subfolders' modified dates

Post by therube »

(I asked similar of FolderTimeUpdate, back in 2023, but he didn't put that feature in... yet ;-).

was thinking that an Update Mode: of

+ Update Mode: Use the modified time of files *OR* subfolders in the folder only

would be of benefit.


That way if the folder itself only has older files,
but subdirectories contain newer dated files & directories,
such that the date of the subdirectory is newer then its' parent,
the parent (base folder:) would be set to the newest file OR subdirectory

Code: Select all

Directory of T:\K-ORSAIR\LIB\PLAYERS\
----------------------------------------------------------------------------
               _d____ Oct 24, 2022 21:01:42 [MPlayer Skins]
               _d____ Sep 12, 2022 12:13:55 [MPlayer]
               _d____ Sep 07, 2022 12:07:26 [MediaPlayerClassic]
               _d____ Mar 07, 2022 13:44:09 [VLC Video Lan]
               _d____ Oct 27, 2021 14:23:05 [OLD]
               _d____ Jul 03, 2013 11:31:19 [WMP Skins]
               _d____ May 20, 2013 13:47:06 [KMPlayer Skins]
               _d____ Nov 03, 2007 22:05:44 [VLC Skins]
     1,527,829 ______ Dec 28, 2006 20:50:00 zp500std (zoom player free).exe
     2,986,272 ______ Dec 28, 2006 20:49:00 zp500pro (zoom player pro).exe
       933,478 ______ Feb 18, 2004 14:05:00 zoomplayer331std.zip
       696,910 ______ Nov 07, 2002 09:55:00 zoomplayer290.zip

currently, /PLAYERS/ would be dated to 12-28-2006, the latest /file/ date,
but (at least in my case) that date is not indicative of "activity" within
the /PLAYERS/ tree, where /MPlayer/ is updated relatively often

so for me setting /PLAYERS/ to the date of /MPlayer Skins/ (directory),
so 10-24-2022 rather then 12-28-2006 (file date) would be a better indicator that
that there is "activity" taking place in there

(in this case, the /PLAYERS/ directory itself is likely to remain static,
but subdirectories therein are updated, & i'd like the "Base Folder:" to
reflect that.)

note that in this case, i'm also setting, Subfolders Depth: 1.)
void
Developer
Posts: 16723
Joined: Fri Oct 16, 2009 11:31 pm

Re: Make the folder's modified date synchronizes with its subfolders' modified dates

Post by void »

If I want to know if there are any changes occurred in folder "A" - how can I do that?
I will consider a search to list 'modified' folders where:
a descendant folder has a modified date that is more recent than the modified date of the containing folder.
(I suspect this is what you want?)
This might be unusable because most folders will be marked 'modified'.
Won't folders like C:, C:\Users, C:\Users\My User Name, C:\Users\My User Name\AppData get in the way?

I will consider a property to show the timestamp of the most recently modified descendant.


For now, there is child-folder-dm:
(Search for child folders with the specified date modified)

To find folders, where a subfolder was modified today:
child-folder-dm:today

!dm:today child-folder-dm:today
(the containing folder wasn't modified today, but a child folder was..)

I will consider a descendant-folder-dm: search function.
iG0R
Posts: 6
Joined: Sun Aug 18, 2024 6:11 pm

Re: Make the folder's modified date synchronizes with its subfolders' modified dates

Post by iG0R »

void wrote: Tue Aug 20, 2024 11:36 pm a descendant folder has a modified date that is more recent than the modified date of the containing folder.
(I suspect this is what you want?)
I want the changes in the modified date of all descendants (files and subfolders) to be reflected on the modified date of all parent(grandfather, great-grandfather, great-great-grandfather etc.) folders.
For instance, there is the following nested chain (the modified date of the corresponding folder or file is indicated in parentheses)
Folder"A"(02.03.2016) -> Folder"B"(01.11.2018) -> Folder"C"(12.12.2021) -> ... Folder"Y"(02.12.2023) -> Folder"Z"(08.09.2022) -> absd.txt(08.09.2022)
If the modified date of the "abcd.txt" file has changed, then all parent folders in this chain also should change their modified dates
Folder"A"(21.08.2024) -> Folder"B"(21.08.2024) -> Folder"C"(21.08.2024) -> ... Folder"Y"(21.08.2024) -> Folder"Z"(21.08.2024) -> absd.txt(21.08.2024)
void wrote: Tue Aug 20, 2024 11:36 pm This might be unusable because most folders will be marked 'modified'.
Yes, they will be marked modified, but with the corresponding date of this modification, which will allow them to be sorted properly by Date Modified.
That is exactly what is needed.
void wrote: Tue Aug 20, 2024 11:36 pm Won't folders like C:, C:\Users, C:\Users\My User Name, C:\Users\My User Name\AppData get in the way?
How?
void wrote: Tue Aug 20, 2024 11:36 pm I will consider a property to show the timestamp of the most recently modified descendant.
Will it help to properly sort files and folders by the Date Modified column in TC or Windows Explorer?
void
Developer
Posts: 16723
Joined: Fri Oct 16, 2009 11:31 pm

Re: Make the folder's modified date synchronizes with its subfolders' modified dates

Post by void »

Won't folders like C:, C:\Users, C:\Users\My User Name, C:\Users\My User Name\AppData get in the way?
How?
Because programs will constantly write to %APPDATA%.
These folders will always have the current date/time.

You will likely need to limit your search results to a particular folder.


Will it help to properly sort files and folders by the Date Modified column in TC or Windows Explorer?
Everything only.
iG0R
Posts: 6
Joined: Sun Aug 18, 2024 6:11 pm

Re: Make the folder's modified date synchronizes with its subfolders' modified dates

Post by iG0R »

void wrote: Sun Aug 25, 2024 2:04 am Because programs will constantly write to %APPDATA%.
These folders will always have the current date/time.

You will likely need to limit your search results to a particular folder.
Is it possible to do this not only via limiting to a specific folder, but more broadly through blacklisting/whitelisting?
void wrote: Sun Aug 25, 2024 2:04 am
Will it help to properly sort files and folders by the Date Modified column in TC or Windows Explorer?
Everything only.
Could it be implemented in such a way that allows proper sorting by Date modified not only in Everything, but also in the system as a whole?

Also, I tried the always_update_folder_recent_change=1 option.
According to the reference:
When enabled, any change made to the Everything folder database entry will cause the recent change date to update.
This includes folder size changes.
This setting will update the date recently changed property for folders for every change single event. (even when there is no actual change)
This includes folder size changes.
But I don't see any date modifications of the root folder if I make changes to files at depth 2 and below.
For example, if I add or delete a few characters in a file in a subfolder and save it, the date in the root folder will not change.
void
Developer
Posts: 16723
Joined: Fri Oct 16, 2009 11:31 pm

Re: Make the folder's modified date synchronizes with its subfolders' modified dates

Post by void »

It's a shame there isn't an NTFS driver level option to do this..

I would like to avoid writing to volumes with Everything.
I think this would be better as a separate tool.


Is it possible to do this not only via limiting to a specific folder, but more broadly through blacklisting/whitelisting?
For your use case, I recommend writing a script that traverses the desired folders and sets the filetime of all parents.



Here's some C code that I use to update parent folder timestamps and copy timestamps to a backup location:

Code: Select all


#include <stdlib.h>
#include <stdio.h>
#include <windows.h>

// update parent to latest file timestamp:
void parse_file2folder_date(char *dstpath)
{
	char dstbuf[4096];
	WIN32_FIND_DATA fd;
	HANDLE h;
	HANDLE fh;
	LARGE_INTEGER best_ft;
	
	printf("parse %s\n",dstpath);
	
	best_ft.QuadPart = 0;
	
	sprintf(dstbuf,"%s\\*.*",dstpath);
	h = FindFirstFile(dstbuf,&fd);
	if (h != INVALID_HANDLE_VALUE)
	{
		for(;;)
		{
			if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			{
				if ((strcmp(fd.cFileName,"..") != 0) && (strcmp(fd.cFileName,".") != 0))
				{
					sprintf(dstbuf,"%s\\%s",dstpath,fd.cFileName);
					parse_file2folder_date(dstbuf);	
				}
			}
			else
			{
				LARGE_INTEGER dm_ft;
				
				dm_ft.HighPart = fd.ftLastWriteTime.dwHighDateTime;
				dm_ft.LowPart = fd.ftLastWriteTime.dwLowDateTime;
				
				if (dm_ft.QuadPart > best_ft.QuadPart)
				{
					best_ft.QuadPart = dm_ft.QuadPart;
				}
			}
			
			if (!FindNextFile(h,&fd)) break;
		}
		
		FindClose(h);
	}
	
	if (best_ft.QuadPart)
	{
		HANDLE fh;
		
		fh = CreateFile(dstpath,FILE_WRITE_ATTRIBUTES,0,0,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0);
		if (fh != INVALID_HANDLE_VALUE)
		{
		printf("set ft %s\n",fd.cFileName);
			SetFileTime(fh,0,0,(FILETIME *)&best_ft.QuadPart);
			
			CloseHandle(fh);
		}
		else
		{
			printf("invalid file handle %s\n",dstbuf);
//						ExitProcess(0);
		}
	}
}

// copy timestamps:
void parse(char *dstpath,char *srcpath)
{
	char dstbuf[4096];
	char srcbuf[4096];
	WIN32_FIND_DATA fd;
	HANDLE h;
	HANDLE fh;
	
	printf("parse %s %s\n",dstpath,srcpath);
	
	sprintf(srcbuf,"%s\\*.*",srcpath);
	h = FindFirstFile(srcbuf,&fd);
	if (h != INVALID_HANDLE_VALUE)
	{
		for(;;)
		{
			if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			{
				if ((strcmp(fd.cFileName,"..") != 0) && (strcmp(fd.cFileName,".") != 0))
				{
					FILETIME ft;
					HANDLE fh;
					
					sprintf(dstbuf,"%s\\%s",dstpath,fd.cFileName);


					fh = CreateFile(dstbuf,FILE_WRITE_ATTRIBUTES,0,0,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0);
					if (fh != INVALID_HANDLE_VALUE)
					{
					printf("set ft %s\n",fd.cFileName);
						SetFileTime(fh,&fd.ftCreationTime,0,&fd.ftLastWriteTime);
						
						CloseHandle(fh);
					}
					else
					{
						printf("invalid file handle %s\n",dstbuf);
//						ExitProcess(0);
					}

					sprintf(srcbuf,"%s\\%s",srcpath,fd.cFileName);
					parse(dstbuf,srcbuf);	
				}
			}
			else
			{
			
				sprintf(dstbuf,"%s\\%s",dstpath,fd.cFileName);
				fh = CreateFile(dstbuf,FILE_WRITE_ATTRIBUTES,0,0,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0);
				if (fh != INVALID_HANDLE_VALUE)
				{
				printf("set ft %s\n",fd.cFileName);
					SetFileTime(fh,&fd.ftCreationTime,0,&fd.ftLastWriteTime);
					
					CloseHandle(fh);
				}
				else
				{
					printf("invalid file handle %s\n",dstbuf);
//					ExitProcess(0);
				}
			

			}
			
			if (!FindNextFile(h,&fd)) break;
		}
		
		FindClose(h);
	}
}

int main(int argc,char **argv)
{
	parse_file2folder_date("E:\\Music Albums");
//	parse("I:\Backup folder","D:\folder");



voidhash also has code that resets folder timestamps.
iG0R
Posts: 6
Joined: Sun Aug 18, 2024 6:11 pm

Re: Make the folder's modified date synchronizes with its subfolders' modified dates

Post by iG0R »

void wrote: Thu Aug 29, 2024 12:04 am It's a shame there isn't an NTFS driver level option to do this..

I would like to avoid writing to volumes with Everything.
I think this would be better as a separate tool.
Yeah, it's a shame... but we have what we have.

Maybe it would be better, but to write such a tool and have the same superb speed as Everything it needs to write from scratch the same tool as Everything + the feature I asked for.

void wrote: Thu Aug 29, 2024 12:04 am For your use case, I recommend writing a script that traverses the desired folders and sets the filetime of all parents.
Well, I mentioned in the very first post and even gave the code of a script that performs this function, but as I wrote then - it has the biggest drawback that it doesn't work automatically, but only in manual mode.
Or do you have a way to screw it to Everything so that it works in automatic mode?

void wrote: Thu Aug 29, 2024 12:04 am Here's some C code that I use to update parent folder timestamps and copy timestamps to a backup location:
Excuse me, where can this code be used? In Everything?

void wrote: Thu Aug 29, 2024 12:04 am voidhash also has code that resets folder timestamps.
Does it work automatically?
anmac1789
Posts: 669
Joined: Mon Aug 24, 2020 1:16 pm

Re: Make the folder's modified date synchronizes with its subfolders' modified dates

Post by anmac1789 »

void wrote: Thu Aug 29, 2024 12:04 am It's a shame there isn't an NTFS driver level option to do this..

I would like to avoid writing to volumes with Everything.
I think this would be better as a separate tool.


Is it possible to do this not only via limiting to a specific folder, but more broadly through blacklisting/whitelisting?
For your use case, I recommend writing a script that traverses the desired folders and sets the filetime of all parents.



Here's some C code that I use to update parent folder timestamps and copy timestamps to a backup location:

Code: Select all


#include <stdlib.h>
#include <stdio.h>
#include <windows.h>

// update parent to latest file timestamp:
void parse_file2folder_date(char *dstpath)
{
	char dstbuf[4096];
	WIN32_FIND_DATA fd;
	HANDLE h;
	HANDLE fh;
	LARGE_INTEGER best_ft;
	
	printf("parse %s\n",dstpath);
	
	best_ft.QuadPart = 0;
	
	sprintf(dstbuf,"%s\\*.*",dstpath);
	h = FindFirstFile(dstbuf,&fd);
	if (h != INVALID_HANDLE_VALUE)
	{
		for(;;)
		{
			if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			{
				if ((strcmp(fd.cFileName,"..") != 0) && (strcmp(fd.cFileName,".") != 0))
				{
					sprintf(dstbuf,"%s\\%s",dstpath,fd.cFileName);
					parse_file2folder_date(dstbuf);	
				}
			}
			else
			{
				LARGE_INTEGER dm_ft;
				
				dm_ft.HighPart = fd.ftLastWriteTime.dwHighDateTime;
				dm_ft.LowPart = fd.ftLastWriteTime.dwLowDateTime;
				
				if (dm_ft.QuadPart > best_ft.QuadPart)
				{
					best_ft.QuadPart = dm_ft.QuadPart;
				}
			}
			
			if (!FindNextFile(h,&fd)) break;
		}
		
		FindClose(h);
	}
	
	if (best_ft.QuadPart)
	{
		HANDLE fh;
		
		fh = CreateFile(dstpath,FILE_WRITE_ATTRIBUTES,0,0,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0);
		if (fh != INVALID_HANDLE_VALUE)
		{
		printf("set ft %s\n",fd.cFileName);
			SetFileTime(fh,0,0,(FILETIME *)&best_ft.QuadPart);
			
			CloseHandle(fh);
		}
		else
		{
			printf("invalid file handle %s\n",dstbuf);
//						ExitProcess(0);
		}
	}
}

// copy timestamps:
void parse(char *dstpath,char *srcpath)
{
	char dstbuf[4096];
	char srcbuf[4096];
	WIN32_FIND_DATA fd;
	HANDLE h;
	HANDLE fh;
	
	printf("parse %s %s\n",dstpath,srcpath);
	
	sprintf(srcbuf,"%s\\*.*",srcpath);
	h = FindFirstFile(srcbuf,&fd);
	if (h != INVALID_HANDLE_VALUE)
	{
		for(;;)
		{
			if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			{
				if ((strcmp(fd.cFileName,"..") != 0) && (strcmp(fd.cFileName,".") != 0))
				{
					FILETIME ft;
					HANDLE fh;
					
					sprintf(dstbuf,"%s\\%s",dstpath,fd.cFileName);


					fh = CreateFile(dstbuf,FILE_WRITE_ATTRIBUTES,0,0,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0);
					if (fh != INVALID_HANDLE_VALUE)
					{
					printf("set ft %s\n",fd.cFileName);
						SetFileTime(fh,&fd.ftCreationTime,0,&fd.ftLastWriteTime);
						
						CloseHandle(fh);
					}
					else
					{
						printf("invalid file handle %s\n",dstbuf);
//						ExitProcess(0);
					}

					sprintf(srcbuf,"%s\\%s",srcpath,fd.cFileName);
					parse(dstbuf,srcbuf);	
				}
			}
			else
			{
			
				sprintf(dstbuf,"%s\\%s",dstpath,fd.cFileName);
				fh = CreateFile(dstbuf,FILE_WRITE_ATTRIBUTES,0,0,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0);
				if (fh != INVALID_HANDLE_VALUE)
				{
				printf("set ft %s\n",fd.cFileName);
					SetFileTime(fh,&fd.ftCreationTime,0,&fd.ftLastWriteTime);
					
					CloseHandle(fh);
				}
				else
				{
					printf("invalid file handle %s\n",dstbuf);
//					ExitProcess(0);
				}
			

			}
			
			if (!FindNextFile(h,&fd)) break;
		}
		
		FindClose(h);
	}
}

int main(int argc,char **argv)
{
	parse_file2folder_date("E:\\Music Albums");
//	parse("I:\Backup folder","D:\folder");



voidhash also has code that resets folder timestamps.
Do you have C code where we can preserve all 3 date and time fields of a chosen source copy of files and folders to a chosen destination ?
therube
Posts: 4972
Joined: Thu Sep 03, 2009 6:48 pm

Re: Make the folder's modified date synchronizes with its subfolders' modified dates

Post by therube »

Do you have C code where we can preserve all 3 date and time fields of a chosen source copy of files and folders to a chosen destination ?
robocopy, fastcopy, turbocopy? ...
And I guess this is related, how to automate robocopy with windows copy and paste ?
And there was another thread of yours (that I'm not finding at the moment) where you asked the same question?
And all answers are likely to have gotcha's too.
horst.epp
Posts: 1445
Joined: Fri Apr 04, 2014 3:24 pm

Re: Make the folder's modified date synchronizes with its subfolders' modified dates

Post by horst.epp »

Take a look on Nirsoft FolderTimeUpdate.
It works for me in the GUI and also with scripts using it command line switches.
https://www.nirsoft.net/utils/folder_time_update.html
iG0R
Posts: 6
Joined: Sun Aug 18, 2024 6:11 pm

Re: Make the folder's modified date synchronizes with its subfolders' modified dates

Post by iG0R »

horst.epp wrote: Thu Aug 29, 2024 5:59 pm Take a look on Nirsoft FolderTimeUpdate.
I know about FolderTimeUpdate. Can it automatically do what I asked in my first post?
therube
Posts: 4972
Joined: Thu Sep 03, 2009 6:48 pm

Re: Make the folder's modified date synchronizes with its subfolders' modified dates

Post by therube »

No.
But I asked him to include that feature, so... who knows, maybe some time in the future.
anmac1789
Posts: 669
Joined: Mon Aug 24, 2020 1:16 pm

Re: Make the folder's modified date synchronizes with its subfolders' modified dates

Post by anmac1789 »

therube wrote: Thu Aug 29, 2024 5:35 pm
Do you have C code where we can preserve all 3 date and time fields of a chosen source copy of files and folders to a chosen destination ?
robocopy, fastcopy, turbocopy? ...
And I guess this is related, how to automate robocopy with windows copy and paste ?
And there was another thread of yours (that I'm not finding at the moment) where you asked the same question?
And all answers are likely to have gotcha's too.
robocopy does work but have to enter source folder and destination and all options manually or to make robocopy job to exclude certain paths. But, for smple copy is there a C code script or anything equivalent ?
iG0R
Posts: 6
Joined: Sun Aug 18, 2024 6:11 pm

Re: Make the folder's modified date synchronizes with its subfolders' modified dates

Post by iG0R »

therube wrote: Thu Aug 29, 2024 7:46 pm
anmac1789 wrote: Thu Aug 29, 2024 8:03 pm
Hey friends, does all of what you are discussing here have anything to do with my question for which I started this thread?
NotNull
Posts: 5461
Joined: Wed May 24, 2017 9:22 pm

Re: Make the folder's modified date synchronizes with its subfolders' modified dates

Post by NotNull »

I doubt if there is a tool around that changes the ancestor folder dates in real-time. And that is what you (@IGOR) need to show these dates in Total Commander [1].
There is a reason why Windows/NTFS does not change the higher-up folderdates. It can be taxing for the (file) system. IIRC, even changing the direct folderdate will be done "whenever there is time" and can take up to 15 minutes.

Be aware od the side-effects of relying on the accuracy of these folder dates, as they can give false positives and -negatives too.
For example: opening a Word document will generate a temp "~xxxxx.docx" document, which will be deleted when Word closes the document. So even without changing anything (effectively), the folder date will change.
False negative: I have seen unchanged folder dates after deleting a file. Still don't know why ...


Anyway, that is not why I responded. Took a quick look at your code and saw multiple "recursive" lines.
That seemed like too much work. Another approach:
  • read all subfolders (not files!) of the starting folder
  • sort descending by full path (so c:\Windows\system32 before c:\windows before c:\)
  • For each of these folders:
    • Check most recent folderdate of all subfolders (not files! that is unreliable!) on the current level (A)
    • Compare with folder date (B)
    • If A more recent than B, B := A
  • Done

Probably less confusing in code:
(to get the basic idea; it would surprise me if this runs without errors ..)

Code: Select all

Param
(
	[Parameter(Mandatory=$true)]
	[String]$startfolder
)

#	Check if valid path
	If ( -not ( Test-Path $startfolder )) {
		echo "Not a valid folder: $startfolder"
		Exit
	}

#	Create list of all subfolders and sort descending by name (+ path), so deeper levels come first.
	$allfolders = gci -literalpath $startfolder  -dir -recurse -force | sort FullName -descending 


#	For each of these subfolders: check if date of most recent item in this folder is newer than folder date. If so: update folderdate.

	$allfolders | % {

		$ItemsDate = ''
		echo "Current Folder : $($_.FullName) "
		$ItemsDate = (gci -Dir -literalpath $_.FullName -force | sort LastWriteTime)[-1].LastWriteTime
		echo "Most recent item date = $($ItemsDate)"
		echo "FolderDate            = $($_.lastWriteTime)"

		If ($_.lastWriteTime -lt $ItemsDate) {
			echo "FolderDate $_.FullName will be updated"
	#		$_.lastWriteTime = $ItemsDate
		}
	}

EDIT:

Almost forgot: If you want this last modified date of a couple of folders, even without changing the actual dates, try the following:
(it has limitations, but will do for a quick impression)

- Start Everything
- Enable the Folders sidebar ( Menu => View => Folders)
- type or paste the following search:

Code: Select all

folder:   sort:dm   count:1   columns:dm;name;size;path
- Browse in the Folders sidebar to the folder you are intereted in
- In the resultlist, the Date Modified field will show the most recent change date in all subfolders. This will be updated in real-time/within one second

[1] In other file managers, like Directory Opus and XYPlorer, there might be options as those support scriptable columns.
void
Developer
Posts: 16723
Joined: Fri Oct 16, 2009 11:31 pm

Re: Make the folder's modified date synchronizes with its subfolders' modified dates

Post by void »

I am exploring ways to use Everything with an external tool to do what you want.
(Index Journal IPC)

Setting the file/folder timestamp creates a BASIC_INFO_CHANGE USN event.
You would have to ignore this event otherwise you would get stuck in an infinite loop of always updating the parent folders.
This might lead to cases where the parent date modified doesn't match the most recent descendant date modified.
(but it should be accurate enough..)

For now, your script is the best solution.


Do you have C code where we can preserve all 3 date and time fields of a chosen source copy of files and folders to a chosen destination ?
Change the following line:
SetFileTime(fh,&fd.ftCreationTime,0,&fd.ftLastWriteTime);

to:
SetFileTime(fh,&fd.ftCreationTime,&fd.ftLastAccessTime,&fd.ftLastWriteTime);


Sorry, it's all hard coded at the moment.
You'll need to call parse("c:\dst-folder","e:\src-folder")
(copies timestamps from e:\src-folder to c:\dst-folder)
There's tools already out there that do this as mentioned by others.
Post Reply