main
cs 214 lines 9.27 KB
Raw
1 // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3 namespace WixTestTools
4 {
5 using System;
6 using System.IO;
7 using System.Linq;
8 using System.Text;
9 using Microsoft.Win32;
10 using WixInternal.TestSupport;
11 using WixToolset.Data;
12 using WixToolset.Data.Symbols;
13 using Xunit;
14
15 public partial class BundleInstaller
16 {
17 public const string DependencyRegistryRoot = "Software\\Classes\\Installer\\Dependencies";
18 public const string FULL_BURN_POLICY_REGISTRY_PATH = "SOFTWARE\\Policies\\WiX\\Burn";
19 public const string FULL_BURN_POLICY_REGISTRY_PATH_WOW6432NODE = "SOFTWARE\\WOW6432Node\\Policies\\WiX\\Burn";
20 public const string PACKAGE_CACHE_FOLDER_NAME = "Package Cache";
21
22 public string BundlePdb { get; }
23
24 private WixBundleSymbol BundleSymbol { get; set; }
25
26 private WixBundleSymbol GetBundleSymbol()
27 {
28 if (this.BundleSymbol == null)
29 {
30 using var wixOutput = WixOutput.Read(this.BundlePdb);
31 var intermediate = Intermediate.Load(wixOutput);
32 var section = intermediate.Sections.Single();
33 this.BundleSymbol = section.Symbols.OfType<WixBundleSymbol>().Single();
34 }
35
36 return this.BundleSymbol;
37 }
38
39 public string GetFullBurnPolicyRegistryPath()
40 {
41 var bundleSymbol = this.GetBundleSymbol();
42 var x64 = bundleSymbol.Platform != Platform.X86;
43 return x64 ? FULL_BURN_POLICY_REGISTRY_PATH : FULL_BURN_POLICY_REGISTRY_PATH_WOW6432NODE;
44 }
45
46 public string GetPackageCachePathForCacheId(string cacheId, bool perMachine)
47 {
48 string cachePath;
49 if (perMachine)
50 {
51 using var policyKey = Registry.LocalMachine.OpenSubKey(this.GetFullBurnPolicyRegistryPath());
52 var redirectedCachePath = policyKey?.GetValue("PackageCache") as string;
53 cachePath = redirectedCachePath ?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), PACKAGE_CACHE_FOLDER_NAME);
54 }
55 else
56 {
57 cachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), PACKAGE_CACHE_FOLDER_NAME);
58 }
59 return Path.Combine(cachePath, cacheId);
60 }
61
62 public string GetExpectedCachedBundlePath()
63 {
64 var bundleSymbol = this.GetBundleSymbol();
65 var cachePath = this.GetPackageCachePathForCacheId(bundleSymbol.BundleId, bundleSymbol.PerMachine);
66 return Path.Combine(cachePath, Path.GetFileName(this.Bundle));
67 }
68
69 public string ManuallyCache()
70 {
71 var expectedCachePath = this.GetExpectedCachedBundlePath();
72 Directory.CreateDirectory(Path.GetDirectoryName(expectedCachePath));
73 File.Copy(this.Bundle, expectedCachePath);
74 return expectedCachePath;
75 }
76
77 public void ManuallyUncache()
78 {
79 var expectedCachePath = this.GetExpectedCachedBundlePath();
80 File.Delete(expectedCachePath);
81 }
82
83 public bool TryGetArpEntryExePackageConfiguration(string packageId, out string arpId, out string arpVersion, out bool arpWin64, out bool perMachine)
84 {
85 using var wixOutput = WixOutput.Read(this.BundlePdb);
86 var intermediate = Intermediate.Load(wixOutput);
87 var section = intermediate.Sections.Single();
88 var packageSymbol = section.Symbols.OfType<WixBundlePackageSymbol>().SingleOrDefault(p => p.Id.Id == packageId);
89 var exePackageSymbol = section.Symbols.OfType<WixBundleExePackageSymbol>().SingleOrDefault(p => p.Id.Id == packageId);
90 if (packageSymbol == null || exePackageSymbol == null || exePackageSymbol.DetectionType != WixBundleExePackageDetectionType.Arp)
91 {
92 arpId = null;
93 arpVersion = null;
94 arpWin64 = false;
95 perMachine = false;
96 return false;
97 }
98
99 arpId = exePackageSymbol.ArpId;
100 arpVersion = exePackageSymbol.ArpDisplayVersion;
101 arpWin64 = exePackageSymbol.ArpWin64;
102 perMachine = packageSymbol.PerMachine == true;
103 return true;
104 }
105
106 public bool TryGetRegistration(out BundleRegistration registration)
107 {
108 var bundleSymbol = this.GetBundleSymbol();
109 var x64 = bundleSymbol.Platform != Platform.X86;
110 var bundleId = bundleSymbol.BundleId;
111 if (bundleSymbol.PerMachine)
112 {
113 return BundleRegistration.TryGetPerMachineBundleRegistrationById(bundleId, x64, out registration);
114 }
115 else
116 {
117 return BundleRegistration.TryGetPerUserBundleRegistrationById(bundleId, out registration);
118 }
119 }
120
121 public BundleRegistration VerifyRegisteredAndInPackageCache(int? expectedSystemComponent = null)
122 {
123 Assert.True(this.TryGetRegistration(out var registration));
124
125 Assert.Equal(expectedSystemComponent, registration.SystemComponent);
126
127 Assert.NotNull(registration.CachePath);
128 Assert.True(File.Exists(registration.CachePath));
129
130 var expectedCachePath = this.GetExpectedCachedBundlePath();
131 WixAssert.StringEqual(expectedCachePath, registration.CachePath, true);
132
133 return registration;
134 }
135
136 public void VerifyUnregisteredAndRemovedFromPackageCache()
137 {
138 var cachedBundlePath = this.GetExpectedCachedBundlePath();
139 this.VerifyUnregisteredAndRemovedFromPackageCache(cachedBundlePath);
140 }
141
142 public void VerifyUnregisteredAndRemovedFromPackageCache(string cachedBundlePath)
143 {
144 Assert.False(this.TryGetRegistration(out _));
145 Assert.False(File.Exists(cachedBundlePath));
146 }
147
148 public void RemovePackageFromCache(string packageId)
149 {
150 using var wixOutput = WixOutput.Read(this.BundlePdb);
151 var intermediate = Intermediate.Load(wixOutput);
152 var section = intermediate.Sections.Single();
153 var packageSymbol = section.Symbols.OfType<WixBundlePackageSymbol>().Single(p => p.Id.Id == packageId);
154 var cachePath = this.GetPackageCachePathForCacheId(packageSymbol.CacheId, packageSymbol.PerMachine == true);
155 if (Directory.Exists(cachePath))
156 {
157 Directory.Delete(cachePath, true);
158 }
159 }
160
161 public string GetPackageEntryPointCachePath(string packageId)
162 {
163 using var wixOutput = WixOutput.Read(this.BundlePdb);
164 var intermediate = Intermediate.Load(wixOutput);
165 var section = intermediate.Sections.Single();
166 var packageSymbol = section.Symbols.OfType<WixBundlePackageSymbol>().Single(p => p.Id.Id == packageId);
167 var packagePayloadSymbol = section.Symbols.OfType<WixBundlePayloadSymbol>().Single(p => p.Id.Id == packageSymbol.PayloadRef);
168 var cachePath = this.GetPackageCachePathForCacheId(packageSymbol.CacheId, packageSymbol.PerMachine == true);
169 return Path.Combine(cachePath, packagePayloadSymbol.Name);
170 }
171
172 public void VerifyPackageIsCached(string packageId, bool cached = true)
173 {
174 var entryPointCachePath = this.GetPackageEntryPointCachePath(packageId);
175 Assert.Equal(cached, File.Exists(entryPointCachePath));
176 }
177
178 public void VerifyPackageProviderRemoved(string packageId)
179 {
180 using var wixOutput = WixOutput.Read(this.BundlePdb);
181 var intermediate = Intermediate.Load(wixOutput);
182 var section = intermediate.Sections.Single();
183 var packageSymbol = section.Symbols.OfType<WixBundlePackageSymbol>().Single(p => p.Id.Id == packageId);
184 var providerSymbol = section.Symbols.OfType<WixDependencyProviderSymbol>().Single(p => p.ParentRef == packageId);
185 var registryRoot = packageSymbol.PerMachine == true ? Registry.LocalMachine : Registry.CurrentUser;
186 var subkeyPath = Path.Combine(DependencyRegistryRoot, providerSymbol.ProviderKey);
187 using var registryKey = registryRoot.OpenSubKey(subkeyPath);
188 if (registryKey != null)
189 {
190 WixAssert.StringEqual(null, subkeyPath);
191 }
192 }
193
194 public void VerifyExeTestRegistryRootDeleted(string name, bool x64 = false)
195 {
196 using var testRegistryRoot = this.TestContext.GetTestRegistryRoot(x64, name);
197 if (testRegistryRoot != null)
198 {
199 var actualValue = testRegistryRoot.GetValue("Version") as string;
200 Assert.Null(actualValue);
201 }
202 }
203
204 public void VerifyExeTestRegistryValue(string name, string expectedValue, bool x64 = false)
205 {
206 using (var root = this.TestContext.GetTestRegistryRoot(x64, name))
207 {
208 Assert.NotNull(root);
209 var actualValue = root.GetValue("Version") as string;
210 Assert.Equal(expectedValue, actualValue);
211 }
212 }
213 }
214 }