main
cs 298 lines 9.96 KB
Raw
1 // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3 using System;
4 using System.Collections.Generic;
5 using System.ComponentModel;
6 using System.Diagnostics;
7 using System.IO;
8 using System.Runtime.InteropServices;
9 using Microsoft.Win32;
10
11 namespace TestExe
12 {
13 public abstract class Task
14 {
15 public string data;
16
17 public Task(string Data)
18 {
19 this.data = Data;
20 }
21
22 public abstract void RunTask();
23
24 }
25
26 public class ExitCodeTask : Task
27 {
28 public ExitCodeTask(string Data) : base(Data) { }
29
30 public override void RunTask()
31 {
32 // this task does nothing. Just stores data about what exit code to return.
33 }
34 }
35
36 public class SleepTask : Task
37 {
38 public SleepTask(string Data) : base(Data) { }
39
40 public override void RunTask()
41 {
42 int milliseconds = int.Parse(this.data);
43 Console.WriteLine("Starting to sleep for {0} milliseconds", milliseconds);
44 System.Threading.Thread.Sleep(milliseconds);
45 }
46 }
47
48 public class SleepRandomTask : Task
49 {
50 public SleepRandomTask(string Data) : base(Data) { }
51
52 public override void RunTask()
53 {
54 int low = int.Parse(this.data.Split(new string[] { ":" }, 2, StringSplitOptions.None)[0]);
55 int high = int.Parse(this.data.Split(new string[] { ":" }, 2, StringSplitOptions.None)[1]);
56
57 Random r = new Random();
58 int milliseconds = r.Next(high - low) + low;
59 Console.WriteLine("Starting to sleep for {0} milliseconds", milliseconds);
60 System.Threading.Thread.Sleep(milliseconds);
61 }
62 }
63
64 public class GenerateFilesTask : Task
65 {
66 public GenerateFilesTask(string Data) : base(Data) { }
67
68 public override void RunTask()
69 {
70 string[] tokens = this.data.Split(new char[] { '|' }, 2);
71 string folderPath = System.Environment.ExpandEnvironmentVariables(tokens[0]);
72 long size = long.Parse(tokens[1]);
73 Directory.CreateDirectory(folderPath);
74 var bytes = new byte[0];
75 for (long i = 1; i <= size; i++)
76 {
77 File.WriteAllBytes(Path.Combine(folderPath, $"{i}.txt"), bytes);
78 }
79 }
80 }
81
82 public class LargeFileTask : Task
83 {
84 public LargeFileTask(string Data) : base(Data) { }
85
86 public override void RunTask()
87 {
88 string[] tokens = this.data.Split(new char[] { '|' }, 2);
89 string filePath = System.Environment.ExpandEnvironmentVariables(tokens[0]);
90 long size = long.Parse(tokens[1]);
91 using (var stream = File.Create(filePath))
92 {
93 stream.Seek(size - 1, SeekOrigin.Begin);
94 stream.WriteByte(1);
95 }
96 }
97 }
98
99 public class LogTask : Task
100 {
101 string[] argsUsed;
102 public LogTask(string Data, string[] args)
103 : base(Data)
104 {
105 this.argsUsed = args;
106 }
107
108 public override void RunTask()
109 {
110 string logFile = "";
111 string argsUsedString = "";
112
113 foreach (string a in this.argsUsed)
114 {
115 argsUsedString += a + " ";
116 }
117
118 try
119 {
120 logFile = System.Environment.ExpandEnvironmentVariables(this.data);
121 Console.WriteLine("creating log file: " + logFile);
122 StreamWriter textFile = File.CreateText(logFile);
123 textFile.WriteLine("This is a log file created by TestExe.exe");
124 textFile.WriteLine("Args used: " + argsUsedString);
125 textFile.Close();
126 }
127 catch
128 {
129 Console.WriteLine("creating a log file failed for: {0}", logFile);
130 }
131
132 }
133 }
134
135 public class FileExistsTask : Task
136 {
137 public FileExistsTask(string Data) : base(Data) { }
138
139 public override void RunTask()
140 {
141 string fileToExist = System.Environment.ExpandEnvironmentVariables(this.data);
142
143 if (!String.IsNullOrEmpty(fileToExist))
144 {
145 Console.WriteLine("Waiting for this file to exist: \"" + fileToExist + "\"");
146 while (!System.IO.File.Exists(fileToExist))
147 {
148 System.Threading.Thread.Sleep(250);
149 }
150 Console.WriteLine("Found: \"" + fileToExist + "\"");
151 }
152
153 }
154 }
155
156 public class DeleteManifestsTask : Task
157 {
158 public DeleteManifestsTask(string Data) : base(Data) { }
159
160 public override void RunTask()
161 {
162 string filePath = System.Environment.ExpandEnvironmentVariables(this.data);
163 IntPtr type = new IntPtr(24); //RT_MANIFEST
164 IntPtr name = new IntPtr(1); //CREATEPROCESS_MANIFEST_RESOURCE_ID
165 DeleteResource(filePath, type, name, 1033);
166 }
167
168 private static void DeleteResource(string filePath, IntPtr type, IntPtr name, ushort language, bool throwOnError = false)
169 {
170 bool discard = true;
171 IntPtr handle = BeginUpdateResourceW(filePath, false);
172 try
173 {
174 if (handle == IntPtr.Zero)
175 {
176 throw new Win32Exception();
177 }
178
179 if (!UpdateResourceW(handle, type, name, language, IntPtr.Zero, 0))
180 {
181 throw new Win32Exception();
182 }
183
184 discard = false;
185 }
186 catch
187 {
188 if (throwOnError)
189 {
190 throw;
191 }
192 }
193 finally
194 {
195 if (handle != IntPtr.Zero)
196 {
197 if (!EndUpdateResourceW(handle, discard) && throwOnError)
198 {
199 throw new Win32Exception();
200 }
201 }
202 }
203 }
204
205 [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
206 private extern static IntPtr BeginUpdateResourceW(string fileName, [MarshalAs(UnmanagedType.Bool)] bool deleteExistingResources);
207
208 [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
209 [return: MarshalAs(UnmanagedType.Bool)]
210 private extern static bool UpdateResourceW(IntPtr hUpdate, IntPtr type, IntPtr name, ushort language, IntPtr pData, uint cb);
211
212 [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
213 [return: MarshalAs(UnmanagedType.Bool)]
214 private extern static bool EndUpdateResourceW(IntPtr hUpdate, [MarshalAs(UnmanagedType.Bool)] bool discard);
215 }
216
217 public class TaskParser
218 {
219
220 public static List<Task> ParseTasks(string[] args)
221 {
222 List<Task> tasks = new List<Task>();
223
224 try
225 {
226 // for invalid args. return empty list
227 if (args.Length % 2 == 0)
228 {
229 Task t;
230
231 for (int i = 0; i < args.Length; i += 2)
232 {
233 switch (args[i].ToLower())
234 {
235 case "/ec":
236 t = new ExitCodeTask(args[i + 1]);
237 tasks.Add(t);
238 break;
239 case "/s":
240 t = new SleepTask(args[i + 1]);
241 tasks.Add(t);
242 break;
243 case "/sr":
244 t = new SleepRandomTask(args[i + 1]);
245 tasks.Add(t);
246 break;
247 case "/gf":
248 t = new GenerateFilesTask(args[i + 1]);
249 tasks.Add(t);
250 break;
251 case "/lf":
252 t = new LargeFileTask(args[i + 1]);
253 tasks.Add(t);
254 break;
255 case "/log":
256 t = new LogTask(args[i + 1], args);
257 tasks.Add(t);
258 break;
259 case "/fe":
260 t = new FileExistsTask(args[i + 1]);
261 tasks.Add(t);
262 break;
263 case "/dm":
264 t = new DeleteManifestsTask(args[i + 1]);
265 tasks.Add(t);
266 break;
267 #if NETFRAMEWORK
268 case "/pinfo":
269 t = new ProcessInfoTask(args[i + 1]);
270 tasks.Add(t);
271 break;
272 case "/regw":
273 t = new RegistryWriterTask(args[i + 1]);
274 tasks.Add(t);
275 break;
276 case "/regd":
277 t = new RegistryDeleterTask(args[i + 1]);
278 tasks.Add(t);
279 break;
280 #endif
281
282 default:
283 Console.WriteLine("Error: Invalid switch specified.");
284 return new List<Task>();
285 }
286 }
287 }
288 }
289 catch
290 {
291 Console.WriteLine("Error: Invalid switch data specified. Couldn't parse the data.");
292 return new List<Task>();
293 }
294
295 return tasks;
296 }
297 }
298 }