aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-05-01 23:58:21 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-05-04 11:33:47 -0500
commit2cbe83832cc76aa379b29665de5523e82c543acf (patch)
tree7cd31282afe0090b753ff3241332237b5602b36b
parent1c22e62b31e92a5788af04d448c19ae0c8b22767 (diff)
downloadwix-2cbe83832cc76aa379b29665de5523e82c543acf.tar.gz
wix-2cbe83832cc76aa379b29665de5523e82c543acf.tar.bz2
wix-2cbe83832cc76aa379b29665de5523e82c543acf.zip
Add test for 5GB external payload.
-rw-r--r--.gitignore2
-rw-r--r--src/TestData/CacheTests/BundleC/BundleC.wixproj26
-rw-r--r--src/TestData/CacheTests/BundleC/BundleC.wxs12
-rw-r--r--src/TestExe/NetfxTask.cs295
-rw-r--r--src/TestExe/Task.cs330
-rw-r--r--src/TestExe/TestExe.csproj7
-rw-r--r--src/WixToolsetTest.BurnE2E/CacheTests.cs27
7 files changed, 401 insertions, 298 deletions
diff --git a/.gitignore b/.gitignore
index 3e8a1553..1075e999 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,8 @@
3## 3##
4## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 4## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 5
6src/TestData/CacheTests/BundleC/fivegb.file
7
6# User-specific files 8# User-specific files
7*.rsuser 9*.rsuser
8*.suo 10*.suo
diff --git a/src/TestData/CacheTests/BundleC/BundleC.wixproj b/src/TestData/CacheTests/BundleC/BundleC.wixproj
new file mode 100644
index 00000000..0acc29c4
--- /dev/null
+++ b/src/TestData/CacheTests/BundleC/BundleC.wixproj
@@ -0,0 +1,26 @@
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<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{997BDF9A-2540-42DB-8F86-296BA243194B}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PackageA\PackageA.wixproj" />
12 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
13 </ItemGroup>
14 <ItemGroup>
15 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
16 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
17 </ItemGroup>
18 <!-- We do this dynamically to avoid committing such a large file to source control. -->
19 <Target Name="CreateLargeFile" AfterTargets="BeforeBuild" Inputs="$(MSBuildProjectFullPath)" Outputs="$(MSBuildProjectDirectory)\fivegb.file">
20 <Exec Command='"$(BaseOutputPath)$(Configuration)\netcoreapp3.1\win-x86\testexe.exe" /lf "fivegb.file|5368709120' WorkingDirectory="$(MSBuildProjectDirectory)" />
21 </Target>
22 <!-- We do this to avoid copying such a large file to the VM to run the tests. -->
23 <Target Name="DeleteLargeFile" AfterTargets="AfterBuild">
24 <Delete Files="$(OutputPath)fivegb.file" />
25 </Target>
26</Project> \ No newline at end of file
diff --git a/src/TestData/CacheTests/BundleC/BundleC.wxs b/src/TestData/CacheTests/BundleC/BundleC.wxs
new file mode 100644
index 00000000..ca21cc6e
--- /dev/null
+++ b/src/TestData/CacheTests/BundleC/BundleC.wxs
@@ -0,0 +1,12 @@
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
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)">
8 <Payload SourceFile="fivegb.file" Compressed="no" />
9 </MsiPackage>
10 </PackageGroup>
11 </Fragment>
12</Wix>
diff --git a/src/TestExe/NetfxTask.cs b/src/TestExe/NetfxTask.cs
new file mode 100644
index 00000000..35b1ea95
--- /dev/null
+++ b/src/TestExe/NetfxTask.cs
@@ -0,0 +1,295 @@
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#if NET35
4using System;
5using System.Collections.Generic;
6using System.Diagnostics;
7using System.IO;
8using System.Management;
9using Microsoft.Win32;
10
11namespace TestExe
12{
13 public class ProcessInfoTask : Task
14 {
15 public ProcessInfoTask(string Data) : base(Data) { }
16
17 public override void RunTask()
18 {
19 try
20 {
21 string processInfoXml = "";
22
23 // Get information about the process and who is running it
24 Process thisProc = Process.GetCurrentProcess();
25 string username = thisProc.StartInfo.EnvironmentVariables["username"].ToString();
26
27 int parentProcId = GetParentProcess(thisProc.Id);
28 Process parentProc = Process.GetProcessById(parentProcId);
29 string parentUsername = parentProc.StartInfo.EnvironmentVariables["username"].ToString();
30
31 int grandparentProcId = GetParentProcess(parentProc.Id);
32 Process grandparentProc = Process.GetProcessById(grandparentProcId);
33 string grandparentUsername = grandparentProc.StartInfo.EnvironmentVariables["username"].ToString();
34
35 processInfoXml += "<ProcessInfo>";
36 processInfoXml += " <ProcessName>" + thisProc.ProcessName + "</ProcessName>";
37 processInfoXml += " <Id>" + thisProc.Id.ToString() + "</Id>";
38 processInfoXml += " <SessionId>" + thisProc.SessionId.ToString() + "</SessionId>";
39 processInfoXml += " <MachineName>" + thisProc.MachineName + "</MachineName>";
40 // this stuff isn't set since we didn't start the process and tell it what to use. So don't bother
41 //processInfoXml += " <StartInfo>";
42 //processInfoXml += " <FileName>" + thisProc.StartInfo.FileName + "</FileName>";
43 //processInfoXml += " <UserName>" + thisProc.StartInfo.UserName + "</UserName>";
44 //processInfoXml += " <WorkingDirectory>" + thisProc.StartInfo.WorkingDirectory + "</WorkingDirectory>";
45 //processInfoXml += " <Arguments>" + thisProc.StartInfo.Arguments + "</Arguments>";
46 //processInfoXml += " </StartInfo>";
47 processInfoXml += " <StartTime>" + thisProc.StartTime.ToString() + "</StartTime>";
48 processInfoXml += " <Username>" + username + "</Username>";
49 processInfoXml += " <ParentProcess>";
50 processInfoXml += " <ProcessName>" + parentProc.ProcessName + "</ProcessName>";
51 processInfoXml += " <Id>" + parentProc.Id.ToString() + "</Id>";
52 processInfoXml += " <StartTime>" + parentProc.StartTime.ToString() + "</StartTime>";
53 processInfoXml += " <Username>" + parentUsername + "</Username>";
54 processInfoXml += " </ParentProcess>";
55 processInfoXml += " <GrandparentProcess>";
56 processInfoXml += " <ProcessName>" + grandparentProc.ProcessName + "</ProcessName>";
57 processInfoXml += " <Id>" + grandparentProc.Id.ToString() + "</Id>";
58 processInfoXml += " <StartTime>" + grandparentProc.StartTime.ToString() + "</StartTime>";
59 processInfoXml += " <Username>" + grandparentUsername + "</Username>";
60 processInfoXml += " </GrandparentProcess>";
61 processInfoXml += "</ProcessInfo>";
62
63 string logFile = System.Environment.ExpandEnvironmentVariables(this.data);
64 Console.WriteLine("Creating Process Info data file: " + logFile);
65 StreamWriter textFile = File.CreateText(logFile);
66 textFile.WriteLine(processInfoXml);
67 textFile.Close();
68 }
69 catch (Exception eX)
70 {
71 Console.WriteLine("Creating Process Info data file failed");
72 Console.WriteLine(eX.Message);
73 }
74
75
76 }
77
78 private static int GetParentProcess(int Id)
79 {
80 int parentPid = 0;
81 using (ManagementObject mo = new ManagementObject("win32_process.handle='" + Id.ToString() + "'"))
82 {
83 mo.Get();
84 parentPid = Convert.ToInt32(mo["ParentProcessId"]);
85 }
86 return parentPid;
87 }
88 }
89
90 /// <summary>
91 /// Task class that will create a registry key and write a name and value in it
92 /// </summary>
93 public class RegistryWriterTask : Task
94 {
95 private string hive;
96 private string keyPath;
97 private string[] keyPathArray;
98 private string name;
99 private RegistryValueKind regValueKind;
100 private object value;
101
102 public RegistryWriterTask(string Data) : base(Data) { }
103
104 public override void RunTask()
105 {
106 if (this.parseRegKeyNameTypeValue(System.Environment.ExpandEnvironmentVariables(this.data)))
107 {
108 RegistryKey rk = Registry.LocalMachine;
109
110 if (this.hive == "HKCU") { rk = Microsoft.Win32.Registry.CurrentUser; }
111 if (this.hive == "HKCC") { rk = Microsoft.Win32.Registry.CurrentConfig; }
112 if (this.hive == "HKLM") { rk = Microsoft.Win32.Registry.LocalMachine; }
113
114 foreach (string key in this.keyPathArray)
115 {
116 rk = rk.CreateSubKey(key, RegistryKeyPermissionCheck.ReadWriteSubTree);
117 }
118
119 rk.SetValue(this.name, this.value, this.regValueKind);
120 Console.WriteLine("Created registry key: '{0}' name: '{1}' value: '{2}' of type: '{3}'",
121 this.hive + "\\" + this.keyPath,
122 this.name,
123 this.value.ToString(),
124 this.regValueKind.ToString());
125 }
126 else
127 {
128 Console.WriteLine("Unable to write registry key.");
129 }
130
131 }
132
133 private bool parseRegKeyNameTypeValue(string delimittedData)
134 {
135 string[] splitString = delimittedData.Split(new string[] { "," }, StringSplitOptions.None);
136 if (splitString.Length != 4)
137 {
138 Console.WriteLine("Invalid regkey. Unable to parse key,name,type,value from: \"" + delimittedData + "\"");
139 return false;
140 }
141 else
142 {
143 this.keyPath = splitString[0];
144 this.name = splitString[1];
145 string datatype = splitString[2];
146 if (datatype == "DWord")
147 {
148 this.value = UInt32.Parse(splitString[3]);
149 }
150 else if (datatype == "QWord")
151 {
152 this.value = UInt64.Parse(splitString[3]);
153 }
154 else
155 {
156 this.value = splitString[3];
157 }
158
159 if (this.keyPath.ToUpper().StartsWith("HKLM\\"))
160 {
161 this.hive = "HKLM";
162 this.keyPath = this.keyPath.Replace("HKLM\\", "");
163 }
164 else if (this.keyPath.ToUpper().StartsWith("HKCC\\"))
165 {
166 this.hive = "HKCC";
167 this.keyPath = this.keyPath.Replace("HKCC\\", "");
168 }
169 else if (this.keyPath.ToUpper().StartsWith("HKCU\\"))
170 {
171 this.hive = "HKCU";
172 this.keyPath = this.keyPath.Replace("HKCU\\", "");
173 }
174 else
175 {
176 Console.WriteLine("Invalid regkey. Unable to determin hive. regkey must start with either: [HKLM], [HKCU], or [HKCC]");
177 return false;
178 }
179 this.keyPathArray = this.keyPath.Split(new string[] { "\\" }, StringSplitOptions.None);
180
181 try
182 {
183 this.regValueKind = (RegistryValueKind)System.Enum.Parse(typeof(RegistryValueKind), datatype);
184 }
185 catch (Exception ex)
186 {
187 Console.WriteLine("Invalid datatype. It must be: String, DWord, or QWord (case sensitive)");
188 Console.WriteLine(ex.Message);
189 return false;
190 }
191 }
192 return true;
193 }
194 }
195
196 /// <summary>
197 /// Task class that will delete a registry key value or registry key and all of its children
198 /// </summary>
199 public class RegistryDeleterTask : Task
200 {
201 private string hive;
202 private string keyPath;
203 private string[] keyPathArray;
204 private string name;
205
206 public RegistryDeleterTask(string Data) : base(Data) { }
207
208 public override void RunTask()
209 {
210 if (this.parseRegKeyName(System.Environment.ExpandEnvironmentVariables(this.data)))
211 {
212 try
213 {
214 RegistryKey rk = Registry.LocalMachine;
215
216 if (this.hive == "HKCU") { rk = Microsoft.Win32.Registry.CurrentUser; }
217 if (this.hive == "HKCC") { rk = Microsoft.Win32.Registry.CurrentConfig; }
218 if (this.hive == "HKLM") { rk = Microsoft.Win32.Registry.LocalMachine; }
219
220 RegistryKey rkParent = null;
221 foreach (string key in this.keyPathArray)
222 {
223 rkParent = rk;
224 rk = rk.OpenSubKey(key, true);
225 }
226
227 if (String.IsNullOrEmpty(this.name))
228 {
229 // delete the key and all of its children
230 string subkeyToDelete = this.keyPathArray[this.keyPathArray.Length - 1];
231 rkParent.DeleteSubKeyTree(subkeyToDelete);
232 Console.WriteLine("Deleted registry key: '{0}'", this.hive + "\\" + this.keyPath);
233 }
234 else
235 {
236 // just delete this value
237 rk.DeleteValue(this.name);
238 Console.WriteLine("Deleted registry key: '{0}' name: '{1}'", this.hive + "\\" + this.keyPath, this.name);
239 }
240 }
241 catch (Exception ex)
242 {
243 Console.WriteLine("Unable to delete registry key: '{0}'", this.hive + "\\" + this.keyPath);
244 Console.WriteLine(ex.Message);
245 }
246 }
247 else
248 {
249 Console.WriteLine("Unable to delete registry key.");
250 }
251
252 }
253
254 private bool parseRegKeyName(string delimittedData)
255 {
256 string[] splitString = delimittedData.Split(new string[] { "," }, StringSplitOptions.None);
257
258 if (splitString.Length > 2)
259 {
260 Console.WriteLine("Unable to parse registry key and name.");
261 return false;
262 }
263
264 this.keyPath = splitString[0];
265 if (splitString.Length == 2)
266 {
267 this.name = splitString[1];
268 }
269
270 if (this.keyPath.ToUpper().StartsWith("HKLM\\"))
271 {
272 this.hive = "HKLM";
273 this.keyPath = this.keyPath.Replace("HKLM\\", "");
274 }
275 else if (this.keyPath.ToUpper().StartsWith("HKCC\\"))
276 {
277 this.hive = "HKCC";
278 this.keyPath = this.keyPath.Replace("HKCC\\", "");
279 }
280 else if (this.keyPath.ToUpper().StartsWith("HKCU\\"))
281 {
282 this.hive = "HKCU";
283 this.keyPath = this.keyPath.Replace("HKCU\\", "");
284 }
285 else
286 {
287 Console.WriteLine("Invalid regkey. Unable to determine hive. regkey must start with either: [HKLM], [HKCU], or [HKCC]");
288 return false;
289 }
290 this.keyPathArray = this.keyPath.Split(new string[] { "\\" }, StringSplitOptions.None);
291 return true;
292 }
293 }
294}
295#endif
diff --git a/src/TestExe/Task.cs b/src/TestExe/Task.cs
index 577acbea..7d39bfd9 100644
--- a/src/TestExe/Task.cs
+++ b/src/TestExe/Task.cs
@@ -4,9 +4,6 @@ using System;
4using System.Collections.Generic; 4using System.Collections.Generic;
5using System.Diagnostics; 5using System.Diagnostics;
6using System.IO; 6using System.IO;
7using System.Linq;
8using System.Management;
9using System.Text;
10using Microsoft.Win32; 7using Microsoft.Win32;
11 8
12namespace TestExe 9namespace TestExe
@@ -17,7 +14,7 @@ namespace TestExe
17 14
18 public Task(string Data) 15 public Task(string Data)
19 { 16 {
20 data = Data; 17 this.data = Data;
21 } 18 }
22 19
23 public abstract void RunTask(); 20 public abstract void RunTask();
@@ -52,8 +49,8 @@ namespace TestExe
52 49
53 public override void RunTask() 50 public override void RunTask()
54 { 51 {
55 int low = int.Parse(data.Split(new string[] { ":" }, 2, StringSplitOptions.None)[0]); 52 int low = int.Parse(this.data.Split(new string[] { ":" }, 2, StringSplitOptions.None)[0]);
56 int high = int.Parse(data.Split(new string[] { ":" }, 2, StringSplitOptions.None)[1]); 53 int high = int.Parse(this.data.Split(new string[] { ":" }, 2, StringSplitOptions.None)[1]);
57 54
58 Random r = new Random(); 55 Random r = new Random();
59 int milliseconds = r.Next(high - low) + low; 56 int milliseconds = r.Next(high - low) + low;
@@ -62,13 +59,30 @@ namespace TestExe
62 } 59 }
63 } 60 }
64 61
62 public class LargeFileTask : Task
63 {
64 public LargeFileTask(string Data) : base(Data) { }
65
66 public override void RunTask()
67 {
68 string[] tokens = this.data.Split(new char[] { '|' }, 2);
69 string filePath = System.Environment.ExpandEnvironmentVariables(tokens[0]);
70 long size = long.Parse(tokens[1]);
71 using (var stream = File.Create(filePath))
72 {
73 stream.Seek(size - 1, SeekOrigin.Begin);
74 stream.WriteByte(1);
75 }
76 }
77 }
78
65 public class LogTask : Task 79 public class LogTask : Task
66 { 80 {
67 string[] argsUsed; 81 string[] argsUsed;
68 public LogTask(string Data, string[] args) 82 public LogTask(string Data, string[] args)
69 : base(Data) 83 : base(Data)
70 { 84 {
71 argsUsed = args; 85 this.argsUsed = args;
72 } 86 }
73 87
74 public override void RunTask() 88 public override void RunTask()
@@ -76,14 +90,14 @@ namespace TestExe
76 string logFile = ""; 90 string logFile = "";
77 string argsUsedString = ""; 91 string argsUsedString = "";
78 92
79 foreach (string a in argsUsed) 93 foreach (string a in this.argsUsed)
80 { 94 {
81 argsUsedString += a + " "; 95 argsUsedString += a + " ";
82 } 96 }
83 97
84 try 98 try
85 { 99 {
86 logFile = System.Environment.ExpandEnvironmentVariables(data); 100 logFile = System.Environment.ExpandEnvironmentVariables(this.data);
87 Console.WriteLine("creating log file: " + logFile); 101 Console.WriteLine("creating log file: " + logFile);
88 StreamWriter textFile = File.CreateText(logFile); 102 StreamWriter textFile = File.CreateText(logFile);
89 textFile.WriteLine("This is a log file created by TestExe.exe"); 103 textFile.WriteLine("This is a log file created by TestExe.exe");
@@ -98,90 +112,13 @@ namespace TestExe
98 } 112 }
99 } 113 }
100 114
101 public class ProcessInfoTask : Task
102 {
103 public ProcessInfoTask(string Data) : base(Data) { }
104
105 public override void RunTask()
106 {
107 try
108 {
109 string processInfoXml = "";
110
111 // Get information about the process and who is running it
112 Process thisProc = Process.GetCurrentProcess();
113 string username = thisProc.StartInfo.EnvironmentVariables["username"].ToString();
114
115 int parentProcId = GetParentProcess(thisProc.Id);
116 Process parentProc = Process.GetProcessById(parentProcId);
117 string parentUsername = parentProc.StartInfo.EnvironmentVariables["username"].ToString();
118
119 int grandparentProcId = GetParentProcess(parentProc.Id);
120 Process grandparentProc = Process.GetProcessById(grandparentProcId);
121 string grandparentUsername = grandparentProc.StartInfo.EnvironmentVariables["username"].ToString();
122
123 processInfoXml += "<ProcessInfo>";
124 processInfoXml += " <ProcessName>" + thisProc.ProcessName + "</ProcessName>";
125 processInfoXml += " <Id>" + thisProc.Id.ToString() + "</Id>";
126 processInfoXml += " <SessionId>" + thisProc.SessionId.ToString() + "</SessionId>";
127 processInfoXml += " <MachineName>" + thisProc.MachineName + "</MachineName>";
128 // this stuff isn't set since we didn't start the process and tell it what to use. So don't bother
129 //processInfoXml += " <StartInfo>";
130 //processInfoXml += " <FileName>" + thisProc.StartInfo.FileName + "</FileName>";
131 //processInfoXml += " <UserName>" + thisProc.StartInfo.UserName + "</UserName>";
132 //processInfoXml += " <WorkingDirectory>" + thisProc.StartInfo.WorkingDirectory + "</WorkingDirectory>";
133 //processInfoXml += " <Arguments>" + thisProc.StartInfo.Arguments + "</Arguments>";
134 //processInfoXml += " </StartInfo>";
135 processInfoXml += " <StartTime>" + thisProc.StartTime.ToString() + "</StartTime>";
136 processInfoXml += " <Username>" + username + "</Username>";
137 processInfoXml += " <ParentProcess>";
138 processInfoXml += " <ProcessName>" + parentProc.ProcessName + "</ProcessName>";
139 processInfoXml += " <Id>" + parentProc.Id.ToString() + "</Id>";
140 processInfoXml += " <StartTime>" + parentProc.StartTime.ToString() + "</StartTime>";
141 processInfoXml += " <Username>" + parentUsername + "</Username>";
142 processInfoXml += " </ParentProcess>";
143 processInfoXml += " <GrandparentProcess>";
144 processInfoXml += " <ProcessName>" + grandparentProc.ProcessName + "</ProcessName>";
145 processInfoXml += " <Id>" + grandparentProc.Id.ToString() + "</Id>";
146 processInfoXml += " <StartTime>" + grandparentProc.StartTime.ToString() + "</StartTime>";
147 processInfoXml += " <Username>" + grandparentUsername + "</Username>";
148 processInfoXml += " </GrandparentProcess>";
149 processInfoXml += "</ProcessInfo>";
150
151 string logFile = System.Environment.ExpandEnvironmentVariables(data);
152 Console.WriteLine("Creating Process Info data file: " + logFile);
153 StreamWriter textFile = File.CreateText(logFile);
154 textFile.WriteLine(processInfoXml);
155 textFile.Close();
156 }
157 catch (Exception eX)
158 {
159 Console.WriteLine("Creating Process Info data file failed");
160 Console.WriteLine(eX.Message);
161 }
162
163
164 }
165
166 private static int GetParentProcess(int Id)
167 {
168 int parentPid = 0;
169 using (ManagementObject mo = new ManagementObject("win32_process.handle='" + Id.ToString() + "'"))
170 {
171 mo.Get();
172 parentPid = Convert.ToInt32(mo["ParentProcessId"]);
173 }
174 return parentPid;
175 }
176 }
177
178 public class FileExistsTask : Task 115 public class FileExistsTask : Task
179 { 116 {
180 public FileExistsTask(string Data) : base(Data) { } 117 public FileExistsTask(string Data) : base(Data) { }
181 118
182 public override void RunTask() 119 public override void RunTask()
183 { 120 {
184 string fileToExist = System.Environment.ExpandEnvironmentVariables(data); 121 string fileToExist = System.Environment.ExpandEnvironmentVariables(this.data);
185 122
186 if (!String.IsNullOrEmpty(fileToExist)) 123 if (!String.IsNullOrEmpty(fileToExist))
187 { 124 {
@@ -196,211 +133,6 @@ namespace TestExe
196 } 133 }
197 } 134 }
198 135
199 /// <summary>
200 /// Task class that will create a registry key and write a name and value in it
201 /// </summary>
202 public class RegistryWriterTask : Task
203 {
204 private string hive;
205 private string keyPath;
206 private string[] keyPathArray;
207 private string name;
208 private RegistryValueKind regValueKind;
209 private object value;
210
211 public RegistryWriterTask(string Data) : base(Data) { }
212
213 public override void RunTask()
214 {
215 if (parseRegKeyNameTypeValue(System.Environment.ExpandEnvironmentVariables(data)))
216 {
217 RegistryKey rk = Registry.LocalMachine;
218
219 if (hive == "HKCU") rk = Microsoft.Win32.Registry.CurrentUser;
220 if (hive == "HKCC") rk = Microsoft.Win32.Registry.CurrentConfig;
221 if (hive == "HKLM") rk = Microsoft.Win32.Registry.LocalMachine;
222
223 foreach (string key in keyPathArray)
224 {
225 rk = rk.CreateSubKey(key, RegistryKeyPermissionCheck.ReadWriteSubTree);
226 }
227
228 rk.SetValue(name, value, regValueKind);
229 Console.WriteLine("Created registry key: '{0}' name: '{1}' value: '{2}' of type: '{3}'",
230 hive + "\\" + keyPath,
231 name,
232 value.ToString(),
233 regValueKind.ToString());
234 }
235 else
236 {
237 Console.WriteLine("Unable to write registry key.");
238 }
239
240 }
241
242 private bool parseRegKeyNameTypeValue(string delimittedData)
243 {
244 string[] splitString = delimittedData.Split(new string[] { "," }, StringSplitOptions.None);
245 if (splitString.Length != 4)
246 {
247 Console.WriteLine("Invalid regkey. Unable to parse key,name,type,value from: \"" + delimittedData + "\"");
248 return false;
249 }
250 else
251 {
252 keyPath = splitString[0];
253 name = splitString[1];
254 string datatype = splitString[2];
255 if (datatype == "DWord")
256 {
257 value = UInt32.Parse(splitString[3]);
258 }
259 else if (datatype == "QWord")
260 {
261 value = UInt64.Parse(splitString[3]);
262 }
263 else
264 {
265 value = splitString[3];
266 }
267
268 if (keyPath.ToUpper().StartsWith("HKLM\\"))
269 {
270 hive = "HKLM";
271 keyPath = keyPath.Replace("HKLM\\", "");
272 }
273 else if (keyPath.ToUpper().StartsWith("HKCC\\"))
274 {
275 hive = "HKCC";
276 keyPath = keyPath.Replace("HKCC\\", "");
277 }
278 else if (keyPath.ToUpper().StartsWith("HKCU\\"))
279 {
280 hive = "HKCU";
281 keyPath = keyPath.Replace("HKCU\\", "");
282 }
283 else
284 {
285 Console.WriteLine("Invalid regkey. Unable to determin hive. regkey must start with either: [HKLM], [HKCU], or [HKCC]");
286 return false;
287 }
288 keyPathArray = keyPath.Split(new string[] { "\\" }, StringSplitOptions.None);
289
290 try
291 {
292 regValueKind = (RegistryValueKind)System.Enum.Parse(typeof(RegistryValueKind), datatype);
293 }
294 catch (Exception ex)
295 {
296 Console.WriteLine("Invalid datatype. It must be: String, DWord, or QWord (case sensitive)");
297 Console.WriteLine(ex.Message);
298 return false;
299 }
300 }
301 return true;
302 }
303 }
304
305 /// <summary>
306 /// Task class that will delete a registry key value or registry key and all of its children
307 /// </summary>
308 public class RegistryDeleterTask : Task
309 {
310 private string hive;
311 private string keyPath;
312 private string[] keyPathArray;
313 private string name;
314
315 public RegistryDeleterTask(string Data) : base(Data) { }
316
317 public override void RunTask()
318 {
319 if (parseRegKeyName(System.Environment.ExpandEnvironmentVariables(data)))
320 {
321 try
322 {
323 RegistryKey rk = Registry.LocalMachine;
324
325 if (hive == "HKCU") rk = Microsoft.Win32.Registry.CurrentUser;
326 if (hive == "HKCC") rk = Microsoft.Win32.Registry.CurrentConfig;
327 if (hive == "HKLM") rk = Microsoft.Win32.Registry.LocalMachine;
328
329 RegistryKey rkParent = null;
330 foreach (string key in keyPathArray)
331 {
332 rkParent = rk;
333 rk = rk.OpenSubKey(key, true);
334 }
335
336 if (String.IsNullOrEmpty(name))
337 {
338 // delete the key and all of its children
339 string subkeyToDelete = keyPathArray[keyPathArray.Length - 1];
340 rkParent.DeleteSubKeyTree(subkeyToDelete);
341 Console.WriteLine("Deleted registry key: '{0}'", hive + "\\" + keyPath);
342 }
343 else
344 {
345 // just delete this value
346 rk.DeleteValue(name);
347 Console.WriteLine("Deleted registry key: '{0}' name: '{1}'", hive + "\\" + keyPath, name);
348 }
349 }
350 catch (Exception ex)
351 {
352 Console.WriteLine("Unable to delete registry key: '{0}'", hive + "\\" + keyPath);
353 Console.WriteLine(ex.Message);
354 }
355 }
356 else
357 {
358 Console.WriteLine("Unable to delete registry key.");
359 }
360
361 }
362
363 private bool parseRegKeyName(string delimittedData)
364 {
365 string[] splitString = delimittedData.Split(new string[] { "," }, StringSplitOptions.None);
366
367 if (splitString.Length > 2)
368 {
369 Console.WriteLine("Unable to parse registry key and name.");
370 return false;
371 }
372
373 keyPath = splitString[0];
374 if (splitString.Length == 2)
375 {
376 name = splitString[1];
377 }
378
379 if (keyPath.ToUpper().StartsWith("HKLM\\"))
380 {
381 hive = "HKLM";
382 keyPath = keyPath.Replace("HKLM\\", "");
383 }
384 else if (keyPath.ToUpper().StartsWith("HKCC\\"))
385 {
386 hive = "HKCC";
387 keyPath = keyPath.Replace("HKCC\\", "");
388 }
389 else if (keyPath.ToUpper().StartsWith("HKCU\\"))
390 {
391 hive = "HKCU";
392 keyPath = keyPath.Replace("HKCU\\", "");
393 }
394 else
395 {
396 Console.WriteLine("Invalid regkey. Unable to determine hive. regkey must start with either: [HKLM], [HKCU], or [HKCC]");
397 return false;
398 }
399 keyPathArray = keyPath.Split(new string[] { "\\" }, StringSplitOptions.None);
400 return true;
401 }
402 }
403
404 public class TaskParser 136 public class TaskParser
405 { 137 {
406 138
@@ -431,18 +163,23 @@ namespace TestExe
431 t = new SleepRandomTask(args[i + 1]); 163 t = new SleepRandomTask(args[i + 1]);
432 tasks.Add(t); 164 tasks.Add(t);
433 break; 165 break;
434 case "/log": 166 case "/lf":
435 t = new LogTask(args[i + 1], args); 167 t = new LargeFileTask(args[i + 1]);
436 tasks.Add(t); 168 tasks.Add(t);
437 break; 169 break;
438 case "/pinfo": 170 case "/log":
439 t = new ProcessInfoTask(args[i + 1]); 171 t = new LogTask(args[i + 1], args);
440 tasks.Add(t); 172 tasks.Add(t);
441 break; 173 break;
442 case "/fe": 174 case "/fe":
443 t = new FileExistsTask(args[i + 1]); 175 t = new FileExistsTask(args[i + 1]);
444 tasks.Add(t); 176 tasks.Add(t);
445 break; 177 break;
178#if NET35
179 case "/pinfo":
180 t = new ProcessInfoTask(args[i + 1]);
181 tasks.Add(t);
182 break;
446 case "/regw": 183 case "/regw":
447 t = new RegistryWriterTask(args[i + 1]); 184 t = new RegistryWriterTask(args[i + 1]);
448 tasks.Add(t); 185 tasks.Add(t);
@@ -451,6 +188,7 @@ namespace TestExe
451 t = new RegistryDeleterTask(args[i + 1]); 188 t = new RegistryDeleterTask(args[i + 1]);
452 tasks.Add(t); 189 tasks.Add(t);
453 break; 190 break;
191#endif
454 192
455 default: 193 default:
456 Console.WriteLine("Error: Invalid switch specified."); 194 Console.WriteLine("Error: Invalid switch specified.");
diff --git a/src/TestExe/TestExe.csproj b/src/TestExe/TestExe.csproj
index 933fa932..5a130422 100644
--- a/src/TestExe/TestExe.csproj
+++ b/src/TestExe/TestExe.csproj
@@ -3,15 +3,18 @@
3 3
4<Project Sdk="Microsoft.NET.Sdk"> 4<Project Sdk="Microsoft.NET.Sdk">
5 <PropertyGroup> 5 <PropertyGroup>
6 <TargetFrameworks>net35</TargetFrameworks> 6 <TargetFrameworks>net35;netcoreapp3.1</TargetFrameworks>
7 <AssemblyName>TestExe</AssemblyName> 7 <AssemblyName>TestExe</AssemblyName>
8 <RootNamespace>TestExe</RootNamespace> 8 <RootNamespace>TestExe</RootNamespace>
9 <OutputType>Exe</OutputType> 9 <OutputType>Exe</OutputType>
10 <DebugType>embedded</DebugType> 10 <DebugType>embedded</DebugType>
11 <RuntimeIdentifier>win-x86</RuntimeIdentifier> 11 <RuntimeIdentifier>win-x86</RuntimeIdentifier>
12 <SelfContained>false</SelfContained>
13 <UseAppHost>true</UseAppHost>
14 <RollForward>Major</RollForward>
12 </PropertyGroup> 15 </PropertyGroup>
13 16
14 <ItemGroup> 17 <ItemGroup Condition="'$(TargetFramework)'=='net35'">
15 <Reference Include="System.Management" /> 18 <Reference Include="System.Management" />
16 </ItemGroup> 19 </ItemGroup>
17</Project> \ No newline at end of file 20</Project> \ No newline at end of file
diff --git a/src/WixToolsetTest.BurnE2E/CacheTests.cs b/src/WixToolsetTest.BurnE2E/CacheTests.cs
index f62b0874..e8d37aef 100644
--- a/src/WixToolsetTest.BurnE2E/CacheTests.cs
+++ b/src/WixToolsetTest.BurnE2E/CacheTests.cs
@@ -5,6 +5,7 @@ namespace WixToolsetTest.BurnE2E
5 using System.Collections.Generic; 5 using System.Collections.Generic;
6 using System.IO; 6 using System.IO;
7 using WixBuildTools.TestSupport; 7 using WixBuildTools.TestSupport;
8 using WixTestTools;
8 using WixToolset.Mba.Core; 9 using WixToolset.Mba.Core;
9 using Xunit; 10 using Xunit;
10 using Xunit.Abstractions; 11 using Xunit.Abstractions;
@@ -14,6 +15,32 @@ namespace WixToolsetTest.BurnE2E
14 public CacheTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { } 15 public CacheTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
15 16
16 [Fact] 17 [Fact]
18 public void CanCache5GBFile()
19 {
20 var packageA = this.CreatePackageInstaller("PackageA");
21 var bundleC = this.CreateBundleInstaller("BundleC");
22
23 packageA.VerifyInstalled(false);
24
25 // Recreate the 5GB payload to avoid having to copy it to the VM to run the tests.
26 var targetFilePath = Path.Combine(this.TestContext.TestDataFolder, "fivegb.file");
27 if (!File.Exists(targetFilePath))
28 {
29 var testTool = new TestTool(Path.Combine(TestData.Get(), "win-x86", "TestExe.exe"))
30 {
31 Arguments = "/lf \"" + targetFilePath + "|5368709120\"",
32 ExpectedExitCode = 0,
33 };
34 testTool.Run(true);
35 }
36
37 bundleC.Install();
38 bundleC.VerifyRegisteredAndInPackageCache();
39
40 packageA.VerifyInstalled(true);
41 }
42
43 [Fact]
17 public void CanDownloadPayloadsFromMissingAttachedContainer() 44 public void CanDownloadPayloadsFromMissingAttachedContainer()
18 { 45 {
19 var packageA = this.CreatePackageInstaller("PackageA"); 46 var packageA = this.CreatePackageInstaller("PackageA");