internal IRequest ExtendRequest(RequestImpl requestImpl, params object[] objects) { var baseGetMessageString = requestImpl.As <GetMessageString>(); return(requestImpl.Extend <IRequest>(new { // check the caller's resource manager first, then fall back to this resource manager GetMessageString = new Func <string, string>((s) => baseGetMessageString(s) ?? Messages.ResourceManager.GetString(s)), }, objects, AdditionalImplementedFunctions)); }
public bool RequirePackageProvider(string requestor, string packageProviderName, string minimumVersion, IRequestObject requestObject) { // check if the package provider is already installed if (_packageProviders.ContainsKey(packageProviderName)) { var current = _packageProviders[packageProviderName].Version; if (current >= minimumVersion) { return(true); } } var request = requestObject.As <IRequest>(); var currentCallCount = request.CallCount(); if (_lastCallCount >= currentCallCount) { // we've already been here this call. // are they asking for the same provider again? if (_providersTriedThisCall.Contains(packageProviderName)) { request.Debug("Skipping RequirePackageProvider -- tried once this call previously."); return(false); } // remember this in case we come back again. _providersTriedThisCall.Add(packageProviderName); } else { _lastCallCount = currentCallCount; _providersTriedThisCall = new HashSet <string> { packageProviderName }; } if (!request.IsInteractive()) { request.Debug("Skipping RequirePackageProvider due to not interactive"); // interactive indicates that the host can respond to queries -- this doesn't happen // in powershell during tab-completion. return(false); } // no? // ask the bootstrap provider if there is a package provider with that name available. var bootstrap = _packageProviders["Bootstrap"]; if (bootstrap == null) { request.Debug("Skipping RequirePackageProvider due to missing bootstrap provider"); return(false); } var pkg = bootstrap.FindPackage(packageProviderName, null, minimumVersion, null, 0, requestObject).ToArray(); if (pkg.Length == 1) { // Yeah? Install it. var package = pkg[0]; var metaWithProviderType = pkg[0].Meta.FirstOrDefault(each => each.ContainsKey("providerType")); var providerType = metaWithProviderType == null ? "unknown" : metaWithProviderType["providerType"]; var destination = providerType == "assembly" ? (AdminPrivilege.IsElevated ? SystemAssemblyLocation : UserAssemblyLocation) : string.Empty; var link = package.Links.FirstOrDefault(each => each.Relationship == "installationmedia"); var location = string.Empty; if (link != null) { location = link.HRef; } // what can't find an installationmedia link? // todo: what should we say here? if (request.ShouldBootstrapProvider(requestor, pkg[0].Name, pkg[0].Version, providerType, location, destination)) { var newRequest = requestObject.Extend <IRequest>(new { GetOptionValues = new Func <string, IEnumerable <string> >(key => { if (key == "DestinationPath") { return(new[] { destination }); } return(new string[0]); }) }); var packagesInstalled = bootstrap.InstallPackage(pkg[0], newRequest).LastOrDefault(); if (packagesInstalled == null) { // that's sad. request.Error(Constants.Messages.FailedProviderBootstrap, ErrorCategory.InvalidOperation.ToString(), package.Name, request.FormatMessageString(Constants.Messages.FailedProviderBootstrap, package.Name)); return(false); } // so it installed something // we must tell the plugin loader to reload the plugins again. LoadProviders(request); return(true); } } return(false); }