diff options
author | Rob Mensching <rob@firegiant.com> | 2022-03-31 11:56:14 -0700 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2022-03-31 18:01:06 -0700 |
commit | 47582b162368e8edf7a3b11c13b8e9dabc5f0a26 (patch) | |
tree | 2c4063eff325684bed39de0edacd7866a257ae02 /src/test/dtf/EmbeddedUI/InstallProgressCounter.cs | |
parent | 167296c42497c4e95f0d5d71168542d747655981 (diff) | |
download | wix-47582b162368e8edf7a3b11c13b8e9dabc5f0a26.tar.gz wix-47582b162368e8edf7a3b11c13b8e9dabc5f0a26.tar.bz2 wix-47582b162368e8edf7a3b11c13b8e9dabc5f0a26.zip |
Provide managed CA and Embedded UI DTF libraries via NuGet
Lots of refactoring to bring the SFX tooling back into the 'dtf'
layer since they are (in the end) tightly coupled to some DTF
assemblies. Also refactored the DTF tests into their own folder
and added a couple integration tests to build using the new CA/UI
NuGet package.
Closes wixtoolset/issues#6080
Diffstat (limited to 'src/test/dtf/EmbeddedUI/InstallProgressCounter.cs')
-rw-r--r-- | src/test/dtf/EmbeddedUI/InstallProgressCounter.cs | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/src/test/dtf/EmbeddedUI/InstallProgressCounter.cs b/src/test/dtf/EmbeddedUI/InstallProgressCounter.cs new file mode 100644 index 00000000..3d75081c --- /dev/null +++ b/src/test/dtf/EmbeddedUI/InstallProgressCounter.cs | |||
@@ -0,0 +1,174 @@ | |||
1 | namespace WixToolset.Samples.EmbeddedUI | ||
2 | { | ||
3 | using System; | ||
4 | using WixToolset.Dtf.WindowsInstaller; | ||
5 | |||
6 | /// <summary> | ||
7 | /// Tracks MSI progress messages and converts them to usable progress. | ||
8 | /// </summary> | ||
9 | public class InstallProgressCounter | ||
10 | { | ||
11 | private int total; | ||
12 | private int completed; | ||
13 | private int step; | ||
14 | private bool moveForward; | ||
15 | private bool enableActionData; | ||
16 | private int progressPhase; | ||
17 | private double scriptPhaseWeight; | ||
18 | |||
19 | public InstallProgressCounter() : this(0.3) | ||
20 | { | ||
21 | } | ||
22 | |||
23 | public InstallProgressCounter(double scriptPhaseWeight) | ||
24 | { | ||
25 | if (!(0 <= scriptPhaseWeight && scriptPhaseWeight <= 1)) | ||
26 | { | ||
27 | throw new ArgumentOutOfRangeException("scriptPhaseWeight"); | ||
28 | } | ||
29 | |||
30 | this.scriptPhaseWeight = scriptPhaseWeight; | ||
31 | } | ||
32 | |||
33 | /// <summary> | ||
34 | /// Gets a number between 0 and 1 that indicates the overall installation progress. | ||
35 | /// </summary> | ||
36 | public double Progress { get; private set; } | ||
37 | |||
38 | public void ProcessMessage(InstallMessage messageType, Record messageRecord) | ||
39 | { | ||
40 | // This MSI progress-handling code was mostly borrowed from burn and translated from C++ to C#. | ||
41 | |||
42 | switch (messageType) | ||
43 | { | ||
44 | case InstallMessage.ActionStart: | ||
45 | if (this.enableActionData) | ||
46 | { | ||
47 | this.enableActionData = false; | ||
48 | } | ||
49 | break; | ||
50 | |||
51 | case InstallMessage.ActionData: | ||
52 | if (this.enableActionData) | ||
53 | { | ||
54 | if (this.moveForward) | ||
55 | { | ||
56 | this.completed += this.step; | ||
57 | } | ||
58 | else | ||
59 | { | ||
60 | this.completed -= this.step; | ||
61 | } | ||
62 | |||
63 | this.UpdateProgress(); | ||
64 | } | ||
65 | break; | ||
66 | |||
67 | case InstallMessage.Progress: | ||
68 | this.ProcessProgressMessage(messageRecord); | ||
69 | break; | ||
70 | } | ||
71 | } | ||
72 | |||
73 | private void ProcessProgressMessage(Record progressRecord) | ||
74 | { | ||
75 | // This MSI progress-handling code was mostly borrowed from burn and translated from C++ to C#. | ||
76 | |||
77 | if (progressRecord == null || progressRecord.FieldCount == 0) | ||
78 | { | ||
79 | return; | ||
80 | } | ||
81 | |||
82 | int fieldCount = progressRecord.FieldCount; | ||
83 | int progressType = progressRecord.GetInteger(1); | ||
84 | string progressTypeString = String.Empty; | ||
85 | switch (progressType) | ||
86 | { | ||
87 | case 0: // Master progress reset | ||
88 | if (fieldCount < 4) | ||
89 | { | ||
90 | return; | ||
91 | } | ||
92 | |||
93 | this.progressPhase++; | ||
94 | |||
95 | this.total = progressRecord.GetInteger(2); | ||
96 | if (this.progressPhase == 1) | ||
97 | { | ||
98 | // HACK!!! this is a hack courtesy of the Windows Installer team. It seems the script planning phase | ||
99 | // is always off by "about 50". So we'll toss an extra 50 ticks on so that the standard progress | ||
100 | // doesn't go over 100%. If there are any custom actions, they may blow the total so we'll call this | ||
101 | // "close" and deal with the rest. | ||
102 | this.total += 50; | ||
103 | } | ||
104 | |||
105 | this.moveForward = (progressRecord.GetInteger(3) == 0); | ||
106 | this.completed = (this.moveForward ? 0 : this.total); // if forward start at 0, if backwards start at max | ||
107 | this.enableActionData = false; | ||
108 | |||
109 | this.UpdateProgress(); | ||
110 | break; | ||
111 | |||
112 | case 1: // Action info | ||
113 | if (fieldCount < 3) | ||
114 | { | ||
115 | return; | ||
116 | } | ||
117 | |||
118 | if (progressRecord.GetInteger(3) == 0) | ||
119 | { | ||
120 | this.enableActionData = false; | ||
121 | } | ||
122 | else | ||
123 | { | ||
124 | this.enableActionData = true; | ||
125 | this.step = progressRecord.GetInteger(2); | ||
126 | } | ||
127 | break; | ||
128 | |||
129 | case 2: // Progress report | ||
130 | if (fieldCount < 2 || this.total == 0 || this.progressPhase == 0) | ||
131 | { | ||
132 | return; | ||
133 | } | ||
134 | |||
135 | if (this.moveForward) | ||
136 | { | ||
137 | this.completed += progressRecord.GetInteger(2); | ||
138 | } | ||
139 | else | ||
140 | { | ||
141 | this.completed -= progressRecord.GetInteger(2); | ||
142 | } | ||
143 | |||
144 | this.UpdateProgress(); | ||
145 | break; | ||
146 | |||
147 | case 3: // Progress total addition | ||
148 | this.total += progressRecord.GetInteger(2); | ||
149 | break; | ||
150 | } | ||
151 | } | ||
152 | |||
153 | private void UpdateProgress() | ||
154 | { | ||
155 | if (this.progressPhase < 1 || this.total == 0) | ||
156 | { | ||
157 | this.Progress = 0; | ||
158 | } | ||
159 | else if (this.progressPhase == 1) | ||
160 | { | ||
161 | this.Progress = this.scriptPhaseWeight * Math.Min(this.completed, this.total) / this.total; | ||
162 | } | ||
163 | else if (this.progressPhase == 2) | ||
164 | { | ||
165 | this.Progress = this.scriptPhaseWeight + | ||
166 | (1 - this.scriptPhaseWeight) * Math.Min(this.completed, this.total) / this.total; | ||
167 | } | ||
168 | else | ||
169 | { | ||
170 | this.Progress = 1; | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | } | ||