├── .gitignore ├── Program.cs ├── Properties └── AssemblyInfo.cs ├── README.md ├── Timestomp.csproj ├── Timestomp.csproj.user └── Timestomp.sln /.gitignore: -------------------------------------------------------------------------------- 1 | .vs/* 2 | bin/* 3 | obj/* -------------------------------------------------------------------------------- /Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Timestomp 5 | { 6 | class Program 7 | { 8 | 9 | static bool CopyTimestampFromFile(string toPath, string fromPath) 10 | { 11 | try 12 | { 13 | if (!File.Exists(toPath)) 14 | { 15 | Console.WriteLine("Cannot find {0}", toPath); 16 | return false; 17 | } 18 | 19 | if (!File.Exists(fromPath)) 20 | { 21 | Console.WriteLine("Cannot find {0}", fromPath); 22 | return false; 23 | } 24 | Console.WriteLine("Old timestamps {0} Create:{1} Modify:{2}", new FileInfo(toPath).FullName, File.GetCreationTime(toPath), File.GetLastWriteTime(toPath)); 25 | 26 | 27 | DateTime creationTime = File.GetCreationTime(fromPath); 28 | DateTime modifyTime = File.GetLastWriteTime(fromPath); 29 | 30 | File.SetCreationTimeUtc(toPath, creationTime); 31 | File.SetLastWriteTimeUtc(toPath, modifyTime); 32 | 33 | } catch (Exception e) 34 | { 35 | Console.WriteLine("Error copying timestamp from {0} to {1}: {2}", new FileInfo(toPath).FullName, toPath, e.Message); 36 | return false; 37 | } 38 | return true; 39 | } 40 | 41 | static bool SetTimestampOnFile(string targetfile, string createTimestamp, string modifyTimestamp) 42 | { 43 | if (!File.Exists(targetfile)) 44 | { 45 | Console.WriteLine("Cannot find {0}", targetfile); 46 | return false; 47 | } 48 | Console.WriteLine("Old timestamps {0} Create:{1} Modify:{2}", new FileInfo(targetfile).FullName, File.GetCreationTime(targetfile), File.GetLastWriteTime(targetfile)); 49 | 50 | //parse into DateTime object 51 | DateTime parsedCreate = new DateTime(); 52 | DateTime parsedModify = new DateTime(); 53 | try 54 | { 55 | parsedCreate = DateTime.Parse(createTimestamp); 56 | parsedModify = DateTime.Parse(modifyTimestamp); 57 | } catch (Exception e) 58 | { 59 | Console.WriteLine("Error parsing timestamps into objects: {0}", e.Message); 60 | PrintUsage(); 61 | return false; 62 | } 63 | 64 | try 65 | { 66 | 67 | File.SetCreationTimeUtc(targetfile, parsedCreate); 68 | File.SetLastWriteTimeUtc(targetfile, parsedModify); 69 | 70 | } catch (Exception e) 71 | { 72 | Console.WriteLine("Error setting timestamp on {0}: {1}", new FileInfo(targetfile).FullName, e.Message); 73 | return false; 74 | } 75 | return true; 76 | } 77 | static void Main(string[] args) 78 | { 79 | if (args.Length < 2) 80 | { 81 | Console.WriteLine("Invalid args"); 82 | PrintUsage(); 83 | return; 84 | } 85 | 86 | string filename = args[0]; 87 | string action = args[1]; 88 | if (!(action == "-copy" || action == "-set" || action == "-get")) 89 | { 90 | PrintUsage(); 91 | return; 92 | } 93 | 94 | if (action == "-get") 95 | { 96 | GetTimestamp(filename); 97 | } 98 | 99 | if (action == "-copy") { 100 | var copyfromfile = args[2]; 101 | CopyTimestampFromFile(filename, copyfromfile); 102 | Console.WriteLine("New timestamps {0} Create={1} Modify={2}", new FileInfo(filename).FullName, File.GetCreationTime(filename), File.GetLastWriteTime(filename)); 103 | 104 | } 105 | 106 | if (action == "-set") 107 | { 108 | if (args.Length == 3) //create and modify timestamp same 109 | { 110 | string newCreate = args[2]; 111 | string newModify = args[2]; 112 | SetTimestampOnFile(filename, newCreate, newModify); 113 | } 114 | else //different create and modify timestamps 115 | { 116 | string newCreate = args[2]; 117 | string newModify = args[3]; 118 | SetTimestampOnFile(filename, newCreate, newModify); 119 | } 120 | Console.WriteLine("New timestamps {0} Create={1} Modify={2}", new FileInfo(filename).FullName, File.GetCreationTime(filename), File.GetLastWriteTime(filename)); 121 | 122 | } 123 | 124 | } 125 | 126 | private static bool GetTimestamp(string filename) 127 | { 128 | if (!File.Exists(filename)) 129 | { 130 | Console.WriteLine("Cannot find {0}", filename); 131 | return false; 132 | } 133 | Console.WriteLine("Existing timestamps {0} Create={1} Modify={2}", new FileInfo(filename).FullName, File.GetCreationTime(filename), File.GetLastWriteTime(filename)); 134 | return true; 135 | } 136 | 137 | public static void PrintUsage() 138 | { 139 | Console.WriteLine(@"Get timestamp of file: Timestomp.exe C:\windows\explorer.exe -get"); 140 | Console.WriteLine(@"Copy from another file: Timestomp.exe C:\targetfile.exe -copy C:\windows\system32\calc.exe"); 141 | Console.WriteLine(@"Set create: Timestomp.exe C:\targetfile.exe -set CreateDate (like YYYY-MM-DDTHH:mm:ss)"); 142 | Console.WriteLine(@"Set create and modify: Timestomp.exe C:\targetfile.exe -set CreateDate ModifyDate"); 143 | Console.WriteLine(@"Example: Timestomp.exe C:\targetfile.exe -set 2018-08-18T07:22:16"); 144 | Console.WriteLine(@"Example: Timestomp.exe C:\targetfile.exe -set 2017-08-18T07:22:16 2018-03-14T03:21:11"); 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Timestomp")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Timestomp")] 13 | [assembly: AssemblyCopyright("Copyright © 2021")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0e804ef3-50d2-402c-b897-0451aee98fff")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This .NET program overwrites file create/modify times in .NET. It does so using .NET methods only (no Pinvoke) 2 | 3 | #### Get timestamp of file: 4 | 5 | `Timestomp.exe C:\windows\explorer.exe -get` 6 | 7 | #### Copy from another file: 8 | 9 | `Timestomp.exe C:\targetfile.exe -copy C:\windows\system32\calc.exe` 10 | 11 | #### Set create and modify to the same timestamp: 12 | 13 | `Timestomp.exe C:\targetfile.exe -set Date (like YYYY-MM-DDTHH:mm:ss)` 14 | 15 | `Timestomp.exe C:\targetfile.exe -set 2018-08-18T07:22:16` 16 | 17 | 18 | #### Set create and modify to different timestamps: 19 | 20 | `Timestomp.exe C:\targetfile.exe -set CreateDate ModifyDate` 21 | 22 | `Timestomp.exe C:\targetfile.exe -set 2017-08-18T07:22:16 2018-03-14T03:21:11` -------------------------------------------------------------------------------- /Timestomp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {0E804EF3-50D2-402C-B897-0451AEE98FFF} 8 | Exe 9 | Timestomp 10 | Timestomp 11 | v4.0 12 | 512 13 | true 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Timestomp.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | C:\windows\explorer.exe -get 5 | 6 | -------------------------------------------------------------------------------- /Timestomp.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30907.101 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Timestomp", "Timestomp.csproj", "{0E804EF3-50D2-402C-B897-0451AEE98FFF}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {0E804EF3-50D2-402C-B897-0451AEE98FFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {0E804EF3-50D2-402C-B897-0451AEE98FFF}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {0E804EF3-50D2-402C-B897-0451AEE98FFF}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {0E804EF3-50D2-402C-B897-0451AEE98FFF}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {5610B983-94F9-45EE-A6BC-A1FF23B157F7} 24 | EndGlobalSection 25 | EndGlobal 26 | --------------------------------------------------------------------------------