Exemplo n.º 1
0
        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);
        }