1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
// 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.
namespace WixToolset.Dtf.Test
{
using System;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using System.Globalization;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WixToolset.Dtf.WindowsInstaller;
using View = WixToolset.Dtf.WindowsInstaller.View;
[TestClass]
public class EmbeddedExternalUI
{
const InstallLogModes TestLogModes =
InstallLogModes.FatalExit |
InstallLogModes.Error |
InstallLogModes.Warning |
InstallLogModes.User |
InstallLogModes.Info |
InstallLogModes.ResolveSource |
InstallLogModes.OutOfDiskSpace |
InstallLogModes.ActionStart |
InstallLogModes.ActionData |
InstallLogModes.CommonData;
#if DEBUG
const string EmbeddedUISampleBinDir = @"..\..\build\debug\";
#else
const string EmbeddedUISampleBinDir = @"..\..\build\release\";
#endif
[TestMethod]
[Ignore] // Requires elevation.
public void EmbeddedUISingleInstall()
{
string dbFile = "EmbeddedUISingleInstall.msi";
string productCode;
string uiDir = Path.GetFullPath(EmbeddedExternalUI.EmbeddedUISampleBinDir);
string uiFile = "WixToolset.Dtf.Samples.EmbeddedUI.dll";
using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect))
{
WindowsInstallerUtils.InitializeProductDatabase(db);
WindowsInstallerUtils.CreateTestProduct(db);
productCode = db.ExecuteStringQuery("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")[0];
using (Record uiRec = new Record(5))
{
uiRec[1] = "TestEmbeddedUI";
uiRec[2] = Path.GetFileNameWithoutExtension(uiFile) + ".Wrapper.dll";
uiRec[3] = 1;
uiRec[4] = (int) (
EmbeddedExternalUI.TestLogModes |
InstallLogModes.Progress |
InstallLogModes.Initialize |
InstallLogModes.Terminate |
InstallLogModes.ShowDialog);
uiRec.SetStream(5, Path.Combine(uiDir, uiFile));
db.Execute(db.Tables["MsiEmbeddedUI"].SqlInsertString, uiRec);
}
db.Commit();
}
Installer.SetInternalUI(InstallUIOptions.Full);
ProductInstallation installation = new ProductInstallation(productCode);
Assert.IsFalse(installation.IsInstalled, "Checking that product is not installed before starting.");
Exception caughtEx = null;
try
{
Installer.EnableLog(EmbeddedExternalUI.TestLogModes, "install.log");
Installer.InstallProduct(dbFile, String.Empty);
}
catch (Exception ex) { caughtEx = ex; }
Assert.IsNull(caughtEx, "Exception thrown while installing product: " + caughtEx);
Assert.IsTrue(installation.IsInstalled, "Checking that product is installed.");
Console.WriteLine();
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("===================================================================");
Console.WriteLine();
Console.WriteLine();
Console.WriteLine();
try
{
Installer.EnableLog(EmbeddedExternalUI.TestLogModes, "uninstall.log");
Installer.InstallProduct(dbFile, "REMOVE=All");
}
catch (Exception ex) { caughtEx = ex; }
Assert.IsNull(caughtEx, "Exception thrown while uninstalling product: " + caughtEx);
}
// This test does not pass if run normally.
// It only passes when a failure is injected into the EmbeddedUI launcher.
////[TestMethod]
public void EmbeddedUIInitializeFails()
{
string dbFile = "EmbeddedUIInitializeFails.msi";
string productCode;
string uiDir = Path.GetFullPath(EmbeddedExternalUI.EmbeddedUISampleBinDir);
string uiFile = "WixToolset.Dtf.Samples.EmbeddedUI.dll";
// A number that will be used to check whether a type 19 CA runs.
const string magicNumber = "3.14159265358979323846264338327950";
using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect))
{
WindowsInstallerUtils.InitializeProductDatabase(db);
WindowsInstallerUtils.CreateTestProduct(db);
const string failureActionName = "EmbeddedUIInitializeFails";
db.Execute("INSERT INTO `CustomAction` (`Action`, `Type`, `Source`, `Target`) " +
"VALUES ('{0}', 19, '', 'Logging magic number: {1}')", failureActionName, magicNumber);
// This type 19 CA (launch condition) is given a condition of 'UILevel = 3' so that it only runs if the
// installation is running in BASIC UI mode, which is what we expect if the EmbeddedUI fails to initialize.
db.Execute("INSERT INTO `InstallExecuteSequence` (`Action`, `Condition`, `Sequence`) " +
"VALUES ('{0}', 'UILevel = 3', 1)", failureActionName);
productCode = db.ExecuteStringQuery("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")[0];
using (Record uiRec = new Record(5))
{
uiRec[1] = "TestEmbeddedUI";
uiRec[2] = Path.GetFileNameWithoutExtension(uiFile) + ".Wrapper.dll";
uiRec[3] = 1;
uiRec[4] = (int)(
EmbeddedExternalUI.TestLogModes |
InstallLogModes.Progress |
InstallLogModes.Initialize |
InstallLogModes.Terminate |
InstallLogModes.ShowDialog);
uiRec.SetStream(5, Path.Combine(uiDir, uiFile));
db.Execute(db.Tables["MsiEmbeddedUI"].SqlInsertString, uiRec);
}
db.Commit();
}
Installer.SetInternalUI(InstallUIOptions.Full);
ProductInstallation installation = new ProductInstallation(productCode);
Assert.IsFalse(installation.IsInstalled, "Checking that product is not installed before starting.");
string logFile = "install.log";
Exception caughtEx = null;
try
{
Installer.EnableLog(EmbeddedExternalUI.TestLogModes, logFile);
Installer.InstallProduct(dbFile, String.Empty);
}
catch (Exception ex) { caughtEx = ex; }
Assert.IsInstanceOfType(caughtEx, typeof(InstallerException),
"Excpected InstallerException installing product; caught: " + caughtEx);
Assert.IsFalse(installation.IsInstalled, "Checking that product is not installed.");
string logText = File.ReadAllText(logFile);
Assert.IsTrue(logText.Contains(magicNumber), "Checking that the type 19 custom action ran.");
}
}
}
|