CheckInstalledStatusInterop.cs (22915B)
1 // ----------------------------------------------------------------------------- 2 // <copyright file="CheckInstalledStatusInterop.cs" company="Microsoft Corporation"> 3 // Copyright (c) Microsoft Corporation. Licensed under the MIT License. 4 // </copyright> 5 // ----------------------------------------------------------------------------- 6 7 namespace AppInstallerCLIE2ETests.Interop 8 { 9 using System; 10 using System.IO; 11 using System.Threading.Tasks; 12 using AppInstallerCLIE2ETests.Helpers; 13 using Microsoft.Management.Deployment; 14 using Microsoft.Management.Deployment.Projection; 15 using NUnit.Framework; 16 using WinRT; 17 18 /// <summary> 19 /// Tests check installed status. 20 /// </summary> 21 [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.InProcess), Category = nameof(InstanceInitializersSource.InProcess))] 22 [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.OutOfProcess), Category = nameof(InstanceInitializersSource.OutOfProcess))] 23 public class CheckInstalledStatusInterop : BaseInterop 24 { 25 private string installDir; 26 private string defaultInstallDir = Path.Combine(Path.GetTempPath(), "TestInstalledStatus"); 27 private PackageManager packageManager; 28 private PackageCatalogReference testSource; 29 30 /// <summary> 31 /// Initializes a new instance of the <see cref="CheckInstalledStatusInterop"/> class. 32 /// </summary> 33 /// <param name="initializer">Initializer.</param> 34 public CheckInstalledStatusInterop(IInstanceInitializer initializer) 35 : base(initializer) 36 { 37 } 38 39 /// <summary> 40 /// Test setup. 41 /// </summary> 42 [SetUp] 43 public void SetUp() 44 { 45 this.packageManager = this.TestFactory.CreatePackageManager(); 46 this.testSource = this.packageManager.GetPackageCatalogByName(Constants.TestSourceName); 47 this.installDir = TestCommon.GetRandomTestDir(); 48 } 49 50 /// <summary> 51 /// Clean up. 52 /// </summary> 53 /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> 54 [TearDown] 55 public async Task Cleanup() 56 { 57 // Find and uninstall the test package if applicable. 58 var options = this.TestFactory.CreateCreateCompositePackageCatalogOptions(); 59 options.Catalogs.Add(this.testSource); 60 options.CompositeSearchBehavior = CompositeSearchBehavior.AllCatalogs; 61 var compositeSource = this.packageManager.CreateCompositePackageCatalog(options); 62 var searchResult = this.FindOnePackage(compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestCheckInstalledStatus"); 63 if (searchResult.CatalogPackage.InstalledVersion != null) 64 { 65 var uninstallOptions = this.TestFactory.CreateUninstallOptions(); 66 var uninstallResult = await this.packageManager.UninstallPackageAsync(searchResult.CatalogPackage, uninstallOptions); 67 Assert.AreEqual(UninstallResultStatus.Ok, uninstallResult.Status); 68 } 69 70 // Remove default install location 71 if (Directory.Exists(this.defaultInstallDir)) 72 { 73 Directory.Delete(this.defaultInstallDir, true); 74 } 75 } 76 77 /// <summary> 78 /// Tests arp entries match. 79 /// </summary> 80 /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> 81 [Test] 82 public async Task CheckInstalledStatusArpVersionMatched() 83 { 84 // Find and install the test package. 85 var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestCheckInstalledStatus"); 86 var installOptions = this.TestFactory.CreateInstallOptions(); 87 installOptions.ReplacementInstallerArguments = $"/InstallDir {this.installDir} /ProductID CheckInstalledStatusProductId /DisplayName TestCheckInstalledStatus /Version 1.0"; 88 var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions); 89 Assert.AreEqual(InstallResultStatus.Ok, installResult.Status); 90 91 // Add the data file listed in the manifest 92 File.WriteAllText(Path.Combine(this.installDir, "data.txt"), "Test"); 93 94 // Search from composite source again after installation 95 var options = this.TestFactory.CreateCreateCompositePackageCatalogOptions(); 96 options.Catalogs.Add(this.testSource); 97 options.CompositeSearchBehavior = CompositeSearchBehavior.AllCatalogs; 98 var compositeSource = this.packageManager.CreateCompositePackageCatalog(options); 99 searchResult = this.FindOnePackage(compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestCheckInstalledStatus"); 100 101 // Check installed status 102 var checkResult = await searchResult.CatalogPackage.CheckInstalledStatusAsync(); 103 Assert.AreEqual(CheckInstalledStatusResultStatus.Ok, checkResult.Status); 104 Assert.AreEqual(1, checkResult.PackageInstalledStatus.Count); 105 106 // Installer info 107 var installerInstalledStatus = checkResult.PackageInstalledStatus[0]; 108 Assert.AreEqual(Windows.System.ProcessorArchitecture.Neutral, installerInstalledStatus.InstallerInfo.Architecture); 109 Assert.AreEqual(PackageInstallerType.Exe, installerInstalledStatus.InstallerInfo.InstallerType); 110 Assert.AreEqual(PackageInstallerType.Unknown, installerInstalledStatus.InstallerInfo.NestedInstallerType); 111 Assert.AreEqual(PackageInstallerScope.Unknown, installerInstalledStatus.InstallerInfo.Scope); 112 113 // Installer status 114 Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntry, installerInstalledStatus.InstallerInstalledStatus[0].Type); 115 Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[0])); 116 Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocation, installerInstalledStatus.InstallerInstalledStatus[1].Type); 117 Assert.AreEqual(this.installDir, installerInstalledStatus.InstallerInstalledStatus[1].Path); 118 Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[1])); 119 Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[2].Type); 120 Assert.AreEqual(Path.Combine(this.installDir, "data.txt"), installerInstalledStatus.InstallerInstalledStatus[2].Path); 121 Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[2])); 122 Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[3].Type); 123 Assert.AreEqual(Path.Combine(this.installDir, "TestExeInstalled.txt"), installerInstalledStatus.InstallerInstalledStatus[3].Path); 124 Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[3])); 125 Assert.AreEqual(InstalledStatusType.DefaultInstallLocation, installerInstalledStatus.InstallerInstalledStatus[4].Type); 126 Assert.AreEqual(this.defaultInstallDir, Path.GetFullPath(installerInstalledStatus.InstallerInstalledStatus[4].Path)); 127 Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_INSTALL_LOCATION_NOT_FOUND, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[4])); 128 } 129 130 /// <summary> 131 /// Test arp entries no version matched. 132 /// </summary> 133 /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> 134 [Test] 135 public async Task CheckInstalledStatusArpVersionNotMatched() 136 { 137 // Find and install the test package. 138 var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestCheckInstalledStatus"); 139 var installOptions = this.TestFactory.CreateInstallOptions(); 140 installOptions.ReplacementInstallerArguments = $"/InstallDir {this.installDir} /ProductID CheckInstalledStatusProductId /DisplayName TestCheckInstalledStatus /Version 2.0"; 141 var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions); 142 Assert.AreEqual(InstallResultStatus.Ok, installResult.Status); 143 144 // Add the data file listed in the manifest 145 File.WriteAllText(Path.Combine(this.installDir, "data.txt"), "Test"); 146 147 // Search from composite source again after installation 148 var options = this.TestFactory.CreateCreateCompositePackageCatalogOptions(); 149 options.Catalogs.Add(this.testSource); 150 options.CompositeSearchBehavior = CompositeSearchBehavior.AllCatalogs; 151 var compositeSource = this.packageManager.CreateCompositePackageCatalog(options); 152 searchResult = this.FindOnePackage(compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestCheckInstalledStatus"); 153 154 // Check installed status 155 var checkResult = await searchResult.CatalogPackage.CheckInstalledStatusAsync(InstalledStatusType.AllAppsAndFeaturesEntryChecks); 156 Assert.AreEqual(CheckInstalledStatusResultStatus.Ok, checkResult.Status); 157 Assert.AreEqual(1, checkResult.PackageInstalledStatus.Count); 158 159 var installerInstalledStatus = checkResult.PackageInstalledStatus[0]; 160 Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntry, installerInstalledStatus.InstallerInstalledStatus[0].Type); 161 Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[0])); 162 Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocation, installerInstalledStatus.InstallerInstalledStatus[1].Type); 163 Assert.AreEqual(this.installDir, installerInstalledStatus.InstallerInstalledStatus[1].Path); 164 Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[1])); 165 Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[2].Type); 166 Assert.AreEqual(Path.Combine(this.installDir, "data.txt"), installerInstalledStatus.InstallerInstalledStatus[2].Path); 167 Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[2])); 168 Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[3].Type); 169 Assert.AreEqual(Path.Combine(this.installDir, "TestExeInstalled.txt"), installerInstalledStatus.InstallerInstalledStatus[3].Path); 170 Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[3])); 171 } 172 173 /// <summary> 174 /// Test arp entries file not found. 175 /// </summary> 176 /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> 177 [Test] 178 public async Task CheckInstalledStatusArpVersionMatchedFileNotFound() 179 { 180 // Find and install the test package. 181 var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestCheckInstalledStatus"); 182 var installOptions = this.TestFactory.CreateInstallOptions(); 183 installOptions.ReplacementInstallerArguments = $"/InstallDir {this.installDir} /ProductID CheckInstalledStatusProductId /DisplayName TestCheckInstalledStatus /Version 1.0"; 184 var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions); 185 Assert.AreEqual(InstallResultStatus.Ok, installResult.Status); 186 187 // Search from composite source again after installation 188 var options = this.TestFactory.CreateCreateCompositePackageCatalogOptions(); 189 options.Catalogs.Add(this.testSource); 190 options.CompositeSearchBehavior = CompositeSearchBehavior.AllCatalogs; 191 var compositeSource = this.packageManager.CreateCompositePackageCatalog(options); 192 searchResult = this.FindOnePackage(compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestCheckInstalledStatus"); 193 194 // Check installed status 195 var checkResult = await searchResult.CatalogPackage.CheckInstalledStatusAsync(InstalledStatusType.AllAppsAndFeaturesEntryChecks); 196 Assert.AreEqual(CheckInstalledStatusResultStatus.Ok, checkResult.Status); 197 Assert.AreEqual(1, checkResult.PackageInstalledStatus.Count); 198 199 var installerInstalledStatus = checkResult.PackageInstalledStatus[0]; 200 Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntry, installerInstalledStatus.InstallerInstalledStatus[0].Type); 201 Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[0])); 202 Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocation, installerInstalledStatus.InstallerInstalledStatus[1].Type); 203 Assert.AreEqual(this.installDir, installerInstalledStatus.InstallerInstalledStatus[1].Path); 204 Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[1])); 205 Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[2].Type); 206 Assert.AreEqual(Path.Combine(this.installDir, "data.txt"), installerInstalledStatus.InstallerInstalledStatus[2].Path); 207 Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_FILE_NOT_FOUND, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[2])); 208 Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[3].Type); 209 Assert.AreEqual(Path.Combine(this.installDir, "TestExeInstalled.txt"), installerInstalledStatus.InstallerInstalledStatus[3].Path); 210 Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[3])); 211 } 212 213 /// <summary> 214 /// Test arp entries hash mismatch. 215 /// </summary> 216 /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> 217 [Test] 218 public async Task CheckInstalledStatusArpVersionMatchedFileHashMisMatch() 219 { 220 // Find and install the test package. 221 var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestCheckInstalledStatus"); 222 var installOptions = this.TestFactory.CreateInstallOptions(); 223 installOptions.ReplacementInstallerArguments = $"/InstallDir {this.installDir} /ProductID CheckInstalledStatusProductId /DisplayName TestCheckInstalledStatus /Version 1.0"; 224 var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions); 225 Assert.AreEqual(InstallResultStatus.Ok, installResult.Status); 226 227 // Add the data file listed in the manifest 228 File.WriteAllText(Path.Combine(this.installDir, "data.txt"), "WrongData"); 229 230 // Search from composite source again after installation 231 var options = this.TestFactory.CreateCreateCompositePackageCatalogOptions(); 232 options.Catalogs.Add(this.testSource); 233 options.CompositeSearchBehavior = CompositeSearchBehavior.AllCatalogs; 234 var compositeSource = this.packageManager.CreateCompositePackageCatalog(options); 235 searchResult = this.FindOnePackage(compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestCheckInstalledStatus"); 236 237 // Check installed status 238 var checkResult = await searchResult.CatalogPackage.CheckInstalledStatusAsync(InstalledStatusType.AllAppsAndFeaturesEntryChecks); 239 Assert.AreEqual(CheckInstalledStatusResultStatus.Ok, checkResult.Status); 240 Assert.AreEqual(1, checkResult.PackageInstalledStatus.Count); 241 242 var installerInstalledStatus = checkResult.PackageInstalledStatus[0]; 243 Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntry, installerInstalledStatus.InstallerInstalledStatus[0].Type); 244 Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[0])); 245 Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocation, installerInstalledStatus.InstallerInstalledStatus[1].Type); 246 Assert.AreEqual(this.installDir, installerInstalledStatus.InstallerInstalledStatus[1].Path); 247 Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[1])); 248 Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[2].Type); 249 Assert.AreEqual(Path.Combine(this.installDir, "data.txt"), installerInstalledStatus.InstallerInstalledStatus[2].Path); 250 Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_FILE_HASH_MISMATCH, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[2])); 251 Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[3].Type); 252 Assert.AreEqual(Path.Combine(this.installDir, "TestExeInstalled.txt"), installerInstalledStatus.InstallerInstalledStatus[3].Path); 253 Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[3])); 254 } 255 256 /// <summary> 257 /// Test arp entries default install location not found. 258 /// </summary> 259 /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> 260 [Test] 261 public async Task CheckInstalledStatusArpNotFoundDefaultInstallLocationFound() 262 { 263 // Add the data file listed in the manifest to default install location. 264 Directory.CreateDirectory(this.defaultInstallDir); 265 File.WriteAllText(Path.Combine(this.defaultInstallDir, "data.txt"), "Test"); 266 267 // Search from composite source without installation 268 var options = this.TestFactory.CreateCreateCompositePackageCatalogOptions(); 269 options.Catalogs.Add(this.testSource); 270 options.CompositeSearchBehavior = CompositeSearchBehavior.AllCatalogs; 271 var compositeSource = this.packageManager.CreateCompositePackageCatalog(options); 272 var searchResult = this.FindOnePackage(compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestCheckInstalledStatus"); 273 274 // Check installed status 275 var checkResult = await searchResult.CatalogPackage.CheckInstalledStatusAsync(); 276 Assert.AreEqual(CheckInstalledStatusResultStatus.Ok, checkResult.Status); 277 Assert.AreEqual(1, checkResult.PackageInstalledStatus.Count); 278 279 var installerInstalledStatus = checkResult.PackageInstalledStatus[0]; 280 Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntry, installerInstalledStatus.InstallerInstalledStatus[0].Type); 281 Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_ARP_ENTRY_NOT_FOUND, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[0])); 282 Assert.AreEqual(InstalledStatusType.DefaultInstallLocation, installerInstalledStatus.InstallerInstalledStatus[1].Type); 283 Assert.AreEqual(this.defaultInstallDir, Path.GetFullPath(installerInstalledStatus.InstallerInstalledStatus[1].Path)); 284 Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[1])); 285 Assert.AreEqual(InstalledStatusType.DefaultInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[2].Type); 286 Assert.AreEqual(Path.Combine(this.defaultInstallDir, "data.txt"), Path.GetFullPath(installerInstalledStatus.InstallerInstalledStatus[2].Path)); 287 Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[2])); 288 Assert.AreEqual(InstalledStatusType.DefaultInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[3].Type); 289 Assert.AreEqual(Path.Combine(this.defaultInstallDir, "TestExeInstalled.txt"), Path.GetFullPath(installerInstalledStatus.InstallerInstalledStatus[3].Path)); 290 Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_FILE_NOT_FOUND, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[3])); 291 } 292 293 // CsWinrt maps success error codes(e.g. INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE) to null exception. 294 // In this case we cannot get the exact hresult by calling winrt projection api. 295 // This method is created to directly get hresult from the InstalledStatus object for the tests to compare. 296 private static unsafe int GetHResultFromInstalledStatus(InstalledStatus status) 297 { 298 if (status.Status != null) 299 { 300 return status.Status.HResult; 301 } 302 else 303 { 304 IObjectReference objRef = ((IWinRTObject)status).NativeObject; 305 ABI.System.Exception exception = default; 306 (*(delegate* unmanaged[Stdcall] <IntPtr, out global::ABI.System.Exception, int>**)objRef.ThisPtr)[8](objRef.ThisPtr, out exception); 307 return exception.hr; 308 } 309 } 310 } 311 }