public void InstallPackage_extract_package_success() { //given var version10 = new Version(1, 0); var packageDetails = new PackageDetails("TestNugetPackage", _nugetFeedFolder, version10); var op = new InstallPackage(); var context = new DeploymentTaskContext { Folders = new ServiceFolders { DeployFolder = (FullPath)_targetPath }, PackageDetails = packageDetails, KeepOnUpdate = FileList.Empty }; context.Parameters.Version = version10.ToString(); //when op.Execute(context); //then string[] sampleFiles = { "TestNugetPackLib.dll", }; var files = Directory .GetFiles(_targetPath) .Select(Path.GetFileName); Assert.That(sampleFiles, Is.SubsetOf(files)); }
/// <summary> /// Analyzes the transforms included in the patch package to find the ones that /// are applicable to an install package. /// </summary> /// <param name="installPackage">The install package to validate the transforms against</param> /// <returns>Array of valid transform names</returns> /// <remarks> /// The returned list does not include the "patch special transforms" that /// are prefixed with "#" If a transform is valid, then its corresponding /// special transform is assumed to be valid as well. /// </remarks> public string[] GetValidTransforms(InstallPackage installPackage) { ArrayList transformArray = new ArrayList(); string transformList = this.SummaryInfo.LastSavedBy; foreach (string transform in transformList.Split(';', ':')) { if (transform.Length != 0 && !transform.StartsWith("#", StringComparison.Ordinal)) { this.LogMessage("Checking validity of transform {0}", transform); string tempTransformFile = null; try { tempTransformFile = Path.GetTempFileName(); this.ExtractTransform(transform, tempTransformFile); if (installPackage.IsTransformValid(tempTransformFile)) { this.LogMessage("Found valid transform: {0}", transform); transformArray.Add(transform); } } finally { if (tempTransformFile != null && File.Exists(tempTransformFile)) { try { File.Delete(tempTransformFile); } catch (IOException) { } } } } } return((string[])transformArray.ToArray(typeof(string))); }
public void InstallPackage_extract_package_success() { //given var version10 = new Version(1, 0); var packageDetails = new PackageDetails("TestNugetPackage", _nugetFeedFolder, version10); var op = new InstallPackage(_targetPath, packageDetails); var stringWriter = new StringWriter(); var buildLog = new DeploymentTaskContext(stringWriter); //when op.Execute(buildLog); //then string[] sampleFiles = { "TestNugetPackLib.dll", }; var files = Directory .GetFiles(_targetPath) .Select(Path.GetFileName); Assert.That(sampleFiles, Is.SubsetOf(files)); }
private bool YieldPackage(InstallPackage package, string filename, Request request) { /* var properties = package.ExecuteStringQuery("SELECT `Property` FROM `Property` "); foreach (var i in properties) { Debug.WriteLine("Property {0} = {1}", i, package.Property[i]); } */ if (request.YieldSoftwareIdentity(filename, package.Property["ProductName"], package.Property["ProductVersion"], "multipartnumeric", package.Property["Summary"], filename, filename, filename, Path.GetFileName(filename)) != null) { var trusted = request.ProviderServices.IsSignedAndTrusted(filename, request); if (request.AddMetadata(filename, "FromTrustedSource", trusted.ToString()) == null ) { return false; } if (request.AddMetadata(filename, "ProductCode", package.Property["ProductCode"]) == null) { return false; } if (request.AddTagId(package.Property["ProductCode"].Trim(new char[] { '{', '}' })) == null) { return false; } if (request.AddMetadata(filename, "UpgradeCode", package.Property["UpgradeCode"]) == null) { return false; } return true; } return false; }
/// <summary> /// Finds packages given a locally-accessible filename /// Package information must be returned using <c>request.YieldPackage(...)</c> function. /// </summary> /// <param name="file">the full path to the file to determine if it is a package</param> /// <param name="id"> /// if this is greater than zero (and the number should have been generated using <c>StartFind(...)</c>, /// the core is calling this multiple times to do a batch search request. The operation can be delayed until /// <c>CompleteFind(...)</c> is called /// </param> /// <param name="request"> /// An object passed in from the CORE that contains functions that can be used to interact with /// the CORE and HOST /// </param> public void FindPackageByFile(string file, int id, Request request) { if( request == null ) { throw new ArgumentNullException("request"); } if( string.IsNullOrWhiteSpace(file) ) { throw new ArgumentNullException("file"); } // Nice-to-have put a debug message in that tells what's going on. request.Debug("Calling '{0}::FindPackageByFile' '{1}','{2}'", ProviderName, file, id); if (!file.FileExists()) { request.Error(ErrorCategory.ObjectNotFound, file, Constants.Messages.UnableToResolvePackage, file); return; } try { var package = new InstallPackage(file, DatabaseOpenMode.ReadOnly); YieldPackage(package, file, request); package.Close(); } catch (Exception e) { e.Dump(); // any exception at this point really just means that request.Error(ErrorCategory.OpenError, file, Constants.Messages.UnableToResolvePackage, file); } }
private static string GetPreviousVersionInstallPath() { var retVal = String.Empty; var products = ProductInstallation.GetProducts("{944871E7-9F8D-47B7-BE04-103E4C8F2254}", null, UserContexts.All); var product = products?.FirstOrDefault(); var location = product?.LocalPackage; if (location != null) { var package = new InstallPackage(location, DatabaseOpenMode.ReadOnly); var componentId = package.Files.FirstOrDefault(kvp => kvp.Value.SourceName == "UO Bulk Order Deeds.exe").Key; if (componentId != null) { var results = package.ExecuteQuery($"SELECT `ComponentId` FROM `Component` WHERE `Component` = 'C_{componentId}'"); var result = results?.Count > 0 ? results[0].ToString() : null; if (result != null) { var componentInstallation = new ComponentInstallation(result); var componentPath = componentInstallation.Path; retVal = Path.GetDirectoryName(componentPath); } } } return(retVal); }
private bool YieldPackage(InstallPackage package, string filename, Request request) { /* * var properties = package.ExecuteStringQuery("SELECT `Property` FROM `Property` "); * foreach (var i in properties) { * Debug.WriteLine("Property {0} = {1}", i, package.Property[i]); * } */ if (request.YieldSoftwareIdentity(filename, package.Property["ProductName"], package.Property["ProductVersion"], "multipartnumeric", package.Property["Summary"], filename, filename, filename, Path.GetFileName(filename))) { var trusted = request.GetPackageManagementService().As <IPackageManagementService>().ProviderServices.IsSignedAndTrusted(filename, ""); if (!request.YieldSoftwareMetadata(filename, "FromTrustedSource", trusted.ToString())) { return(false); } if (!request.YieldSoftwareMetadata(filename, "ProductCode", package.Property["ProductCode"])) { return(false); } if (!request.YieldSoftwareMetadata(filename, "UpgradeCode", package.Property["UpgradeCode"])) { return(false); } return(true); } return(false); }
private void MergeCubes(InstallPackage db) { if (!this.NoDefault) { string darice = ComponentSearcher.Find(ComponentSearcher.KnownComponent.Darice); if (!string.IsNullOrEmpty(darice)) { this.MergeCube(db, darice); } else { this.WriteWarning(Resources.Error_DefaultCubNotFound); } } if (null != this.AdditionalCube) { foreach (string cube in this.ResolveFiles(this.AdditionalCube)) { this.MergeCube(db, cube); } db.Commit(); } }
/// <summary> /// Finds packages given a locally-accessible filename /// Package information must be returned using <c>request.YieldPackage(...)</c> function. /// </summary> /// <param name="file">the full path to the file to determine if it is a package</param> /// <param name="id"> /// if this is greater than zero (and the number should have been generated using <c>StartFind(...)</c>, /// the core is calling this multiple times to do a batch search request. The operation can be delayed until /// <c>CompleteFind(...)</c> is called /// </param> /// <param name="requestImpl"> /// An object passed in from the CORE that contains functions that can be used to interact with /// the CORE and HOST /// </param> public void FindPackageByFile(string file, int id, RequestImpl requestImpl) { try { // create a strongly-typed request object. using (var request = requestImpl.As <Request>()) { // Nice-to-have put a debug message in that tells what's going on. request.Debug("Calling '{0}::FindPackageByFile' '{1}','{2}'", ProviderName, file, id); if (!file.FileExists()) { request.Error(ErrorCategory.ObjectNotFound, file, Constants.Messages.UnableToResolvePackage, file); return; } try { var package = new InstallPackage(file, DatabaseOpenMode.ReadOnly); YieldPackage(package, file, request); package.Close(); } catch (Exception e) { e.Dump(); // any exception at this point really just means that request.Error(ErrorCategory.OpenError, file, Constants.Messages.UnableToResolvePackage, file); } } } catch (Exception e) { // We shoudn't throw exceptions from here, it's not-optimal. And if the exception class wasn't properly Serializable, it'd cause other issues. // Really this is just here as a precautionary to behave correctly. // At the very least, we'll write it to the system debug channel, so a developer can find it if they are looking for it. Debug.WriteLine("Unexpected Exception thrown in '{0}::FindPackageByFile' -- {1}\\{2}\r\n{3}", ProviderName, e.GetType().Name, e.Message, e.StackTrace); } }
static ICollection <string> FindFileKeys(InstallPackage pkg, ICollection <string> fileNames) { List <string> fileKeys = null; if (fileNames != null) { fileKeys = new List <string>(); foreach (string fileName in fileNames) { string[] foundFileKeys = null; if (fileName.IndexOfAny(new char[] { '*', '?' }) >= 0) { foundFileKeys = pkg.FindFiles(FilePatternToRegex(fileName)); } else { foundFileKeys = pkg.FindFiles(fileName); } fileKeys.AddRange(foundFileKeys); } if (fileKeys.Count == 0) { throw new FileNotFoundException("Files not found in package."); } } return(fileKeys); }
private static bool DownloadAndInstallPackage(string packageName, string packageUrl, string downloadPath) { bool ok = true; InstallPackage installPackage = new InstallPackage(); ok = DownloadFile(packageName, packageUrl, downloadPath); if (ok) { try { installPackage = installPackage.LoadFromXML(Path.Combine(downloadPath, packageName)); } catch { ok = false; } if (ok) { var downloadElements = installPackage.DownloadElementToArray(); foreach (var element in downloadElements) { ok = DownloadFile(element.FileName, Path.Combine(element.Url, element.Subdir), Path.Combine(downloadPath, element.Subdir)); if (!ok) { break; } } } } return(ok); }
protected Database OpenDatabase(string path) { var type = FileInfo.GetFileTypeInternal(path); if (FileType.Package == type) { var db = new InstallPackage(path, DatabaseOpenMode.ReadOnly); this.ApplyTransforms(db); return(db); } else if (FileType.Patch == type) { return(new PatchPackage(path)); } else { var message = string.Format(Resources.Error_InvalidStorage, path); var ex = new PSNotSupportedException(message); if (null != ex.ErrorRecord) { base.WriteError(ex.ErrorRecord); } return(null); } }
static void Main(string[] args) { using (var package = new InstallPackage(@"C:\test.msi", DatabaseOpenMode.ReadOnly)) { package.ExtractFiles(); } }
/// <summary> /// Extracts files from an MSI database and rewrites the paths embedded in the source .wixpdb to the output .wixpdb. /// </summary> private void MeltProduct() { // print friendly message saying what file is being decompiled Console.WriteLine("{0} / {1}", Path.GetFileName(this.inputFile), Path.GetFileName(this.inputPdbFile)); // extract files from the .msi (unless suppressed) and get the path map of File ids to target paths string outputDirectory = this.exportBasePath ?? Environment.GetEnvironmentVariable("WIX_TEMP"); IDictionary <string, string> paths = null; using (InstallPackage package = new InstallPackage(this.inputFile, DatabaseOpenMode.ReadOnly, null, outputDirectory)) { if (!this.suppressExtraction) { package.ExtractFiles(); } paths = package.Files.SourcePaths; } Pdb inputPdb = Pdb.Load(this.inputPdbFile, true, true); Table wixFileTable = inputPdb.Output.Tables["WixFile"]; if (null != wixFileTable) { foreach (Row row in wixFileTable.Rows) { WixFileRow fileRow = row as WixFileRow; if (null != fileRow) { string newPath; if (paths.TryGetValue(fileRow.File, out newPath)) { fileRow.Source = Path.Combine(outputDirectory, newPath); } } } } string tempPath = Path.Combine(Environment.GetEnvironmentVariable("WIX_TEMP") ?? Path.GetTempPath(), Path.GetRandomFileName()); try { inputPdb.Save(this.outputFile, null, null, tempPath); } finally { if (this.tidy) { if (!AppCommon.DeleteDirectory(tempPath, this.messageHandler)) { Console.WriteLine(MeltStrings.WAR_FailedToDeleteTempDir, tempPath); } } else { Console.WriteLine(MeltStrings.INF_TempDirLocatedAt, tempPath); } } }
private void InstallAdditionalPackages() { ThreadPool.QueueUserWorkItem((ctx) => { InstallPackage installer = new InstallPackage(); installer.Run(); }); }
/// <summary> /// Initializes a new instance of the <see cref="PatchApplicator"/> class. /// </summary> /// <param name="db">The <see cref="InstallPackage"/> to transform.</param> internal PatchApplicator(InstallPackage db) { if (null == db) { throw new ArgumentNullException("db"); } this.db = db; this.sequencer = new PatchSequencer(); }
public void NoTransformViewChanges() { var package = Path.Combine(base.TestContext.DeploymentDirectory, "Example.msi"); using (var db = new InstallPackage(package, DatabaseOpenMode.ReadOnly)) { var view = new TransformView(db); Assert.AreEqual <int>(0, view.Tables.Count); } }
public static Response AsNewPackage(this IResponseFormatter formatter, InstallPackage package, PackageManifest manifest) { string fileName = Path.GetFileName(package.Path); string url = string.Format("{0}/{1}", formatter.Context.Request.Url, fileName); return(new Response { StatusCode = HttpStatusCode.Created } .WithHeader("Location", url)); }
public static void Main(string[] args) { currentDir = Directory.GetCurrentDirectory(); DirSearch(currentDir); InstallPackage installSettings = new InstallPackage(); foreach (var element in downloadList) { installSettings.AddDownloadElement(element); } installSettings.SaveToXML(Path.Combine(currentDir, installFileName)); }
static void Main(string[] args) { string path = @"... myfile.msi"; using (InstallPackage package = new InstallPackage(path, DatabaseOpenMode.ReadOnly)) { foreach (var kvp in package.Files.Where(f => Path.GetExtension(f.Value.TargetName) == ".dll")) { Console.WriteLine(kvp.Value.TargetName); } } }
static void Main(string[] args) { using (var package = new InstallPackage("foo.msi", DatabaseOpenMode.ReadOnly)) { foreach (var filePath in package.Files) { Console.WriteLine(filePath.Value); } Console.WriteLine("Finished"); Console.Read(); } }
protected void Page_Load(object sender, EventArgs e) { if (Request.QueryString["force"] == "1") { InstallPackage.ResetInstallState(); } ThreadPool.QueueUserWorkItem((ctx) => { InstallPackage installer = new InstallPackage(); installer.Run(); }); }
/// <summary> /// Extracts the files contained in the msi. /// </summary> /// <param name="msiFile">The msi file to extract.</param> /// <param name="path">The path to extract the files to.</param> /// <returns>List of files in MSI.</returns> public string[] ExtractFilesInMsi(string msiFile, string path) { _ = msiFile ?? throw new ArgumentNullException(nameof(msiFile)); _ = path ?? throw new ArgumentNullException(nameof(path)); using (var package = new InstallPackage(msiFile, DatabaseOpenMode.ReadOnly, null, path)) { package.ExtractFiles(); } var msiFiles = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories); return msiFiles; }
private static InstallPackage Copy(InstallPackage db) { var temp = Path.ChangeExtension(Path.GetTempFileName(), ".msi"); File.Copy(db.FilePath, temp, true); // Open a copy and schedule delete it when closed. var copy = new InstallPackage(temp, DatabaseOpenMode.ReadOnly); copy.DeleteOnClose(temp); return(copy); }
/// <summary> /// Opens the package read-only and sets the <see cref="InstallCommandActionData.ProductCode"/> property. /// </summary> public void SetProductCode() { using (var db = new InstallPackage(this.Path, DatabaseOpenMode.ReadOnly)) { if (db.Tables.Contains("Property")) { this.ProductCode = db.Property["ProductCode"]; } else { this.ProductCode = null; } } }
/// <summary> /// Applies any applicable transforms from <see cref="Patch"/> and <see cref="Transform"/> to the given package. /// </summary> /// <param name="db">The <see cref="InstallPackage"/> database to which applicable transforms are applied.</param> protected void ApplyTransforms(InstallPackage db) { // Apply transforms first since they likely apply to the unpatched product. if (0 < this.Transform.Count()) { this.Transform = this.ResolveFiles(this.Transform).ToArray(); foreach (string path in this.Transform) { try { db.ApplyTransform(path, PatchApplicator.IgnoreErrors); db.ApplyTransform(path, PatchApplicator.IgnoreErrors | TransformErrors.ViewTransform); } catch (InstallerException ex) { using (var pse = new PSInstallerException(ex)) { if (null != pse.ErrorRecord) { base.WriteError(pse.ErrorRecord); } } } } db.Commit(); } // Apply applicable patch transforms. if (0 < this.Patch.Count()) { this.Patch = this.ResolveFiles(this.Patch).ToArray(); var applicator = new PatchApplicator(db); foreach (string path in this.Patch) { applicator.Add(path); } applicator.InapplicablePatch += (source, args) => { var message = string.Format(CultureInfo.CurrentCulture, Resources.Error_InapplicablePatch, args.Patch, args.Product); base.WriteVerbose(message); }; // The applicator will commit the changes. applicator.Apply(); } }
public MsiManager(string msiFile) { _msiFile = msiFile; var ispackage = Installer.VerifyPackage(msiFile); if (!ispackage) { throw new ArgumentException("Not a valid MSI file", msiFile); } _installPackage = new InstallPackage(msiFile, DatabaseOpenMode.ReadOnly); _productCode = _installPackage.Property["ProductCode"]; }
private dynamic InstallUploadPackage(dynamic o) { try { var file = Request.Files.FirstOrDefault(); var uploadPackage = this.Bind <InstallUploadPackage>(); if (file == null) { return(new Response { StatusCode = HttpStatusCode.BadRequest }); } PackageManifest manifest; try { var package = new InstallPackage { Path = _tempPackager.GetPackageToInstall(file.Value), DisableIndexing = uploadPackage.DisableIndexing, EnableSecurityInstall = uploadPackage.EnableSecurityInstall }; manifest = _repository.AddPackage(package); _installationRecorder.RecordInstall(uploadPackage.PackageId, uploadPackage.Description, DateTime.Now); } finally { _tempPackager.Dispose(); } if (uploadPackage.DisableManifest) { // Skip manifest reporting. Nancy will return an empty message body. manifest = null; } return(Response .AsJson(manifest, HttpStatusCode.Created) .WithHeader("Location", ShipServiceUrl.PackageLatestVersion)); } catch (NotFoundException) { return(new Response { StatusCode = HttpStatusCode.NotFound }); } }
public static List <InstallPackage> GetInstallPackages() { var detectedPackages = new List <InstallPackage>(); var contentPath = Path.Combine(Origin.DataPath, "LocalContent"); if (Directory.Exists(contentPath)) { var packages = Directory.GetFiles(contentPath, "*.mfst", SearchOption.AllDirectories); foreach (var package in packages) { try { var installPackage = new InstallPackage(); var gameId = Path.GetFileNameWithoutExtension(package); installPackage.OriginalId = gameId; installPackage.ConvertedId = gameId; if (!gameId.StartsWith("Origin")) { // Get game id by fixing file via adding : before integer part of the name // for example OFB-EAST52017 converts to OFB-EAST:52017 var match = Regex.Match(gameId, @"^(.*?)(\d+)$"); if (!match.Success) { logger.Warn("Failed to get game id from file " + package); continue; } gameId = match.Groups[1].Value + ":" + match.Groups[2].Value; } var subTypeIndex = gameId.IndexOf('@'); if (subTypeIndex >= 0) { installPackage.Source = gameId.Substring(subTypeIndex); gameId = gameId.Substring(0, subTypeIndex); } installPackage.ConvertedId = gameId; detectedPackages.Add(installPackage); } catch (Exception e) when(!Environment.IsDebugBuild) { logger.Error(e, $"Failed to parse Origin install pacakge {package}."); } } } return(detectedPackages); }
public override bool Execute() { try { using (var package = new InstallPackage(InstallPackage, 0)) { Value = package.Property[Property]; } } catch (Exception exception) { Log.LogErrorFromException(exception); } return(!Log.HasLoggedErrors); }
/// <summary> /// Installs a given package. /// </summary> /// <param name="fastPackageReference">A provider supplied identifier that specifies an exact package</param> /// <param name="request"> /// An object passed in from the CORE that contains functions that can be used to interact with /// the CORE and HOST /// </param> public void InstallPackage(string fastPackageReference, Request request) { if( request == null ) { throw new ArgumentNullException("request"); } if( string.IsNullOrWhiteSpace(fastPackageReference) ) { throw new ArgumentNullException("fastPackageReference"); } // Nice-to-have put a debug message in that tells what's going on. request.Debug("Calling '{0}::InstallPackage' '{1}'", ProviderName, fastPackageReference); var file = fastPackageReference.CanonicalizePath(false); if (!file.FileExists()) { request.Error(Microsoft.PackageManagement.Internal.ErrorCategory.OpenError, fastPackageReference, Constants.Messages.UnableToResolvePackage, fastPackageReference); return; } string errorLogFolder = Path.GetTempPath() + Guid.NewGuid(); DirectoryInfo errorDir = Directory.CreateDirectory(errorLogFolder); string errorLogPath = errorLogFolder + "\\msi.log"; try { var package = new InstallPackage(file, DatabaseOpenMode.ReadOnly); Installer.SetInternalUI(InstallUIOptions.UacOnly | InstallUIOptions.Silent); // todo 1501: support additional parameters! if (request.Sources != null && request.Sources.Any()) { // The 'file' can be from a temp location downloaded by a chained provider. In that case, we can show // the orignal package source specified in the request.Sources. _progressId = request.StartProgress(0, Resources.Messages.InstallingMSIPackage, request.Sources.FirstOrDefault()); } else { _progressId = request.StartProgress(0, Resources.Messages.InstallingMSIPackage, file); } var handler = CreateProgressHandler(request, Resources.Messages.Installing); Installer.SetExternalUI(handler, InstallLogModes.Progress | InstallLogModes.Info); Installer.EnableLog(InstallLogModes.Error, errorLogPath); Installer.InstallProduct(file, "REBOOT=REALLYSUPPRESS"); Installer.SetInternalUI(InstallUIOptions.Default); Installer.SetExternalUI(handler, InstallLogModes.None); if (request.Sources != null && request.Sources.Any()) { // The 'file' can be from a temp location downloaded by a chained provider. In that case, we can show // the orignal package source specified in the request.Sources. YieldPackage(package, request.Sources.FirstOrDefault(), request); } else { YieldPackage(package, file, request); } package.Close(); if (Installer.RebootRequired) { request.Warning(Resources.Messages.InstallRequireReboot); } if (errorDir.Exists) errorDir.Delete(true); } catch (Exception e) { e.Dump(); request.Error(Microsoft.PackageManagement.Internal.ErrorCategory.InvalidOperation, file, Constants.Messages.PackageFailedInstallErrorLog, file, errorLogPath); } request.CompleteProgress(_progressId, true); }
private bool YieldPackage(InstallPackage package, string filename, Request request) { /* var properties = package.ExecuteStringQuery("SELECT `Property` FROM `Property` "); foreach (var i in properties) { Debug.WriteLine("Property {0} = {1}", i, package.Property[i]); } */ if (request.YieldSoftwareIdentity(filename, package.Property["ProductName"], package.Property["ProductVersion"], "multipartnumeric", package.Property["Summary"], filename, filename, filename, Path.GetFileName(filename)) != null) { var trusted = request.ProviderServices.IsSignedAndTrusted(filename, request); if (request.AddMetadata(filename, "FromTrustedSource", trusted.ToString()) == null ) { return false; } if (request.AddMetadata(filename, "ProductCode", package.Property["ProductCode"]) == null) { return false; } if (request.AddMetadata(filename, "UpgradeCode", package.Property["UpgradeCode"]) == null) { return false; } return true; } return false; }
/// <summary> /// Installs a given package. /// </summary> /// <param name="fastPackageReference">A provider supplied identifier that specifies an exact package</param> /// <param name="request"> /// An object passed in from the CORE that contains functions that can be used to interact with /// the CORE and HOST /// </param> public void InstallPackage(string fastPackageReference, Request request) { if( request == null ) { throw new ArgumentNullException("request"); } if( string.IsNullOrWhiteSpace(fastPackageReference) ) { throw new ArgumentNullException("fastPackageReference"); } // Nice-to-have put a debug message in that tells what's going on. request.Debug("Calling '{0}::InstallPackage' '{1}'", ProviderName, fastPackageReference); var file = fastPackageReference.CanonicalizePath(false); if (!file.FileExists()) { request.Error(ErrorCategory.OpenError, fastPackageReference, Constants.Messages.UnableToResolvePackage, fastPackageReference); return; } try { var package = new InstallPackage(file, DatabaseOpenMode.ReadOnly); Installer.SetInternalUI(InstallUIOptions.UacOnly | InstallUIOptions.Silent); // todo 1501: support additional parameters! var handler = CreateProgressHandler(request); _progressId = request.StartProgress(0, "Installing MSI '{0}'", file); Installer.SetExternalUI(handler, InstallLogModes.Progress | InstallLogModes.Info); Installer.InstallProduct(file, "REBOOT=REALLYSUPPRESS"); Installer.SetInternalUI(InstallUIOptions.Default); Installer.SetExternalUI(handler, InstallLogModes.None); YieldPackage(package, file, request); package.Close(); if (Installer.RebootRequired) { request.Warning("Reboot is required to complete Installation."); } } catch (Exception e) { e.Dump(); request.Error(ErrorCategory.InvalidOperation, file, Constants.Messages.UnableToResolvePackage, file); } request.CompleteProgress(_progressId, true); }