/// <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); } }
/// <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); } }
/// <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); }
/// <summary> /// Installs a given package. /// </summary> /// <param name="fastPackageReference">A provider supplied identifier that specifies an exact package</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 InstallPackage(string fastPackageReference, 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}::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); 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); } } 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}::InstallPackage' -- {1}\\{2}\r\n{3}", ProviderName, e.GetType().Name, e.Message, e.StackTrace); } }
/// <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); }
/// <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); }
/// <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); }