1 using System;
2 using System.IO;
3 using System.Text;
4
5 namespace Touch
6 {
7
8
9 class Program
10 {
11 static void Main(string[] args)
12 {
13 Touch myTouch = new Touch();
14 bool boErrorFlag = false;
15
16 if (args.Length == 0)
17 {
18 Console.WriteLine(new UsageText().Text);
19 boErrorFlag = true;
20 }
21
22 for (int i = 0; i < args.Length; i++)
23 {
24 try
25 {
26 if (Directory.Exists(args[i]))
27 {
28 string strDir2Touch = args[i];
29 myTouch.TouchDirectoryRecursive(strDir2Touch);
30 }
31 else if (File.Exists(args[i]))
32 {
33 string strFile2Touch = args[i];
34 myTouch.TouchFile(strFile2Touch);
35 }
36 else
37 {
38 Console.WriteLine("File not found: " + args[i]);
39 boErrorFlag = true;
40 }
41 }
42 catch (Exception e)
43 {
44 Console.WriteLine(e.GetType() + ": " + e.Message + ": " + args[i] + "\r\n");
45 boErrorFlag = true;
46 }
47 }
48
49 if (myTouch.Errors.Length != 0)
50 {
51 Console.WriteLine(myTouch.Errors);
52 boErrorFlag = true;
53 }
54
55 if (boErrorFlag)
56 {
57 Console.WriteLine();
58 Console.WriteLine("Files touched successfully: " + myTouch.SuccesfullTouched);
59 Console.WriteLine("Files touched not successfully: " + myTouch.UnsuccesfullTouched);
60 Console.WriteLine("Press key to exit.");
61 Console.ReadKey();
62 }
63 }
64 }
65
66
67
68 class Touch
69 {
70 private DateTime m_dtCurrentTime;
71 private StringBuilder m_strExceptionStack;
72 private int m_iSuccesfullTouched;
73 private int m_iUnsuccesfullTouched;
74
75
76 public Touch()
77 {
78 m_dtCurrentTime = DateTime.Now;
79 m_strExceptionStack = new StringBuilder();
80 }
81
82
83 public string Errors
84 {
85 get { return m_strExceptionStack.ToString(); }
86 }
87
88
89 public string SuccesfullTouched
90 {
91 get { return m_iSuccesfullTouched.ToString(); }
92 }
93
94
95 public string UnsuccesfullTouched
96 {
97 get { return m_iUnsuccesfullTouched.ToString(); }
98 }
99
100
101 public void TouchDirectoryRecursive(string strDirectory)
102 {
103 DirectoryInfo theDir = new DirectoryInfo(strDirectory);
104 DirectoryInfo[] subDirectories = theDir.GetDirectories();
105
106 for (int i = 0; i < subDirectories.Length; i++)
107 {
108 TouchDirectoryRecursive(subDirectories[i].FullName);
109 }
110
111 try
112 {
113 TouchDirectory(theDir);
114 }
115 catch (Exception e)
116 {
117 AppendException(e, theDir.FullName);
118 }
119
120 FileInfo[] theFiles = theDir.GetFiles();
121
122 for (int i = 0; i < theFiles.Length; i++)
123 {
124 try
125 {
126 TouchFile(theFiles[i]);
127 }
128 catch (Exception e)
129 {
130 AppendException(e, theFiles[i].FullName);
131 }
132 }
133 }
134
135
136 public void TouchFile(string strFile)
137 {
138 try
139 {
140 TouchFile(new FileInfo(strFile));
141 }
142 catch (Exception e)
143 {
144 AppendException(e, strFile);
145 }
146 }
147
148
149 private void TouchDirectory(DirectoryInfo theDir)
150 {
151 FileAttributes faOriginal = theDir.Attributes;
152 theDir.Attributes &= ~(FileAttributes.ReadOnly);
153
154 theDir.CreationTime = m_dtCurrentTime;
155 theDir.LastAccessTime = m_dtCurrentTime;
156 theDir.LastWriteTime = m_dtCurrentTime;
157
158 theDir.Attributes = faOriginal;
159
160 m_iSuccesfullTouched++;
161 }
162
163
164 private void TouchFile(FileInfo theFile)
165 {
166 FileAttributes faOriginal = theFile.Attributes;
167 theFile.Attributes &= ~(FileAttributes.ReadOnly);
168
169 theFile.CreationTime = m_dtCurrentTime;
170 theFile.LastAccessTime = m_dtCurrentTime;
171 theFile.LastWriteTime = m_dtCurrentTime;
172
173 theFile.Attributes = faOriginal;
174
175 m_iSuccesfullTouched++;
176 }
177
178
179 private void AppendException(Exception e, string fileName)
180 {
181 m_strExceptionStack.Append(e.GetType());
182 m_strExceptionStack.Append(": ");
183 m_strExceptionStack.Append(e.Message);
184 m_strExceptionStack.Append(": ");
185 m_strExceptionStack.Append(fileName);
186 m_strExceptionStack.Append("\r\n");
187
188 m_iUnsuccesfullTouched++;
189 }
190 }
191
192
193 }
194
195
196 class UsageText
197 {
198
199 public string Text
200 {
201 get
202 {
203 string s = "" +
204 "Touch by Sebastian Roll 2009/05/28" + "\r\n" +
205 "\r\n" +
206 "Description:" + "\r\n" +
207 "Touch is a little tool for setting the timestamp of files to the current time." + "\r\n" +
208 "It works on Windows systems and it is a simple version of the touch program commonly found on Unix machines." + "\r\n" +
209 "Touch changes the creation, modification and access times of files." + "\r\n" +
210 "The time is taken from standard Windows API. The time used can not be specified." + "\r\n" +
211 "\r\n" +
212 "For each file operand, Touch performs the touch action." + "\r\n" +
213 "If a given file's attribute is read-only, Touch temporarily removes the flag and performs the touch action." + "\r\n" +
214 "If a given file does not exist, no action is taken, but the error is reported." + "\r\n" +
215 "If Touch has no access to a given file, the error is reported." + "\r\n" +
216 "\r\n" +
217 "Requirements:" + "\r\n" +
218 "Microsoft .Net Framework 2.0 or higher." + "\r\n" +
219 "\r\n" +
220 "Limitation:" + "\r\n" +
221 "The Win32 limitation for a command-line string is 8191 characters." + "\r\n" +
222 "Let's say you got many files in a folder named: E:\\Public\\Projects\\C#\\temp" + "\r\n" +
223 "And each file within this folder has 20 characters, " + "\r\n" +
224 "you end up with a length of each command-line argument by 46 characters, including the folder prefix." + "\r\n" +
225 "8191 / 46 = 178 files can be processed with one call of Touch from command-line at max." + "\r\n" +
226 "\r\n" +
227 "Examples:" + "\r\n" +
228 "1. Touch one file" + "\r\n" +
229 "touch FileName.txt" + "\r\n" +
230 "\r\n" +
231 "2. Touch two files" + "\r\n" +
232 "touch FileName_1.txt FileName_2.txt" + "\r\n" +
233 "\r\n" +
234 "3. Touch all content within a directory (recursive)" + "\r\n" +
235 "touch FolderPath" + "\r\n" +
236 "\r\n" +
237 "4. Touch all content within two directories (both recursive)" + "\r\n" +
238 "touch FolderPath_1 FolderPath_2" + "\r\n" +
239 "\r\n" +
240 "5. Touch all content within a directory (recursive) and one file" + "\r\n" +
241 "touch FolderPath FileName.txt" + "\r\n";
242
243 return s;
244 }
245 }
246
247
248 }