aboutsummaryrefslogtreecommitdiff
path: root/src/dtf/WixToolsetTests.Dtf.WindowsInstaller
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/dtf/WixToolsetTests.Dtf.WindowsInstaller.CustomActions/CustomActionTest.cs206
-rw-r--r--src/dtf/WixToolsetTests.Dtf.WindowsInstaller.CustomActions/WixToolsetTests.Dtf.WindowsInstaller.CustomActions.csproj28
-rw-r--r--src/dtf/WixToolsetTests.Dtf.WindowsInstaller.Linq/LinqTest.cs509
-rw-r--r--src/dtf/WixToolsetTests.Dtf.WindowsInstaller.Linq/WixToolsetTests.Dtf.WindowsInstaller.Linq.csproj31
-rw-r--r--src/dtf/WixToolsetTests.Dtf.WindowsInstaller/EmbeddedExternalUI.cs173
-rw-r--r--src/dtf/WixToolsetTests.Dtf.WindowsInstaller/Schema.cs238
-rw-r--r--src/dtf/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTest.cs409
-rw-r--r--src/dtf/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTransactions.cs161
-rw-r--r--src/dtf/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerUtils.cs174
-rw-r--r--src/dtf/WixToolsetTests.Dtf.WindowsInstaller/WixToolsetTests.Dtf.WindowsInstaller.csproj34
10 files changed, 1963 insertions, 0 deletions
diff --git a/src/dtf/WixToolsetTests.Dtf.WindowsInstaller.CustomActions/CustomActionTest.cs b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller.CustomActions/CustomActionTest.cs
new file mode 100644
index 00000000..bf843024
--- /dev/null
+++ b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller.CustomActions/CustomActionTest.cs
@@ -0,0 +1,206 @@
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
3namespace WixToolset.Dtf.Test
4{
5 using System;
6 using System.IO;
7 using System.Text;
8 using System.Collections.Generic;
9 using Microsoft.VisualStudio.TestTools.UnitTesting;
10 using WixToolset.Dtf.WindowsInstaller;
11
12 [TestClass]
13 public class CustomActionTest
14 {
15 public CustomActionTest()
16 {
17 }
18
19 [TestMethod]
20 [Ignore] // Currently fails.
21 public void CustomActionTest1()
22 {
23 InstallLogModes logEverything =
24 InstallLogModes.FatalExit |
25 InstallLogModes.Error |
26 InstallLogModes.Warning |
27 InstallLogModes.User |
28 InstallLogModes.Info |
29 InstallLogModes.ResolveSource |
30 InstallLogModes.OutOfDiskSpace |
31 InstallLogModes.ActionStart |
32 InstallLogModes.ActionData |
33 InstallLogModes.CommonData |
34 InstallLogModes.Progress |
35 InstallLogModes.Initialize |
36 InstallLogModes.Terminate |
37 InstallLogModes.ShowDialog;
38
39 Installer.SetInternalUI(InstallUIOptions.Silent);
40 ExternalUIHandler prevHandler = Installer.SetExternalUI(
41 WindowsInstallerTest.ExternalUILogger, logEverything);
42
43 try
44 {
45 string[] customActions = new string[] { "SampleCA1", "SampleCA2" };
46 #if DEBUG
47 string caDir = @"..\..\..\..\..\build\debug\x86\";
48 #else
49 string caDir = @"..\..\..\..\..\build\ship\x86\";
50 #endif
51 caDir = Path.GetFullPath(caDir);
52 string caFile = "WixToolset.Dtf.Samples.ManagedCA.dll";
53 string caProduct = "CustomActionTest.msi";
54
55 this.CreateCustomActionProduct(caProduct, caDir + caFile, customActions, false);
56
57 Exception caughtEx = null;
58 try
59 {
60 Installer.InstallProduct(caProduct, String.Empty);
61 }
62 catch (Exception ex) { caughtEx = ex; }
63 Assert.IsInstanceOfType(caughtEx, typeof(InstallCanceledException),
64 "Exception thrown while installing product: " + caughtEx);
65
66 string arch = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
67 string arch2 = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432");
68 if (arch == "AMD64" || arch2 == "AMD64")
69 {
70 caDir = caDir.Replace("x86", "x64");
71
72 this.CreateCustomActionProduct(caProduct, caDir + caFile, customActions, true);
73
74 caughtEx = null;
75 try
76 {
77 Installer.InstallProduct(caProduct, String.Empty);
78 }
79 catch (Exception ex) { caughtEx = ex; }
80 Assert.IsInstanceOfType(caughtEx, typeof(InstallCanceledException),
81 "Exception thrown while installing 64bit product: " + caughtEx);
82 }
83 }
84 finally
85 {
86 Installer.SetExternalUI(prevHandler, InstallLogModes.None);
87 }
88 }
89
90 private void CreateCustomActionProduct(
91 string msiFile, string customActionFile, IList<string> customActions, bool sixtyFourBit)
92 {
93 using (Database db = new Database(msiFile, DatabaseOpenMode.CreateDirect))
94 {
95 WindowsInstallerUtils.InitializeProductDatabase(db, sixtyFourBit);
96 WindowsInstallerUtils.CreateTestProduct(db);
97
98 if (!File.Exists(customActionFile))
99 throw new FileNotFoundException(customActionFile);
100
101 using (Record binRec = new Record(2))
102 {
103 binRec[1] = Path.GetFileName(customActionFile);
104 binRec.SetStream(2, customActionFile);
105
106 db.Execute("INSERT INTO `Binary` (`Name`, `Data`) VALUES (?, ?)", binRec);
107 }
108
109 using (Record binRec2 = new Record(2))
110 {
111 binRec2[1] = "TestData";
112 binRec2.SetStream(2, new MemoryStream(Encoding.UTF8.GetBytes("This is a test data stream.")));
113
114 db.Execute("INSERT INTO `Binary` (`Name`, `Data`) VALUES (?, ?)", binRec2);
115 }
116
117 for (int i = 0; i < customActions.Count; i++)
118 {
119 db.Execute(
120 "INSERT INTO `CustomAction` (`Action`, `Type`, `Source`, `Target`) VALUES ('{0}', 1, '{1}', '{2}')",
121 customActions[i],
122 Path.GetFileName(customActionFile),
123 customActions[i]);
124 db.Execute(
125 "INSERT INTO `InstallExecuteSequence` (`Action`, `Condition`, `Sequence`) VALUES ('{0}', '', {1})",
126 customActions[i],
127 101 + i);
128 }
129
130 db.Execute("INSERT INTO `Property` (`Property`, `Value`) VALUES ('SampleCATest', 'TestValue')");
131
132 db.Commit();
133 }
134 }
135
136 [TestMethod]
137 public void CustomActionData()
138 {
139 string dataString = "Key1=Value1;Key2=;Key3;Key4=Value=4;Key5";
140 string dataString2 = "Key1=;Key2=Value2;Key3;Key4;Key6=Value;;6=6;Key7=Value7";
141
142 CustomActionData data = new CustomActionData(dataString);
143 Assert.AreEqual<string>(dataString, data.ToString());
144
145 data["Key1"] = String.Empty;
146 data["Key2"] = "Value2";
147 data["Key4"] = null;
148 data.Remove("Key5");
149 data["Key6"] = "Value;6=6";
150 data["Key7"] = "Value7";
151
152 Assert.AreEqual<string>(dataString2, data.ToString());
153
154 MyDataClass myData = new MyDataClass();
155 myData.Member1 = "test1";
156 myData.Member2 = "test2";
157 data.AddObject("MyData", myData);
158
159 string myDataString = data.ToString();
160 CustomActionData data2 = new CustomActionData(myDataString);
161
162 MyDataClass myData2 = data2.GetObject<MyDataClass>("MyData");
163 Assert.AreEqual<MyDataClass>(myData, myData2);
164
165 List<string> myComplexDataObject = new List<string>();
166 myComplexDataObject.Add("CValue1");
167 myComplexDataObject.Add("CValue2");
168 myComplexDataObject.Add("CValue3");
169
170 CustomActionData myComplexData = new CustomActionData();
171 myComplexData.AddObject("MyComplexData", myComplexDataObject);
172 myComplexData.AddObject("NestedData", data);
173 string myComplexDataString = myComplexData.ToString();
174
175 CustomActionData myComplexData2 = new CustomActionData(myComplexDataString);
176 List<string> myComplexDataObject2 = myComplexData2.GetObject<List<string>>("MyComplexData");
177
178 Assert.AreEqual<int>(myComplexDataObject.Count, myComplexDataObject2.Count);
179 for (int i = 0; i < myComplexDataObject.Count; i++)
180 {
181 Assert.AreEqual<string>(myComplexDataObject[i], myComplexDataObject2[i]);
182 }
183
184 data2 = myComplexData2.GetObject<CustomActionData>("NestedData");
185 Assert.AreEqual<string>(data.ToString(), data2.ToString());
186 }
187
188 public class MyDataClass
189 {
190 public string Member1;
191 public string Member2;
192
193 public override bool Equals(object obj)
194 {
195 MyDataClass other = obj as MyDataClass;
196 return other != null && this.Member1 == other.Member1 && this.Member2 == other.Member2;
197 }
198
199 public override int GetHashCode()
200 {
201 return (this.Member1 != null ? this.Member1.GetHashCode() : 0) ^
202 (this.Member2 != null ? this.Member2.GetHashCode() : 0);
203 }
204 }
205 }
206}
diff --git a/src/dtf/WixToolsetTests.Dtf.WindowsInstaller.CustomActions/WixToolsetTests.Dtf.WindowsInstaller.CustomActions.csproj b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller.CustomActions/WixToolsetTests.Dtf.WindowsInstaller.CustomActions.csproj
new file mode 100644
index 00000000..aadd4592
--- /dev/null
+++ b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller.CustomActions/WixToolsetTests.Dtf.WindowsInstaller.CustomActions.csproj
@@ -0,0 +1,28 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4
5<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
6 <PropertyGroup>
7 <ProjectGuid>{137D376B-989F-4FEA-9A67-01D8D38CA0DE}</ProjectGuid>
8 <OutputType>Library</OutputType>
9 <RootNamespace>WixToolsetTests.Dtf</RootNamespace>
10 <AssemblyName>WixToolsetTests.Dtf.WindowsInstaller.CustomActions</AssemblyName>
11 <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
12 <CreateDocumentation>false</CreateDocumentation>
13 </PropertyGroup>
14
15 <ItemGroup>
16 <Compile Include="CustomActionTest.cs" />
17 </ItemGroup>
18
19 <ItemGroup>
20 <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
21 <Reference Include="System" />
22 <Reference Include="System.Windows.Forms" />
23 <Reference Include="$(OutputPath)\WixToolset.Dtf.WindowsInstaller.dll" />
24 <ProjectReference Include="..\WixToolsetTests.Dtf.WindowsInstaller\WixToolsetTests.Dtf.WindowsInstaller.csproj" />
25 </ItemGroup>
26
27 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
28</Project>
diff --git a/src/dtf/WixToolsetTests.Dtf.WindowsInstaller.Linq/LinqTest.cs b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller.Linq/LinqTest.cs
new file mode 100644
index 00000000..7776a1c3
--- /dev/null
+++ b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller.Linq/LinqTest.cs
@@ -0,0 +1,509 @@
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
3using System;
4using System.Text;
5using System.Collections;
6using System.Collections.Generic;
7using System.Linq;
8using System.Linq.Expressions;
9using Microsoft.VisualStudio.TestTools.UnitTesting;
10using WixToolset.Dtf.WindowsInstaller;
11using WixToolset.Dtf.WindowsInstaller.Linq;
12
13namespace WixToolset.Dtf.Test
14{
15 [TestClass]
16 public class LinqTest
17 {
18 private void InitLinqTestDatabase(QDatabase db)
19 {
20 WindowsInstallerUtils.InitializeProductDatabase(db);
21 WindowsInstallerUtils.CreateTestProduct(db);
22
23 db.Execute(
24 "INSERT INTO `Feature` (`Feature`, `Title`, `Description`, `Level`, `Attributes`) VALUES ('{0}', '{1}', '{2}', {3}, {4})",
25 "TestFeature2",
26 "Test Feature 2",
27 "Test Feature 2 Description",
28 1,
29 (int) FeatureAttributes.None);
30
31 WindowsInstallerUtils.AddRegistryComponent(
32 db, "TestFeature2", "MyTestRegComp",
33 Guid.NewGuid().ToString("B"),
34 "SOFTWARE\\Microsoft\\DTF\\Test",
35 "MyTestRegComp", "test");
36 WindowsInstallerUtils.AddRegistryComponent(
37 db, "TestFeature2", "MyTestRegComp2",
38 Guid.NewGuid().ToString("B"),
39 "SOFTWARE\\Microsoft\\DTF\\Test",
40 "MyTestRegComp2", "test2");
41 WindowsInstallerUtils.AddRegistryComponent(
42 db, "TestFeature2", "excludeComp",
43 Guid.NewGuid().ToString("B"),
44 "SOFTWARE\\Microsoft\\DTF\\Test",
45 "MyTestRegComp3", "test3");
46
47 db.Commit();
48
49 db.Log = Console.Out;
50 }
51
52 [TestMethod]
53 public void LinqSimple()
54 {
55 using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create))
56 {
57 this.InitLinqTestDatabase(db);
58
59 var comps = from c in db.Components
60 select c;
61
62 int count = 0;
63 foreach (var c in comps)
64 {
65 Console.WriteLine(c);
66 count++;
67 }
68
69 Assert.AreEqual<int>(4, count);
70 }
71 }
72
73 [TestMethod]
74 public void LinqWhereNull()
75 {
76 using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create))
77 {
78 this.InitLinqTestDatabase(db);
79
80 var features = from f in db.Features
81 where f.Description != null
82 select f;
83
84 int count = 0;
85 foreach (var f in features)
86 {
87 Console.WriteLine(f);
88 Assert.AreEqual<string>("TestFeature2", f.Feature);
89 count++;
90 }
91
92 Assert.AreEqual<int>(1, count);
93
94 var features2 = from f in db.Features
95 where f.Description == null
96 select f;
97
98 count = 0;
99 foreach (var f in features2)
100 {
101 Console.WriteLine(f);
102 Assert.AreEqual<string>("TestFeature1", f.Feature);
103 count++;
104 }
105
106 Assert.AreEqual<int>(1, count);
107 }
108 }
109
110 [TestMethod]
111 public void LinqWhereOperators()
112 {
113 using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create))
114 {
115 this.InitLinqTestDatabase(db);
116
117 for (int i = 0; i < 100; i++)
118 {
119 var newFile = db.Files.NewRecord();
120 newFile.File = "TestFile" + i;
121 newFile.Component_ = "TestComponent";
122 newFile.FileName = "TestFile" + i + ".txt";
123 newFile.FileSize = i % 10;
124 newFile.Sequence = i;
125 newFile.Insert();
126 }
127
128 var files1 = from f in db.Files where f.Sequence < 40 select f;
129 Assert.AreEqual<int>(40, files1.AsEnumerable().Count());
130
131 var files2 = from f in db.Files where f.Sequence <= 40 select f;
132 Assert.AreEqual<int>(41, files2.AsEnumerable().Count());
133
134 var files3 = from f in db.Files where f.Sequence > 40 select f;
135 Assert.AreEqual<int>(59, files3.AsEnumerable().Count());
136
137 var files4 = from f in db.Files where f.Sequence >= 40 select f;
138 Assert.AreEqual<int>(60, files4.AsEnumerable().Count());
139
140 var files5 = from f in db.Files where 40 < f.Sequence select f;
141 Assert.AreEqual<int>(59, files5.AsEnumerable().Count());
142
143 var files6 = from f in db.Files where 40 <= f.Sequence select f;
144 Assert.AreEqual<int>(60, files6.AsEnumerable().Count());
145
146 var files7 = from f in db.Files where 40 > f.Sequence select f;
147 Assert.AreEqual<int>(40, files7.AsEnumerable().Count());
148
149 var files8 = from f in db.Files where 40 >= f.Sequence select f;
150 Assert.AreEqual<int>(41, files8.AsEnumerable().Count());
151
152 var files9 = from f in db.Files where f.Sequence == 40 select f;
153 Assert.AreEqual<int>(40, files9.AsEnumerable().First().Sequence);
154
155 var files10 = from f in db.Files where f.Sequence != 40 select f;
156 Assert.AreEqual<int>(99, files10.AsEnumerable().Count());
157
158 var files11 = from f in db.Files where 40 == f.Sequence select f;
159 Assert.AreEqual<int>(40, files11.AsEnumerable().First().Sequence);
160
161 var files12 = from f in db.Files where 40 != f.Sequence select f;
162 Assert.AreEqual<int>(99, files12.AsEnumerable().Count());
163 }
164 }
165
166 [TestMethod]
167 public void LinqShapeSelect()
168 {
169 using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create))
170 {
171 this.InitLinqTestDatabase(db);
172
173 Console.WriteLine("Running LINQ query 1.");
174 var features1 = from f in db.Features
175 select new { Name = f.Feature,
176 Desc = f.Description };
177
178 int count = 0;
179 foreach (var f in features1)
180 {
181 Console.WriteLine(f);
182 count++;
183 }
184
185 Assert.AreEqual<int>(2, count);
186
187 Console.WriteLine();
188 Console.WriteLine("Running LINQ query 2.");
189 var features2 = from f in db.Features
190 where f.Description != null
191 select new { Name = f.Feature,
192 Desc = f.Description.ToLower() };
193
194 count = 0;
195 foreach (var f in features2)
196 {
197 Console.WriteLine(f);
198 Assert.AreEqual<string>("TestFeature2", f.Name);
199 count++;
200 }
201
202 Assert.AreEqual<int>(1, count);
203 }
204 }
205
206 [TestMethod]
207 public void LinqUpdateNullableString()
208 {
209 using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create))
210 {
211 this.InitLinqTestDatabase(db);
212
213 string newDescription = "New updated feature description.";
214
215 var features = from f in db.Features
216 where f.Description != null
217 select f;
218
219 int count = 0;
220 foreach (var f in features)
221 {
222 Console.WriteLine(f);
223 Assert.AreEqual<string>("TestFeature2", f.Feature);
224 f.Description = newDescription;
225 count++;
226 }
227
228 Assert.AreEqual<int>(1, count);
229
230 var features2 = from f in db.Features
231 where f.Description == newDescription
232 select f;
233 count = 0;
234 foreach (var f in features2)
235 {
236 Console.WriteLine(f);
237 Assert.AreEqual<string>("TestFeature2", f.Feature);
238 f.Description = null;
239 count++;
240 }
241
242 Assert.AreEqual<int>(1, count);
243
244 var features3 = from f in db.Features
245 where f.Description == null
246 select f.Feature;
247 count = 0;
248 foreach (var f in features3)
249 {
250 Console.WriteLine(f);
251 count++;
252 }
253
254 Assert.AreEqual<int>(2, count);
255
256 db.Commit();
257 }
258 }
259
260 [TestMethod]
261 public void LinqInsertDelete()
262 {
263 using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create))
264 {
265 this.InitLinqTestDatabase(db);
266
267 var newProp = db.Properties.NewRecord();
268 newProp.Property = "TestNewProp1";
269 newProp.Value = "TestNewValue";
270 newProp.Insert();
271
272 string prop = (from p in db.Properties
273 where p.Property == "TestNewProp1"
274 select p.Value).AsEnumerable().First();
275 Assert.AreEqual<string>("TestNewValue", prop);
276
277 newProp.Delete();
278
279 int propCount = (from p in db.Properties
280 where p.Property == "TestNewProp1"
281 select p.Value).AsEnumerable().Count();
282 Assert.AreEqual<int>(0, propCount);
283
284 db.Commit();
285 }
286 }
287
288 [TestMethod]
289 public void LinqQueryQRecord()
290 {
291 using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create))
292 {
293 this.InitLinqTestDatabase(db);
294
295 var installFilesSeq = (from a in db["InstallExecuteSequence"]
296 where a["Action"] == "InstallFiles"
297 select a["Sequence"]).AsEnumerable().First();
298 Assert.AreEqual<string>("4000", installFilesSeq);
299 }
300 }
301
302 [TestMethod]
303 public void LinqOrderBy()
304 {
305 using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create))
306 {
307 this.InitLinqTestDatabase(db);
308
309 var actions = from a in db.InstallExecuteSequences
310 orderby a.Sequence
311 select a.Action;
312 foreach (var a in actions)
313 {
314 Console.WriteLine(a);
315 }
316
317 var files = from f in db.Files
318 orderby f.FileSize, f["Sequence"]
319 where f.Attributes == FileAttributes.None
320 select f;
321
322 foreach (var f in files)
323 {
324 Console.WriteLine(f);
325 }
326 }
327 }
328
329 [TestMethod]
330 public void LinqTwoWayJoin()
331 {
332 using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create))
333 {
334 this.InitLinqTestDatabase(db);
335 int count;
336
337 var regs = from r in db.Registries
338 join c in db["Component"] on r.Component_ equals c["Component"]
339 where c["Component"] == "MyTestRegComp" &&
340 r.Root == RegistryRoot.UserOrMachine
341 select new { Reg = r.Registry, Dir = c["Directory_"] };
342
343 count = 0;
344 foreach (var r in regs)
345 {
346 Console.WriteLine(r);
347 count++;
348 }
349 Assert.AreEqual<int>(1, count);
350
351 var regs2 = from r in db.Registries
352 join c in db.Components on r.Component_ equals c.Component
353 where c.Component == "MyTestRegComp" &&
354 r.Root == RegistryRoot.UserOrMachine
355 select new { Reg = r, Dir = c.Directory_ };
356
357 count = 0;
358 foreach (var r in regs2)
359 {
360 Assert.IsNotNull(r.Reg.Registry);
361 Console.WriteLine(r);
362 count++;
363 }
364 Assert.AreEqual<int>(1, count);
365
366 var regs3 = from r in db.Registries
367 join c in db.Components on r.Component_ equals c.Component
368 where c.Component == "MyTestRegComp" &&
369 r.Root == RegistryRoot.UserOrMachine
370 select r;
371
372 count = 0;
373 foreach (var r in regs3)
374 {
375 Assert.IsNotNull(r.Registry);
376 Console.WriteLine(r);
377 count++;
378 }
379 Assert.AreEqual<int>(1, count);
380
381 }
382 }
383
384 [TestMethod]
385 public void LinqFourWayJoin()
386 {
387 using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create))
388 {
389 this.InitLinqTestDatabase(db);
390 int count;
391
392 IList<string> pretest = db.ExecuteStringQuery(
393 "SELECT `Feature`.`Feature` " +
394 "FROM `Feature`, `FeatureComponents`, `Component`, `Registry` " +
395 "WHERE `Feature`.`Feature` = `FeatureComponents`.`Feature_` " +
396 "AND `FeatureComponents`.`Component_` = `Component`.`Component` " +
397 "AND `Component`.`Component` = `Registry`.`Component_` " +
398 "AND (`Registry`.`Registry` = 'MyTestRegCompReg1')");
399 Assert.AreEqual<int>(1, pretest.Count);
400
401 var features = from f in db.Features
402 join fc in db.FeatureComponents on f.Feature equals fc.Feature_
403 join c in db.Components on fc.Component_ equals c.Component
404 join r in db.Registries on c.Component equals r.Component_
405 where r.Registry == "MyTestRegCompReg1"
406 select f.Feature;
407
408 count = 0;
409 foreach (var featureName in features)
410 {
411 Console.WriteLine(featureName);
412 count++;
413 }
414 Assert.AreEqual<int>(1, count);
415
416 }
417 }
418
419 [TestMethod]
420 public void EnumTable()
421 {
422 using (QDatabase db = new QDatabase("testlinq.msi", DatabaseOpenMode.Create))
423 {
424 this.InitLinqTestDatabase(db);
425 int count = 0;
426 foreach (var comp in db.Components)
427 {
428 Console.WriteLine(comp);
429 count++;
430 }
431 Assert.AreNotEqual<int>(0, count);
432 }
433 }
434
435 [TestMethod]
436 public void DatabaseAsQueryable()
437 {
438 using (Database db = new Database("testlinq.msi", DatabaseOpenMode.Create))
439 {
440 WindowsInstallerUtils.InitializeProductDatabase(db);
441 WindowsInstallerUtils.CreateTestProduct(db);
442
443 var comps = from c in db.AsQueryable().Components
444 select c;
445
446 int count = 0;
447 foreach (var c in comps)
448 {
449 Console.WriteLine(c);
450 count++;
451 }
452
453 Assert.AreEqual<int>(1, count);
454 }
455 }
456
457 [TestMethod]
458 public void EnumProducts()
459 {
460 var products = from p in ProductInstallation.AllProducts
461 where p.Publisher == ".NET Foundation"
462 select new { Name = p.ProductName,
463 Ver = p.ProductVersion,
464 Company = p.Publisher,
465 InstallDate = p.InstallDate,
466 PackageCode = p.AdvertisedPackageCode };
467
468 foreach (var p in products)
469 {
470 Console.WriteLine(p);
471 Assert.IsTrue(p.Company == ".NET Foundation");
472 }
473 }
474
475 [TestMethod]
476 public void EnumFeatures()
477 {
478 foreach (var p in ProductInstallation.AllProducts)
479 {
480 Console.WriteLine(p.ProductName);
481
482 foreach (var f in p.Features)
483 {
484 Console.WriteLine("\t" + f.FeatureName);
485 }
486 }
487 }
488
489 [TestMethod]
490 public void EnumComponents()
491 {
492 var comps = from c in ComponentInstallation.AllComponents
493 where c.State == InstallState.Local &&
494 c.Product.Publisher == ".NET Foundation"
495 select c.Path;
496
497 int count = 0;
498 foreach (var c in comps)
499 {
500 if (++count == 100) break;
501
502 Console.WriteLine(c);
503 }
504
505 Assert.AreEqual<int>(100, count);
506 }
507 }
508
509}
diff --git a/src/dtf/WixToolsetTests.Dtf.WindowsInstaller.Linq/WixToolsetTests.Dtf.WindowsInstaller.Linq.csproj b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller.Linq/WixToolsetTests.Dtf.WindowsInstaller.Linq.csproj
new file mode 100644
index 00000000..0dc90860
--- /dev/null
+++ b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller.Linq/WixToolsetTests.Dtf.WindowsInstaller.Linq.csproj
@@ -0,0 +1,31 @@
1<?xml version="1.0" encoding="utf-8" ?>
2<!-- 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. -->
3
4<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
5 <PropertyGroup>
6 <ProjectGuid>{4F55F9B8-D8B6-41EB-8796-221B4CD98324}</ProjectGuid>
7 <OutputType>Library</OutputType>
8 <RootNamespace>WixToolsetTests.Dtf</RootNamespace>
9 <AssemblyName>WixToolsetTests.Dtf.Linq</AssemblyName>
10 <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
11 <CreateDocumentation>false</CreateDocumentation>
12 </PropertyGroup>
13
14 <ItemGroup>
15 <Compile Include="LinqTest.cs" />
16 </ItemGroup>
17
18 <ItemGroup>
19 <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
20 <Reference Include="System" />
21 <Reference Include="System.Core" />
22 </ItemGroup>
23
24 <ItemGroup>
25 <ProjectReference Include="..\WixToolset.Dtf.WindowsInstaller\WixToolset.Dtf.WindowsInstaller.csproj" />
26 <ProjectReference Include="..\WixToolset.Dtf.WindowsInstaller.Linq\WixToolset.Dtf.WindowsInstaller.Linq.csproj" />
27 <ProjectReference Include="..\WixToolsetTests.Dtf.WindowsInstaller\WixToolsetTests.Dtf.WindowsInstaller.csproj" />
28 </ItemGroup>
29
30 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
31</Project>
diff --git a/src/dtf/WixToolsetTests.Dtf.WindowsInstaller/EmbeddedExternalUI.cs b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller/EmbeddedExternalUI.cs
new file mode 100644
index 00000000..b0fc00a8
--- /dev/null
+++ b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller/EmbeddedExternalUI.cs
@@ -0,0 +1,173 @@
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
3namespace WixToolset.Dtf.Test
4{
5 using System;
6 using System.IO;
7 using System.Reflection;
8 using System.Windows.Forms;
9 using System.Globalization;
10 using System.Collections.Generic;
11 using Microsoft.VisualStudio.TestTools.UnitTesting;
12 using WixToolset.Dtf.WindowsInstaller;
13 using View = WixToolset.Dtf.WindowsInstaller.View;
14
15 [TestClass]
16 public class EmbeddedExternalUI
17 {
18 const InstallLogModes TestLogModes =
19 InstallLogModes.FatalExit |
20 InstallLogModes.Error |
21 InstallLogModes.Warning |
22 InstallLogModes.User |
23 InstallLogModes.Info |
24 InstallLogModes.ResolveSource |
25 InstallLogModes.OutOfDiskSpace |
26 InstallLogModes.ActionStart |
27 InstallLogModes.ActionData |
28 InstallLogModes.CommonData;
29
30#if DEBUG
31 const string EmbeddedUISampleBinDir = @"..\..\build\debug\";
32#else
33 const string EmbeddedUISampleBinDir = @"..\..\build\release\";
34#endif
35
36 [TestMethod]
37 [Ignore] // Requires elevation.
38 public void EmbeddedUISingleInstall()
39 {
40 string dbFile = "EmbeddedUISingleInstall.msi";
41 string productCode;
42
43 string uiDir = Path.GetFullPath(EmbeddedExternalUI.EmbeddedUISampleBinDir);
44 string uiFile = "WixToolset.Dtf.Samples.EmbeddedUI.dll";
45
46 using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect))
47 {
48 WindowsInstallerUtils.InitializeProductDatabase(db);
49 WindowsInstallerUtils.CreateTestProduct(db);
50
51 productCode = db.ExecuteStringQuery("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")[0];
52
53 using (Record uiRec = new Record(5))
54 {
55 uiRec[1] = "TestEmbeddedUI";
56 uiRec[2] = Path.GetFileNameWithoutExtension(uiFile) + ".Wrapper.dll";
57 uiRec[3] = 1;
58 uiRec[4] = (int) (
59 EmbeddedExternalUI.TestLogModes |
60 InstallLogModes.Progress |
61 InstallLogModes.Initialize |
62 InstallLogModes.Terminate |
63 InstallLogModes.ShowDialog);
64 uiRec.SetStream(5, Path.Combine(uiDir, uiFile));
65 db.Execute(db.Tables["MsiEmbeddedUI"].SqlInsertString, uiRec);
66 }
67
68 db.Commit();
69 }
70
71 Installer.SetInternalUI(InstallUIOptions.Full);
72
73 ProductInstallation installation = new ProductInstallation(productCode);
74 Assert.IsFalse(installation.IsInstalled, "Checking that product is not installed before starting.");
75
76 Exception caughtEx = null;
77 try
78 {
79 Installer.EnableLog(EmbeddedExternalUI.TestLogModes, "install.log");
80 Installer.InstallProduct(dbFile, String.Empty);
81 }
82 catch (Exception ex) { caughtEx = ex; }
83 Assert.IsNull(caughtEx, "Exception thrown while installing product: " + caughtEx);
84
85 Assert.IsTrue(installation.IsInstalled, "Checking that product is installed.");
86 Console.WriteLine();
87 Console.WriteLine();
88 Console.WriteLine();
89 Console.WriteLine("===================================================================");
90 Console.WriteLine();
91 Console.WriteLine();
92 Console.WriteLine();
93
94 try
95 {
96 Installer.EnableLog(EmbeddedExternalUI.TestLogModes, "uninstall.log");
97 Installer.InstallProduct(dbFile, "REMOVE=All");
98 }
99 catch (Exception ex) { caughtEx = ex; }
100 Assert.IsNull(caughtEx, "Exception thrown while uninstalling product: " + caughtEx);
101 }
102
103 // This test does not pass if run normally.
104 // It only passes when a failure is injected into the EmbeddedUI launcher.
105 ////[TestMethod]
106 public void EmbeddedUIInitializeFails()
107 {
108 string dbFile = "EmbeddedUIInitializeFails.msi";
109 string productCode;
110
111 string uiDir = Path.GetFullPath(EmbeddedExternalUI.EmbeddedUISampleBinDir);
112 string uiFile = "WixToolset.Dtf.Samples.EmbeddedUI.dll";
113
114 // A number that will be used to check whether a type 19 CA runs.
115 const string magicNumber = "3.14159265358979323846264338327950";
116
117 using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect))
118 {
119 WindowsInstallerUtils.InitializeProductDatabase(db);
120 WindowsInstallerUtils.CreateTestProduct(db);
121
122 const string failureActionName = "EmbeddedUIInitializeFails";
123 db.Execute("INSERT INTO `CustomAction` (`Action`, `Type`, `Source`, `Target`) " +
124 "VALUES ('{0}', 19, '', 'Logging magic number: {1}')", failureActionName, magicNumber);
125
126 // This type 19 CA (launch condition) is given a condition of 'UILevel = 3' so that it only runs if the
127 // installation is running in BASIC UI mode, which is what we expect if the EmbeddedUI fails to initialize.
128 db.Execute("INSERT INTO `InstallExecuteSequence` (`Action`, `Condition`, `Sequence`) " +
129 "VALUES ('{0}', 'UILevel = 3', 1)", failureActionName);
130
131 productCode = db.ExecuteStringQuery("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")[0];
132
133 using (Record uiRec = new Record(5))
134 {
135 uiRec[1] = "TestEmbeddedUI";
136 uiRec[2] = Path.GetFileNameWithoutExtension(uiFile) + ".Wrapper.dll";
137 uiRec[3] = 1;
138 uiRec[4] = (int)(
139 EmbeddedExternalUI.TestLogModes |
140 InstallLogModes.Progress |
141 InstallLogModes.Initialize |
142 InstallLogModes.Terminate |
143 InstallLogModes.ShowDialog);
144 uiRec.SetStream(5, Path.Combine(uiDir, uiFile));
145 db.Execute(db.Tables["MsiEmbeddedUI"].SqlInsertString, uiRec);
146 }
147
148 db.Commit();
149 }
150
151 Installer.SetInternalUI(InstallUIOptions.Full);
152
153 ProductInstallation installation = new ProductInstallation(productCode);
154 Assert.IsFalse(installation.IsInstalled, "Checking that product is not installed before starting.");
155
156 string logFile = "install.log";
157 Exception caughtEx = null;
158 try
159 {
160 Installer.EnableLog(EmbeddedExternalUI.TestLogModes, logFile);
161 Installer.InstallProduct(dbFile, String.Empty);
162 }
163 catch (Exception ex) { caughtEx = ex; }
164 Assert.IsInstanceOfType(caughtEx, typeof(InstallerException),
165 "Excpected InstallerException installing product; caught: " + caughtEx);
166
167 Assert.IsFalse(installation.IsInstalled, "Checking that product is not installed.");
168
169 string logText = File.ReadAllText(logFile);
170 Assert.IsTrue(logText.Contains(magicNumber), "Checking that the type 19 custom action ran.");
171 }
172 }
173}
diff --git a/src/dtf/WixToolsetTests.Dtf.WindowsInstaller/Schema.cs b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller/Schema.cs
new file mode 100644
index 00000000..26c172c9
--- /dev/null
+++ b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller/Schema.cs
@@ -0,0 +1,238 @@
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
3namespace WixToolset.Dtf.Test
4{
5 using System;
6 using System.IO;
7 using System.Collections.Generic;
8 using System.Text;
9 using WixToolset.Dtf.WindowsInstaller;
10
11 public static class Schema
12 {
13 public static IList<TableInfo> Tables
14 {
15 get
16 {
17 return new TableInfo[]
18 {
19 Binary,
20 Component,
21 CustomAction,
22 Directory,
23 EmbeddedUI,
24 Feature,
25 FeatureComponents,
26 File,
27 InstallExecuteSequence,
28 Media,
29 Property,
30 Registry
31 };
32 }
33 }
34
35 #region Table data
36
37 public static TableInfo Binary { get { return new TableInfo(
38 "Binary",
39 new ColumnInfo[]
40 {
41 new ColumnInfo("Name", typeof(String), 72, true),
42 new ColumnInfo("Data", typeof(Stream), 0, true),
43 },
44 new string[] { "Name" });
45 } }
46
47 public static TableInfo Component { get { return new TableInfo(
48 "Component",
49 new ColumnInfo[]
50 {
51 new ColumnInfo("Component", typeof(String), 72, true),
52 new ColumnInfo("ComponentId", typeof(String), 38, false),
53 new ColumnInfo("Directory_", typeof(String), 72, true),
54 new ColumnInfo("Attributes", typeof(Int16), 2, true),
55 new ColumnInfo("Condition", typeof(String), 255, false),
56 new ColumnInfo("KeyPath", typeof(String), 72, false),
57 },
58 new string[] { "Component" });
59 } }
60
61 public static TableInfo CustomAction { get { return new TableInfo(
62 "CustomAction",
63 new ColumnInfo[]
64 {
65 new ColumnInfo("Action", typeof(String), 72, true),
66 new ColumnInfo("Type", typeof(Int16), 2, true),
67 new ColumnInfo("Source", typeof(String), 64, false),
68 new ColumnInfo("Target", typeof(String), 255, false),
69 },
70 new string[] { "Action" });
71 } }
72
73 public static TableInfo Directory { get { return new TableInfo(
74 "Directory",
75 new ColumnInfo[]
76 {
77 new ColumnInfo("Directory", typeof(String), 72, true),
78 new ColumnInfo("Directory_Parent", typeof(String), 72, false),
79 new ColumnInfo("DefaultDir", typeof(String), 255, true, false, true),
80 },
81 new string[] { "Directory" });
82 } }
83
84 public static TableInfo EmbeddedUI { get { return new TableInfo(
85 "MsiEmbeddedUI",
86 new ColumnInfo[]
87 {
88 new ColumnInfo("MsiEmbeddedUI", typeof(String), 72, true),
89 new ColumnInfo("FileName", typeof(String), 72, true),
90 new ColumnInfo("Attributes", typeof(Int16), 2, true),
91 new ColumnInfo("MessageFilter", typeof(Int32), 4, false),
92 new ColumnInfo("Data", typeof(Stream), 0, true),
93 },
94 new string[] { "MsiEmbeddedUI" });
95 } }
96
97 public static TableInfo Feature { get { return new TableInfo(
98 "Feature",
99 new ColumnInfo[]
100 {
101 new ColumnInfo("Feature", typeof(String), 38, true),
102 new ColumnInfo("Feature_Parent", typeof(String), 38, false),
103 new ColumnInfo("Title", typeof(String), 64, false, false, true),
104 new ColumnInfo("Description", typeof(String), 64, false, false, true),
105 new ColumnInfo("Display", typeof(Int16), 2, false),
106 new ColumnInfo("Level", typeof(Int16), 2, true),
107 new ColumnInfo("Directory_", typeof(String), 72, false),
108 new ColumnInfo("Attributes", typeof(Int16), 2, true),
109 },
110 new string[] { "Feature" });
111 } }
112
113 public static TableInfo FeatureComponents { get { return new TableInfo(
114 "FeatureComponents",
115 new ColumnInfo[]
116 {
117 new ColumnInfo("Feature_", typeof(String), 38, true),
118 new ColumnInfo("Component_", typeof(String), 72, true),
119 },
120 new string[] { "Feature_", "Component_" });
121 } }
122
123 public static TableInfo File { get { return new TableInfo(
124 "File",
125 new ColumnInfo[]
126 {
127 new ColumnInfo("File", typeof(String), 72, true),
128 new ColumnInfo("Component_", typeof(String), 72, true),
129 new ColumnInfo("FileName", typeof(String), 255, true, false, true),
130 new ColumnInfo("FileSize", typeof(Int32), 4, true),
131 new ColumnInfo("Version", typeof(String), 72, false),
132 new ColumnInfo("Language", typeof(String), 20, false),
133 new ColumnInfo("Attributes", typeof(Int16), 2, false),
134 new ColumnInfo("Sequence", typeof(Int16), 2, true),
135 },
136 new string[] { "File" });
137 } }
138
139 public static TableInfo InstallExecuteSequence { get { return new TableInfo(
140 "InstallExecuteSequence",
141 new ColumnInfo[]
142 {
143 new ColumnInfo("Action", typeof(String), 72, true),
144 new ColumnInfo("Condition", typeof(String), 255, false),
145 new ColumnInfo("Sequence", typeof(Int16), 2, true),
146 },
147 new string[] { "Action" });
148 } }
149
150 public static TableInfo Media { get { return new TableInfo(
151 "Media",
152 new ColumnInfo[]
153 {
154 new ColumnInfo("DiskId", typeof(Int16), 2, true),
155 new ColumnInfo("LastSequence", typeof(Int16), 2, true),
156 new ColumnInfo("DiskPrompt", typeof(String), 64, false, false, true),
157 new ColumnInfo("Cabinet", typeof(String), 255, false),
158 new ColumnInfo("VolumeLabel", typeof(String), 32, false),
159 new ColumnInfo("Source", typeof(String), 32, false),
160 },
161 new string[] { "DiskId" });
162 } }
163
164 public static TableInfo Property { get { return new TableInfo(
165 "Property",
166 new ColumnInfo[]
167 {
168 new ColumnInfo("Property", typeof(String), 72, true),
169 new ColumnInfo("Value", typeof(String), 255, true),
170 },
171 new string[] { "Property" });
172 } }
173
174 public static TableInfo Registry { get { return new TableInfo(
175 "Registry",
176 new ColumnInfo[]
177 {
178 new ColumnInfo("Registry", typeof(String), 72, true),
179 new ColumnInfo("Root", typeof(Int16), 2, true),
180 new ColumnInfo("Key", typeof(String), 255, true, false, true),
181 new ColumnInfo("Name", typeof(String), 255, false, false, true),
182 new ColumnInfo("Value", typeof(String), 0, false, false, true),
183 new ColumnInfo("Component_", typeof(String), 72, true),
184 },
185 new string[] { "Registry" });
186 } }
187
188 #endregion
189
190 }
191
192 public class Action
193 {
194 public readonly string Name;
195 public readonly int Sequence;
196
197 public Action(string name, int sequence)
198 {
199 this.Name = name;
200 this.Sequence = sequence;
201 }
202
203 }
204
205 public class Sequence
206 {
207 public static IList<Action> InstallExecute
208 {
209 get
210 {
211 return new Action[]
212 {
213 new Action("CostInitialize", 800),
214 new Action("FileCost", 900),
215 new Action("CostFinalize", 1000),
216 new Action("InstallValidate", 1400),
217 new Action("InstallInitialize", 1500),
218 new Action("ProcessComponents", 1600),
219 new Action("UnpublishComponents", 1700),
220 new Action("UnpublishFeatures", 1800),
221 new Action("RemoveRegistryValues", 2600),
222 new Action("RemoveFiles", 3500),
223 new Action("RemoveFolders", 3600),
224 new Action("CreateFolders", 3700),
225 new Action("MoveFiles", 3800),
226 new Action("InstallFiles", 4000),
227 new Action("WriteRegistryValues", 5000),
228 new Action("RegisterProduct", 6100),
229 new Action("PublishComponents", 6200),
230 new Action("PublishFeatures", 6300),
231 new Action("PublishProduct", 6400),
232 new Action("InstallFinalize", 6600),
233 };
234 }
235 }
236
237 }
238}
diff --git a/src/dtf/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTest.cs b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTest.cs
new file mode 100644
index 00000000..f994dfef
--- /dev/null
+++ b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTest.cs
@@ -0,0 +1,409 @@
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
3namespace WixToolset.Dtf.Test
4{
5 using System;
6 using System.IO;
7 using System.Windows.Forms;
8 using System.Globalization;
9 using System.Collections.Generic;
10 using Microsoft.VisualStudio.TestTools.UnitTesting;
11 using WixToolset.Dtf.WindowsInstaller;
12 using View = WixToolset.Dtf.WindowsInstaller.View;
13
14 [TestClass]
15 public class WindowsInstallerTest
16 {
17 public WindowsInstallerTest()
18 {
19 }
20
21 [TestInitialize()]
22 public void Initialize()
23 {
24 }
25
26 [TestCleanup()]
27 public void Cleanup()
28 {
29 }
30
31 [TestMethod]
32 [Ignore] // Currently fails.
33 public void InstallerErrorMessages()
34 {
35 string msg3002 = Installer.GetErrorMessage(3002);
36 Console.WriteLine("3002=" + msg3002);
37 Assert.IsNotNull(msg3002);
38 Assert.IsTrue(msg3002.Length > 0);
39 }
40
41 [TestMethod]
42 public void InstallerDatabaseSchema()
43 {
44 string dbFile = "InstallerDatabaseSchema.msi";
45
46 using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect))
47 {
48 WindowsInstallerUtils.InitializeProductDatabase(db);
49 db.Commit();
50 }
51
52 Assert.IsTrue(File.Exists(dbFile), "Checking whether created database file " + dbFile + " exists.");
53
54 using (Database db = new Database(dbFile, DatabaseOpenMode.ReadOnly))
55 {
56 TableCollection tables = db.Tables;
57 Assert.AreEqual<int>(Schema.Tables.Count, tables.Count, "Counting tables.");
58 Assert.AreEqual<int>(Schema.Property.Columns.Count, tables["Property"].Columns.Count, "Counting columns in Property table.");
59
60 foreach (TableInfo tableInfo in tables)
61 {
62 Console.WriteLine(tableInfo.Name);
63 foreach (ColumnInfo columnInfo in tableInfo.Columns)
64 {
65 Console.WriteLine("\t{0} {1}", columnInfo.Name, columnInfo.ColumnDefinitionString);
66 }
67 }
68 }
69 }
70
71 [TestMethod]
72 public void InstallerViewTables()
73 {
74 string dbFile = "InstallerViewTables.msi";
75
76 using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect))
77 {
78 WindowsInstallerUtils.InitializeProductDatabase(db);
79 db.Commit();
80
81 using (View view1 = db.OpenView("SELECT `Property`, `Value` FROM `Property` WHERE `Value` IS NOT NULL"))
82 {
83 IList<TableInfo> viewTables = view1.Tables;
84 Assert.IsNotNull(viewTables);
85 Assert.AreEqual<int>(1, viewTables.Count);
86 Assert.AreEqual<String>("Property", viewTables[0].Name);
87 }
88
89 using (View view2 = db.OpenView("INSERT INTO `Property` (`Property`, `Value`) VALUES ('TestViewTables', 1)"))
90 {
91 IList<TableInfo> viewTables = view2.Tables;
92 Assert.IsNotNull(viewTables);
93 Assert.AreEqual<int>(1, viewTables.Count);
94 Assert.AreEqual<String>("Property", viewTables[0].Name);
95 }
96
97 using (View view3 = db.OpenView("UPDATE `Property` SET `Value` = 2 WHERE `Property` = 'TestViewTables'"))
98 {
99 IList<TableInfo> viewTables = view3.Tables;
100 Assert.IsNotNull(viewTables);
101 Assert.AreEqual<int>(1, viewTables.Count);
102 Assert.AreEqual<String>("Property", viewTables[0].Name);
103 }
104
105 using (View view4 = db.OpenView("alter table Property hold"))
106 {
107 IList<TableInfo> viewTables = view4.Tables;
108 Assert.IsNotNull(viewTables);
109 Assert.AreEqual<int>(1, viewTables.Count);
110 Assert.AreEqual<String>("Property", viewTables[0].Name);
111 }
112 }
113 }
114
115 [TestMethod]
116 public void InstallerInstallProduct()
117 {
118 string dbFile = "InstallerInstallProduct.msi";
119 string productCode;
120
121 using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect))
122 {
123 WindowsInstallerUtils.InitializeProductDatabase(db);
124 WindowsInstallerUtils.CreateTestProduct(db);
125
126 productCode = db.ExecuteStringQuery("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")[0];
127
128 db.Commit();
129 }
130
131 ProductInstallation installation = new ProductInstallation(productCode);
132 Assert.IsFalse(installation.IsInstalled, "Checking that product is not installed before starting.");
133
134 Installer.SetInternalUI(InstallUIOptions.Silent);
135 ExternalUIHandler prevHandler = Installer.SetExternalUI(WindowsInstallerTest.ExternalUILogger,
136 InstallLogModes.FatalExit |
137 InstallLogModes.Error |
138 InstallLogModes.Warning |
139 InstallLogModes.User |
140 InstallLogModes.Info |
141 InstallLogModes.ResolveSource |
142 InstallLogModes.OutOfDiskSpace |
143 InstallLogModes.ActionStart |
144 InstallLogModes.ActionData |
145 InstallLogModes.CommonData |
146 InstallLogModes.Progress |
147 InstallLogModes.Initialize |
148 InstallLogModes.Terminate |
149 InstallLogModes.ShowDialog);
150 Assert.IsNull(prevHandler, "Checking that returned previous UI handler is null.");
151
152 Exception caughtEx = null;
153 try
154 {
155 Installer.InstallProduct(dbFile, String.Empty);
156 }
157 catch (Exception ex) { caughtEx = ex; }
158 Assert.IsNull(caughtEx, "Exception thrown while installing product: " + caughtEx);
159
160 prevHandler = Installer.SetExternalUI(prevHandler, InstallLogModes.None);
161 Assert.AreEqual<ExternalUIHandler>(WindowsInstallerTest.ExternalUILogger, prevHandler, "Checking that previously-set UI handler is returned.");
162
163 Assert.IsTrue(installation.IsInstalled, "Checking that product is installed.");
164 Console.WriteLine();
165 Console.WriteLine();
166 Console.WriteLine();
167 Console.WriteLine("===================================================================");
168 Console.WriteLine();
169 Console.WriteLine();
170 Console.WriteLine();
171
172 ExternalUIRecordHandler prevRecHandler = Installer.SetExternalUI(WindowsInstallerTest.ExternalUIRecordLogger,
173 InstallLogModes.FatalExit |
174 InstallLogModes.Error |
175 InstallLogModes.Warning |
176 InstallLogModes.User |
177 InstallLogModes.Info |
178 InstallLogModes.ResolveSource |
179 InstallLogModes.OutOfDiskSpace |
180 InstallLogModes.ActionStart |
181 InstallLogModes.ActionData |
182 InstallLogModes.CommonData |
183 InstallLogModes.Progress |
184 InstallLogModes.Initialize |
185 InstallLogModes.Terminate |
186 InstallLogModes.ShowDialog);
187 Assert.IsNull(prevRecHandler, "Checking that returned previous UI record handler is null.");
188
189 try
190 {
191 Installer.InstallProduct(dbFile, "REMOVE=All");
192 }
193 catch (Exception ex) { caughtEx = ex; }
194 Assert.IsNull(caughtEx, "Exception thrown while installing product: " + caughtEx);
195
196 Assert.IsFalse(installation.IsInstalled, "Checking that product is not installed after removing.");
197
198 prevRecHandler = Installer.SetExternalUI(prevRecHandler, InstallLogModes.None);
199 Assert.AreEqual<ExternalUIRecordHandler>(WindowsInstallerTest.ExternalUIRecordLogger, prevRecHandler, "Checking that previously-set UI record handler is returned.");
200 }
201
202 public static MessageResult ExternalUILogger(
203 InstallMessage messageType,
204 string message,
205 MessageButtons buttons,
206 MessageIcon icon,
207 MessageDefaultButton defaultButton)
208 {
209 Console.WriteLine("{0}: {1}", messageType, message);
210 return MessageResult.None;
211 }
212
213 public static MessageResult ExternalUIRecordLogger(
214 InstallMessage messageType,
215 Record messageRecord,
216 MessageButtons buttons,
217 MessageIcon icon,
218 MessageDefaultButton defaultButton)
219 {
220 if (messageRecord != null)
221 {
222 if (messageRecord.FormatString.Length == 0 && messageRecord.FieldCount > 0)
223 {
224 messageRecord.FormatString = "1: [1] 2: [2] 3: [3] 4: [4] 5: [5]";
225 }
226 Console.WriteLine("{0}: {1}", messageType, messageRecord.ToString());
227 }
228 else
229 {
230 Console.WriteLine("{0}: (null)", messageType);
231 }
232 return MessageResult.None;
233 }
234
235 [TestMethod]
236 [Ignore] // Currently fails.
237 public void InstallerMessageResources()
238 {
239 string message1101 = Installer.GetErrorMessage(1101);
240 Console.WriteLine("Message 1101: " + message1101);
241 Assert.IsNotNull(message1101);
242 Assert.IsTrue(message1101.Contains("file"));
243
244 message1101 = Installer.GetErrorMessage(1101, CultureInfo.GetCultureInfo(1033));
245 Console.WriteLine("Message 1101: " + message1101);
246 Assert.IsNotNull(message1101);
247 Assert.IsTrue(message1101.Contains("file"));
248
249 string message2621 = Installer.GetErrorMessage(2621);
250 Console.WriteLine("Message 2621: " + message2621);
251 Assert.IsNotNull(message2621);
252 Assert.IsTrue(message2621.Contains("DLL"));
253
254 string message3002 = Installer.GetErrorMessage(3002);
255 Console.WriteLine("Message 3002: " + message3002);
256 Assert.IsNotNull(message3002);
257 Assert.IsTrue(message3002.Contains("sequencing"));
258 }
259
260 [TestMethod]
261 public void EnumComponentQualifiers()
262 {
263 foreach (ComponentInstallation comp in ComponentInstallation.AllComponents)
264 {
265 bool qualifiers = false;
266 foreach (ComponentInstallation.Qualifier qualifier in comp.Qualifiers)
267 {
268 if (!qualifiers)
269 {
270 Console.WriteLine(comp.Path);
271 qualifiers = true;
272 }
273
274 Console.WriteLine("\t{0}: {1}", qualifier.QualifierCode, qualifier.Data);
275 }
276 }
277 }
278
279 [TestMethod]
280 public void DeleteRecord()
281 {
282 string dbFile = "DeleteRecord.msi";
283
284 using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect))
285 {
286 WindowsInstallerUtils.InitializeProductDatabase(db);
287 WindowsInstallerUtils.CreateTestProduct(db);
288
289 string query = "SELECT `Property`, `Value` FROM `Property` WHERE `Property` = 'UpgradeCode'";
290
291 using (View view = db.OpenView(query))
292 {
293 view.Execute();
294
295 Record rec = view.Fetch();
296
297 Console.WriteLine("Calling ToString() : " + rec);
298
299 view.Delete(rec);
300 }
301
302 Assert.AreEqual(0, db.ExecuteStringQuery(query).Count);
303 }
304 }
305
306 [TestMethod]
307 public void InsertRecordThenTryFormatString()
308 {
309 string dbFile = "InsertRecordThenTryFormatString.msi";
310
311 using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect))
312 {
313 WindowsInstallerUtils.InitializeProductDatabase(db);
314 WindowsInstallerUtils.CreateTestProduct(db);
315
316 string parameterFormatString = "[1]";
317 string[] properties = new string[]
318 {
319 "SonGoku", "Over 9000",
320 };
321
322 string query = "SELECT `Property`, `Value` FROM `Property`";
323
324 using (View view = db.OpenView(query))
325 {
326 using (Record rec = new Record(2))
327 {
328 rec[1] = properties[0];
329 rec[2] = properties[1];
330 rec.FormatString = parameterFormatString;
331 Console.WriteLine("Format String before inserting: " + rec.FormatString);
332 view.Insert(rec);
333
334 Console.WriteLine("Format String after inserting: " + rec.FormatString);
335 // After inserting, the format string is invalid.
336 Assert.AreEqual(String.Empty, rec.ToString());
337
338 // Setting the format string manually makes it valid again.
339 rec.FormatString = parameterFormatString;
340 Assert.AreEqual(properties[0], rec.ToString());
341 }
342 }
343 }
344 }
345
346 [TestMethod]
347 public void SeekRecordThenTryFormatString()
348 {
349 string dbFile = "SeekRecordThenTryFormatString.msi";
350
351 using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect))
352 {
353 WindowsInstallerUtils.InitializeProductDatabase(db);
354 WindowsInstallerUtils.CreateTestProduct(db);
355
356 string parameterFormatString = "[1]";
357 string[] properties = new string[]
358 {
359 "SonGoku", "Over 9000",
360 };
361
362 string query = "SELECT `Property`, `Value` FROM `Property`";
363
364 using (View view = db.OpenView(query))
365 {
366 using (Record rec = new Record(2))
367 {
368 rec[1] = properties[0];
369 rec[2] = properties[1];
370 rec.FormatString = parameterFormatString;
371 Console.WriteLine("Record fields before seeking: " + rec[0] + " " + rec[1] + " " + rec[2]);
372 view.Seek(rec);
373
374 //TODO: Why does view.Seek remove the record fields?
375 Console.WriteLine("Record fields after seeking: " + rec[0] + " " + rec[1] + " " + rec[2]);
376 // After inserting, the format string is invalid.
377 Assert.AreEqual(String.Empty, rec.ToString());
378 }
379 }
380 }
381 }
382
383 [TestMethod]
384 public void TestToString()
385 {
386 string defaultString = "1: ";
387 string vegetaShout = "It's OVER 9000!!";
388 string gokuPowerLevel = "9001";
389 string nappaInquiry = "Vegeta, what's the Scouter say about his power level?";
390 string parameterFormatString = "[1]";
391
392 Record rec = new Record(1);
393 Assert.AreEqual(defaultString, rec.ToString(), "Testing default FormatString");
394
395 rec.FormatString = String.Empty;
396 Assert.AreEqual(defaultString, rec.ToString(), "Explicitly set the FormatString to the empty string.");
397
398 rec.FormatString = vegetaShout;
399 Assert.AreEqual(vegetaShout, rec.ToString(), "Testing text only (empty FormatString)");
400
401 rec.FormatString = gokuPowerLevel;
402 Assert.AreEqual(gokuPowerLevel, rec.ToString(), "Testing numbers only from a record that wasn't fetched.");
403
404 Record rec2 = new Record(nappaInquiry);
405 rec2.FormatString = parameterFormatString;
406 Assert.AreEqual(nappaInquiry, rec2.ToString(), "Testing text with a FormatString set.");
407 }
408 }
409}
diff --git a/src/dtf/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTransactions.cs b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTransactions.cs
new file mode 100644
index 00000000..3bdf5acd
--- /dev/null
+++ b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerTransactions.cs
@@ -0,0 +1,161 @@
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
3namespace WixToolset.Dtf.Test
4{
5 using System;
6 using System.IO;
7 using System.Windows.Forms;
8 using System.Globalization;
9 using System.Collections.Generic;
10 using Microsoft.VisualStudio.TestTools.UnitTesting;
11 using WixToolset.Dtf.WindowsInstaller;
12 using View = WixToolset.Dtf.WindowsInstaller.View;
13
14 [TestClass]
15 public class WindowsInstallerTransactions
16 {
17 [TestInitialize()]
18 public void Initialize()
19 {
20 }
21
22 [TestCleanup()]
23 public void Cleanup()
24 {
25 }
26
27 [TestMethod]
28 [Ignore] // Requires elevation.
29 public void InstallerTransactTwoProducts()
30 {
31 string dbFile1 = "InstallerTransactProduct1.msi";
32 string dbFile2 = "InstallerTransactProduct2.msi";
33 string productCode1;
34 string productCode2;
35
36 using (Database db1 = new Database(dbFile1, DatabaseOpenMode.CreateDirect))
37 {
38 WindowsInstallerUtils.InitializeProductDatabase(db1);
39 WindowsInstallerUtils.CreateTestProduct(db1);
40
41 productCode1 = db1.ExecuteStringQuery("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")[0];
42
43 db1.Commit();
44 }
45
46 using (Database db2 = new Database(dbFile2, DatabaseOpenMode.CreateDirect))
47 {
48 WindowsInstallerUtils.InitializeProductDatabase(db2);
49 WindowsInstallerUtils.CreateTestProduct(db2);
50
51 productCode2 = db2.ExecuteStringQuery("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")[0];
52
53 db2.Commit();
54 }
55
56 ProductInstallation installation1 = new ProductInstallation(productCode1);
57 ProductInstallation installation2 = new ProductInstallation(productCode2);
58 Assert.IsFalse(installation1.IsInstalled, "Checking that product 1 is not installed before starting.");
59 Assert.IsFalse(installation2.IsInstalled, "Checking that product 2 is not installed before starting.");
60
61 Installer.SetInternalUI(InstallUIOptions.Silent);
62 ExternalUIHandler prevHandler = Installer.SetExternalUI(WindowsInstallerTest.ExternalUILogger,
63 InstallLogModes.FatalExit |
64 InstallLogModes.Error |
65 InstallLogModes.Warning |
66 InstallLogModes.User |
67 InstallLogModes.Info |
68 InstallLogModes.ResolveSource |
69 InstallLogModes.OutOfDiskSpace |
70 InstallLogModes.ActionStart |
71 InstallLogModes.ActionData |
72 InstallLogModes.CommonData |
73 InstallLogModes.Progress |
74 InstallLogModes.Initialize |
75 InstallLogModes.Terminate |
76 InstallLogModes.ShowDialog);
77 Assert.IsNull(prevHandler, "Checking that returned previous UI handler is null.");
78
79 Transaction transaction = new Transaction("TestInstallTransaction", TransactionAttributes.None);
80
81 Exception caughtEx = null;
82 try
83 {
84 Installer.InstallProduct(dbFile1, String.Empty);
85 }
86 catch (Exception ex) { caughtEx = ex; }
87 Assert.IsNull(caughtEx, "Exception thrown while installing product 1: " + caughtEx);
88
89 Console.WriteLine();
90 Console.WriteLine("===================================================================");
91 Console.WriteLine();
92
93 try
94 {
95 Installer.InstallProduct(dbFile2, String.Empty);
96 }
97 catch (Exception ex) { caughtEx = ex; }
98 Assert.IsNull(caughtEx, "Exception thrown while installing product 2: " + caughtEx);
99
100 transaction.Commit();
101 transaction.Close();
102
103 prevHandler = Installer.SetExternalUI(prevHandler, InstallLogModes.None);
104 Assert.AreEqual<ExternalUIHandler>(WindowsInstallerTest.ExternalUILogger, prevHandler, "Checking that previously-set UI handler is returned.");
105
106 Assert.IsTrue(installation1.IsInstalled, "Checking that product 1 is installed.");
107 Assert.IsTrue(installation2.IsInstalled, "Checking that product 2 is installed.");
108
109 Console.WriteLine();
110 Console.WriteLine();
111 Console.WriteLine();
112 Console.WriteLine("===================================================================");
113 Console.WriteLine("===================================================================");
114 Console.WriteLine();
115 Console.WriteLine();
116 Console.WriteLine();
117
118 ExternalUIRecordHandler prevRecHandler = Installer.SetExternalUI(WindowsInstallerTest.ExternalUIRecordLogger,
119 InstallLogModes.FatalExit |
120 InstallLogModes.Error |
121 InstallLogModes.Warning |
122 InstallLogModes.User |
123 InstallLogModes.Info |
124 InstallLogModes.ResolveSource |
125 InstallLogModes.OutOfDiskSpace |
126 InstallLogModes.ActionStart |
127 InstallLogModes.ActionData |
128 InstallLogModes.CommonData |
129 InstallLogModes.Progress |
130 InstallLogModes.Initialize |
131 InstallLogModes.Terminate |
132 InstallLogModes.ShowDialog);
133 Assert.IsNull(prevRecHandler, "Checking that returned previous UI record handler is null.");
134
135 transaction = new Transaction("TestUninstallTransaction", TransactionAttributes.None);
136
137 try
138 {
139 Installer.InstallProduct(dbFile1, "REMOVE=All");
140 }
141 catch (Exception ex) { caughtEx = ex; }
142 Assert.IsNull(caughtEx, "Exception thrown while removing product 1: " + caughtEx);
143
144 try
145 {
146 Installer.InstallProduct(dbFile2, "REMOVE=All");
147 }
148 catch (Exception ex) { caughtEx = ex; }
149 Assert.IsNull(caughtEx, "Exception thrown while removing product 2: " + caughtEx);
150
151 transaction.Commit();
152 transaction.Close();
153
154 Assert.IsFalse(installation1.IsInstalled, "Checking that product 1 is not installed after removing.");
155 Assert.IsFalse(installation2.IsInstalled, "Checking that product 2 is not installed after removing.");
156
157 prevRecHandler = Installer.SetExternalUI(prevRecHandler, InstallLogModes.None);
158 Assert.AreEqual<ExternalUIRecordHandler>(WindowsInstallerTest.ExternalUIRecordLogger, prevRecHandler, "Checking that previously-set UI record handler is returned.");
159 }
160 }
161}
diff --git a/src/dtf/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerUtils.cs b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerUtils.cs
new file mode 100644
index 00000000..644f1988
--- /dev/null
+++ b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller/WindowsInstallerUtils.cs
@@ -0,0 +1,174 @@
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
3namespace WixToolset.Dtf.Test
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Text;
8 using WixToolset.Dtf.WindowsInstaller;
9
10 public class WindowsInstallerUtils
11 {
12 public static void InitializeProductDatabase(Database db)
13 {
14 InitializeProductDatabase(db, false);
15 }
16
17 public static void InitializeProductDatabase(Database db, bool sixtyFourBit)
18 {
19 db.SummaryInfo.CodePage = (short) Encoding.Default.CodePage;
20 db.SummaryInfo.Title = "Windows Installer Test";
21 db.SummaryInfo.Subject = db.SummaryInfo.Title;
22 db.SummaryInfo.Author = typeof(WindowsInstallerUtils).Assembly.FullName;
23 db.SummaryInfo.CreatingApp = db.SummaryInfo.Author;
24 db.SummaryInfo.Comments = typeof(WindowsInstallerUtils).FullName + ".CreateBasicDatabase()";
25 db.SummaryInfo.Keywords = "Installer,MSI,Database";
26 db.SummaryInfo.PageCount = 300;
27 db.SummaryInfo.WordCount = 0;
28 db.SummaryInfo.RevisionNumber = Guid.NewGuid().ToString("B").ToUpper();
29 db.SummaryInfo.Template = (sixtyFourBit ? "x64" : "Intel") + ";0";
30
31 foreach (TableInfo tableInfo in Schema.Tables)
32 {
33 db.Execute(tableInfo.SqlCreateString);
34 }
35
36 db.Execute("INSERT INTO `Directory` (`Directory`, `DefaultDir`) VALUES ('TARGETDIR', 'SourceDir')");
37 db.Execute("INSERT INTO `Directory` (`Directory`, `Directory_Parent`, `DefaultDir`) VALUES ('ProgramFilesFolder', 'TARGETDIR', '.')");
38
39 foreach (Action action in Sequence.InstallExecute)
40 {
41 db.Execute("INSERT INTO `InstallExecuteSequence` (`Action`, `Sequence`) VALUES ('{0}', {1})",
42 action.Name, action.Sequence);
43 }
44 }
45
46 public const string UpgradeCode = "{05955FE8-005F-4695-A81F-D559338065BB}";
47
48 public static void CreateTestProduct(Database db)
49 {
50 Guid productGuid = Guid.NewGuid();
51
52 string[] properties = new string[]
53 {
54 "ProductCode", productGuid.ToString("B").ToUpper(),
55 "UpgradeCode", UpgradeCode,
56 "ProductName", "Windows Installer Test Product " + productGuid.ToString("P").ToUpper(),
57 "ProductVersion", "1.0.0.0000",
58 };
59
60 using (View view = db.OpenView("INSERT INTO `Property` (`Property`, `Value`) VALUES (?, ?)"))
61 {
62 using (Record rec = new Record(2))
63 {
64 for (int i = 0; i < properties.Length; i += 2)
65 {
66 rec[1] = properties[i];
67 rec[2] = properties[i + 1];
68 view.Execute(rec);
69 }
70 }
71 }
72
73 int randomId = new Random().Next(10000);
74 string productDir = "TestDir" + randomId;
75 db.Execute(
76 "INSERT INTO `Directory` (`Directory`, `Directory_Parent`, `DefaultDir`) " +
77 "VALUES ('TestDir', 'ProgramFilesFolder', 'TestDir|{0}:.')", productDir);
78
79 string compId = Guid.NewGuid().ToString("B").ToUpper();
80 db.Execute(
81 "INSERT INTO `Component` " +
82 "(`Component`, `ComponentId`, `Directory_`, `Attributes`, `KeyPath`) " +
83 "VALUES ('{0}', '{1}', '{2}', {3}, '{4}')",
84 "TestRegComp1",
85 compId,
86 "TestDir",
87 (int) ComponentAttributes.RegistryKeyPath,
88 "TestReg1");
89
90 string productReg = "TestReg" + randomId;
91 db.Execute(
92 "INSERT INTO `Registry` (`Registry`, `Root`, `Key`, `Component_`) VALUES ('{0}', {1}, '{2}', '{3}')",
93 "TestReg1",
94 -1,
95 @"Software\Microsoft\Windows Installer Test\" + productReg,
96 "TestRegComp1");
97
98 db.Execute(
99 "INSERT INTO `Feature` (`Feature`, `Title`, `Level`, `Attributes`) VALUES ('{0}', '{1}', {2}, {3})",
100 "TestFeature1",
101 "Test Feature 1",
102 1,
103 (int) FeatureAttributes.None);
104
105 db.Execute(
106 "INSERT INTO `FeatureComponents` (`Feature_`, `Component_`) VALUES ('{0}', '{1}')",
107 "TestFeature1",
108 "TestRegComp1");
109 }
110
111 public static void AddFeature(Database db, string featureName)
112 {
113 db.Execute(
114 "INSERT INTO `Feature` (`Feature`, `Title`, `Level`, `Attributes`) VALUES ('{0}', '{1}', {2}, {3})",
115 featureName,
116 featureName,
117 1,
118 (int) FeatureAttributes.None);
119 }
120
121 public static void AddRegistryComponent(Database db,
122 string featureName, string compName, string compId,
123 string keyName, string keyValueName, string value)
124 {
125 db.Execute(
126 "INSERT INTO `Component` " +
127 "(`Component`, `ComponentId`, `Directory_`, `Attributes`, `KeyPath`) " +
128 "VALUES ('{0}', '{1}', '{2}', {3}, '{4}')",
129 compName,
130 compId,
131 "TestDir",
132 (int) ComponentAttributes.RegistryKeyPath,
133 compName + "Reg1");
134 db.Execute(
135 "INSERT INTO `Registry` (`Registry`, `Root`, `Key`, `Name`, `Value`, `Component_`) VALUES ('{0}', {1}, '{2}', '{3}', '{4}', '{5}')",
136 compName + "Reg1",
137 -1,
138 @"Software\Microsoft\Windows Installer Test\" + keyName,
139 keyValueName,
140 value,
141 compName);
142 db.Execute(
143 "INSERT INTO `FeatureComponents` (`Feature_`, `Component_`) VALUES ('{0}', '{1}')",
144 featureName,
145 compName);
146 }
147
148 public static void AddFileComponent(Database db,
149 string featureName, string compName, string compId,
150 string fileKey, string fileName)
151 {
152 db.Execute(
153 "INSERT INTO `Component` " +
154 "(`Component`, `ComponentId`, `Directory_`, `Attributes`, `KeyPath`) " +
155 "VALUES ('{0}', '{1}', '{2}', {3}, '{4}')",
156 compName,
157 compId,
158 "TestDir",
159 (int) ComponentAttributes.None,
160 fileKey);
161 db.Execute(
162 "INSERT INTO `File` " +
163 "(`File`, `Component_`, `FileName`, `FileSize`, `Attributes`, `Sequence`) " +
164 "VALUES ('{0}', '{1}', '{2}', 1, 0, 1)",
165 fileKey,
166 compName,
167 fileName);
168 db.Execute(
169 "INSERT INTO `FeatureComponents` (`Feature_`, `Component_`) VALUES ('{0}', '{1}')",
170 featureName,
171 compName);
172 }
173 }
174}
diff --git a/src/dtf/WixToolsetTests.Dtf.WindowsInstaller/WixToolsetTests.Dtf.WindowsInstaller.csproj b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller/WixToolsetTests.Dtf.WindowsInstaller.csproj
new file mode 100644
index 00000000..dbddb682
--- /dev/null
+++ b/src/dtf/WixToolsetTests.Dtf.WindowsInstaller/WixToolsetTests.Dtf.WindowsInstaller.csproj
@@ -0,0 +1,34 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
5 <PropertyGroup>
6 <ProjectGuid>{16F5202F-9276-4166-975C-C9654BAF8012}</ProjectGuid>
7 <OutputType>Library</OutputType>
8 <RootNamespace>WixToolsetTests.Dtf</RootNamespace>
9 <AssemblyName>WixToolsetTests.Dtf.WindowsInstaller</AssemblyName>
10 <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
11 <CreateDocumentation>false</CreateDocumentation>
12 </PropertyGroup>
13
14 <ItemGroup>
15 <Compile Include="EmbeddedExternalUI.cs" />
16 <Compile Include="Schema.cs" />
17 <Compile Include="WindowsInstallerTest.cs" />
18 <Compile Include="WindowsInstallerTransactions.cs" />
19 <Compile Include="WindowsInstallerUtils.cs" />
20 </ItemGroup>
21
22 <ItemGroup>
23 <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
24 <Reference Include="System" />
25 <Reference Include="System.Windows.Forms" />
26 <Reference Include="System.Xml" />
27 </ItemGroup>
28
29 <ItemGroup>
30 <ProjectReference Include="..\WixToolset.Dtf.WindowsInstaller\WixToolset.Dtf.WindowsInstaller.csproj" />
31 </ItemGroup>
32
33 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
34</Project>