コード例 #1
0
ファイル: Yieldable.cs プロジェクト: 40a/PowerShell
 protected virtual bool YieldDetails(PsRequest r) {
     if (_details != null && _details.Count > 0) {
         // we need to send this back as a set of key/path & value  pairs.
         return _details.Flatten().All(kvp => r.YieldKeyValuePair(kvp.Key, kvp.Value));
     }
     return true;
 }
コード例 #2
0
        private PackageProvider AnalyzeModule(PsRequest request, string modulePath, Version requiredVersion, bool force, bool logWarning =true, PSModuleInfo psModuleInfo = null)
        {
            if (string.IsNullOrWhiteSpace(modulePath)) {
                return null;
            }

            request.Debug("Attempting to load PowerShell Provider Module [{0}]", modulePath);

            if (string.Equals(Path.GetExtension(modulePath), ".dll", StringComparison.OrdinalIgnoreCase))
            {
                if (psModuleInfo != null)
                {
                    // fake provider and returns it
                    var result = new PackageProvider(new DefaultPackageProvider(psModuleInfo.Name, psModuleInfo.Version.ToString()))
                    {
                        ProviderPath = modulePath,
                        Version = psModuleInfo.Version,
                        IsLoaded = false
                    };

                    AddToPackageProviderCacheTable(result);

                    return result;
                }
                else
                {
                    // psmoduleinfo is only null when this function is called in loadavailableprovider
                    // but in that case we want to load the provider directly anyway so we can do this
                    // if the path is a .dll then we ask packagemanagement to load it for us
                    // it will also register the dll
                    PackageManagementService.LoadProviderAssembly(request, modulePath, true);

                    // now let's checked whether we can find it in the list of loaded providers
                    foreach (var loadedProvider in PackageManagementService.PackageProviders)
                    {
                        // the one loaded should have the same path
                        if (string.Equals(loadedProvider.ProviderPath, modulePath, StringComparison.OrdinalIgnoreCase))
                        {
                            return loadedProvider;
                        }
                    }

                    // if we reached here then we have failed to load the provider :(
                    return null;
                }                
            }

            string requiredVersionString = requiredVersion.ToString();
            var provider = Create(request, modulePath, requiredVersionString, force, logWarning);
            if (provider != null) {
                var providerName = provider.GetPackageProviderName();
                if (!string.IsNullOrWhiteSpace(providerName)) {
                    request.Debug(string.Format(CultureInfo.CurrentCulture, Resources.Messages.SuccessfullyLoadedModule, modulePath));
                    // looks good to me, let's add this to the list of modules this meta provider can create.

                    var packageProvider = new PackageProvider(provider.As<IPackageProvider>()) {
                        IsLoaded = true,
                        Version = provider.GetProviderVersion(),
                        ProviderPath = modulePath
                    };

                    // take out powershell get
                    var psgetprovider = PackageManagementService.PackageProviders.FirstOrDefault(pv => string.Equals(pv.ProviderName, PowerShellGet, StringComparison.OrdinalIgnoreCase));

                    if (psModuleInfo != null)
                    {
                        // add swidtag information using moduleinfo
                        // however, this won't give us as much information yet
                        // we may have to fill this up later
                        ProvideSwidTagInformation(packageProvider, psModuleInfo);
                    }
                    
                    AddToPackageProviderCacheTable(packageProvider);
                    _availableProviders.AddOrSet(providerName, provider);

                    return packageProvider;
                } else {
                    provider.Dispose();
                    provider = null;
                    request.Debug(string.Format(CultureInfo.CurrentCulture, Resources.Messages.ProviderNameIsNullOrEmpty, modulePath));
                }
            }
            return null;
        }
コード例 #3
0
        public IEnumerable<object> LoadAvailableProvider(PsRequest request, string modulePath, Version requiredVersion, bool force) {
            if (request == null) {
                throw new ArgumentNullException("request");
            }

            if (string.IsNullOrEmpty(modulePath)) {
                throw new ArgumentNullException("modulePath");
            }

            EnsurePowerShellInitialized();

            //Check if it is already in the cache table
            var providersAlreadyImported = FindMatchedProvidersFromInternalCacheTable(request, modulePath).ToArray();

            if (providersAlreadyImported.Any() && !force) {
                return providersAlreadyImported;
            }

            //Trying to load it from the path directly
            var pkgProvider = AnalyzeModule(request, modulePath, requiredVersion ?? new Version(0, 0), force);
            if (pkgProvider != null) {
                return new[] { pkgProvider }.WhereNotNull();
            }

            request.Error(PackageManagement.Internal.Constants.Messages.FailedToImportProvider,
                ErrorCategory.InvalidOperation.ToString(), PowerShellGet, string.Format(CultureInfo.CurrentCulture, Resources.Messages.FailedToImportProvider, modulePath));
            return Enumerable.Empty<PackageProvider>();
        }
コード例 #4
0
        private IEnumerable<PackageProvider> FindMatchedProvidersFromInternalCacheTable(PsRequest request, string providerPath) {
            //Search from the internal table to see if we can the matched provider
  
            var providers = PackageManagementService.ProviderCacheTable
                .Select(each => each.Value).Select(list => list
                .Where(each => each.ProviderPath.EqualsIgnoreCase(providerPath) && each.IsLoaded)
                .Select(each => each));

            return providers.SelectMany(list => {
                var packageProviders = list as PackageProvider[] ?? list.ToArray();
                return packageProviders;
            });
        }
コード例 #5
0
        public void RefreshProviders(PsRequest request, string providerName, Version requiredVersion, Version minimumVersion, Version maximumVersion, bool logWarning) {
            //find and load the latest versions of the providers if only providerName exists, e.g., get-pp -name or import-pp -name 
            //find and load the particular provider if both providerName and version are provided
            _psProviderCacheTable.Clear();

            EnsurePowerShellInitialized();

            if (!string.IsNullOrWhiteSpace(providerName)) {
                //Get the list of available providers
                var modules = ScanForModules(request, requiredVersion, minimumVersion, maximumVersion, ProviderOption.AllProvider).ReEnumerable();

                var tasks = modules.AsyncForEach(modulePath => AnalyzeModule(request, modulePath.Key, modulePath.Value.Version ?? new Version(0, 0), false, logWarning, modulePath.Value));
                tasks.WaitAll();
            } else {
                //find all providers but only load the latest if no name nor version exists, e.g. get-pp -list 

                //Scan for the all available providers
                var results = ScanForModules(request, null, null, null, ProviderOption.AllProvider).ToArray();

                if (!_psProviderCacheTable.Any()) {
                    return;
                }

                foreach (var list in _psProviderCacheTable.Values.WhereNotNull()) {
                    var psInfo = list.OrderByDescending(each => each.ModuleInfo.Version).ToArray();
                    if (!psInfo.Any()) {
                        continue;
                    }

                    PackageProvider pkgProvider = null;
                    for (var index = 0; index < psInfo.Length; index++) {
                        var providerItem = psInfo[index];
                        if (providerItem == null) {
                            continue;
                        }

                        // if the provider is a dll, we will just provide a default provider, assuming the module name will be the name of the provider and add to the cache table (if it is not already loaded)
                        if (string.Equals(Path.GetExtension(providerItem.ProviderPath), ".dll", StringComparison.OrdinalIgnoreCase))
                        {
                            // check whether it is already loaded or not
                            var loadedProvider = PackageManagementService.PackageProviders.FirstOrDefault(item => string.Equals(item.ProviderPath, providerItem.ProviderPath, StringComparison.OrdinalIgnoreCase));

                            // only provide default provider if it is not loaded
                            if (loadedProvider == null)
                            {
                                // here moduleinfo.providercategory is the module name.
                                // we are applying the guideline that module name is the same as provider name so we use that as the provider name
                                AddToPackageProviderCacheTable(new PackageProvider(new DefaultPackageProvider(providerItem.ModuleInfo.Name, providerItem.ModuleInfo.Version.ToString()))
                                {
                                    ProviderPath = providerItem.ProviderPath,
                                    Version = providerItem.ModuleInfo.Version,
                                    IsLoaded = false
                                });
                            }

                            continue;
                        }

                        //load the provider that has the latest version
                        if (pkgProvider == null) {
                            // analyze the module
                            pkgProvider = AnalyzeModule(request, providerItem.ProviderPath, providerItem.ModuleInfo.Version, false, logWarning, providerItem.ModuleInfo);
                        } else {
                            //the rest of providers under the same module will just create a provider object for the output but not loaded
                            var packageProvider = new PackageProvider(new DefaultPackageProvider(pkgProvider.ProviderName, providerItem.ModuleInfo.Version.ToString()))
                            {
                                ProviderPath = providerItem.ProviderPath,
                                Version = providerItem.ModuleInfo.Version,
                                IsLoaded = false
                            };
                            AddToPackageProviderCacheTable(packageProvider);
                        }
                    }
                }

                _psProviderCacheTable.Clear();
            }
        }
コード例 #6
0
        public void InitializeProvider(PsRequest request) {
            if (request == null) {
                throw new ArgumentNullException("request");
            }

            request.Debug("Initializing PowerShell MetaProvider");

            //During the initialization, we load the PowerShellGet only to speeding up a little bit 
            var psModules = ScanForPowerShellGetModule(request).WhereNotNull();

            foreach (var psModule in psModules) {
                //Check if the PowerShellGet provider exists
                if ((psModule.Key != null) && (psModule.Value != null)) {
                    //load the PowerShellGet
                    AnalyzeModule(request, psModule.Key, psModule.Value.Version ?? new Version(0, 0), false, true, psModule.Value);
                }
            }

            if (_availableProviders.ContainsKey(PowerShellGet))
            {
                request.Debug("Loaded PowerShell Provider: PowerShellGet");
            }
            else
            {
                //if we can not load PowerShellGet, we do not fail the initialization
                request.Verbose(string.Format(CultureInfo.CurrentCulture, Resources.Messages.ModuleNotFound, PowerShellGet));
            }
        }
コード例 #7
0
        private PackageProvider AnalyzeModule(PsRequest request, string modulePath, Version requiredVersion, bool force)
        {
            if (string.IsNullOrWhiteSpace(modulePath)) {
                return null;
            }
            request.Debug("Attempting to load PowerShell Provider Module [{0}]", modulePath);
            var provider = Create(request, modulePath, requiredVersion.ToString(), force);
            if (provider != null) {
                var providerName = provider.GetPackageProviderName();
                if (!string.IsNullOrWhiteSpace(providerName)) {
                    request.Debug(string.Format(CultureInfo.CurrentCulture, Resources.Messages.SuccessfullyLoadedModule, modulePath));
                    // looks good to me, let's add this to the list of moduels this meta provider can create.

                    var packageProvider = new PackageProvider(provider.As<IPackageProvider>()) {
                        IsLoaded = true,
                        Version = provider.GetProviderVersion(),
                        ProviderPath = modulePath
                    };

                    AddToPackageProviderCacheTable(packageProvider);
                    _availableProviders.AddOrSet(providerName, provider);

                    return packageProvider;
                } else {
                    provider.Dispose();
                    provider = null;
                    request.Debug(string.Format(CultureInfo.CurrentCulture, Resources.Messages.ProviderNameIsNullOrEmpty, modulePath));
                }
            }
            return null;
        }
コード例 #8
0
        private void error_DataAdded(object sender, DataAddedEventArgs e, PsRequest request, ConcurrentBag<ErrorRecord> errors)
        {
            PSDataCollection<ErrorRecord> errorStream = sender as PSDataCollection<ErrorRecord>;

            if (errorStream == null)
            {
                return;
            }

            var error = errorStream[e.Index];

            if (error != null)
            {
                // add the error so we can report them later
                errors.Add(error);
            }
        
        }
コード例 #9
0
 private IEnumerable<KeyValuePair<string, PSModuleInfo>> ScanForPowerShellGetModule(PsRequest request)
 {
     var psget = _powershell.GetModule("PowerShellGet").FirstOrDefault();
     return psget != null ? GetPackageManagementModules(request, psget, null, null, null) : Enumerable.Empty<KeyValuePair<string, PSModuleInfo>>();
 }
コード例 #10
0
        //key = path, value = PSModuleInfo
        private IEnumerable<KeyValuePair<string, PSModuleInfo>> ScanForModules(
            PsRequest request,
            Version requiredVersion,
            Version minimumVersion,
            Version maximumVersion,
            ProviderOption providerOption = ProviderOption.LatestVersion) {

            // two places we search for modules
            // 1. in this assembly's folder, look for all psd1 and psm1 files.
            //
            // 2. modules in the PSMODULEPATH
            //
            // Import each one of those, and check to see if they have a PackageManagementProviders section in their private data

            var allAvailableModules = _powershell
                .Clear()
                .AddCommand("Get-Module")
                .AddParameter("ListAvailable")
                .Invoke<PSModuleInfo>();

            return allAvailableModules.WhereNotNull()
                .SelectMany(each => GetPackageManagementModules(request, each, requiredVersion, minimumVersion, maximumVersion));
        }
コード例 #11
0
        private IEnumerable<KeyValuePair<string, PSModuleInfo>> GetPackageManagementModules(PsRequest request, PSModuleInfo module, Version requiredVersion, Version minimumVersion, Version maximumVersion) {
            // skip modules that we know don't contain any PM modules
            if (!_exclusionList.Contains(module.Name)) {
                var privateData = module.PrivateData as Hashtable;
                if (privateData != null) {
                    if (requiredVersion != null) {
                        if ((FourPartVersion)module.Version == (FourPartVersion)requiredVersion) {
                            return ScanPrivateDataForProviders(request, Path.GetDirectoryName(module.Path), privateData, module).ToArray();
                        } else {
                            return Enumerable.Empty<KeyValuePair<string, PSModuleInfo>>();
                        }
                    }

                    if ((minimumVersion != null) && ((FourPartVersion)module.Version < (FourPartVersion)minimumVersion)) {
                        return Enumerable.Empty<KeyValuePair<string, PSModuleInfo>>();
                    }

                    if ((maximumVersion != null) && ((FourPartVersion)module.Version > (FourPartVersion)maximumVersion)) {
                        return Enumerable.Empty<KeyValuePair<string, PSModuleInfo>>();
                    }

                    return ScanPrivateDataForProviders(request, Path.GetDirectoryName(module.Path), privateData, module).ToArray();
                }
            }
            return Enumerable.Empty<KeyValuePair<string, PSModuleInfo>>();
        }
コード例 #12
0
        private IEnumerable<KeyValuePair<string,PSModuleInfo>> ScanPrivateDataForProviders(PsRequest request, string baseFolder, Hashtable privateData, PSModuleInfo moduleInfo) {
            var providers = privateData.GetStringCollection("PackageManagementProviders").ReEnumerable();
            if (providers.Any()) {
                // found a module that is advertizing one or more  Providers.

                foreach (var provider in providers) {
                    var fullPath = provider;
                    try {
                        if (!Path.IsPathRooted(provider)) {
                            fullPath = Path.GetFullPath(Path.Combine(baseFolder, provider));
                        }
                    } catch {
                        // got an error from the path.
                        continue;
                    }
                    if (Directory.Exists(fullPath) || File.Exists(fullPath)) {
                        // looks like we have something that could definitely be a
                        // a module path.
                        var result = new KeyValuePair<string, PSModuleInfo>(fullPath, moduleInfo);
                        AddToPowerShellProviderCacheTable(result);
                        yield return result;
                    } else {
                        request.Verbose(string.Format(CultureInfo.CurrentCulture, Resources.Messages.FileNotFound, fullPath));
                    }
                }
            } else {
                request.Debug(string.Format(Resources.Messages.PackageManagementProvidersNotFound, baseFolder));
            }
        }
コード例 #13
0
ファイル: Yieldable.cs プロジェクト: 40a/PowerShell
 public abstract bool YieldResult(PsRequest r);
コード例 #14
0
        //key = path, value = PSModuleInfo
        private IEnumerable<KeyValuePair<string, PSModuleInfo>> ScanForModules(
            PsRequest request,
            Version requiredVersion,
            Version minimumVersion,
            Version maximumVersion,
            ProviderOption providerOption = ProviderOption.LatestVersion)
        {
            // two places we search for modules
            // 1. in this assembly's folder, look for all psd1 and psm1 files.
            //
            // 2. modules in the PSMODULEPATH
            //
            // Import each one of those, and check to see if they have a PackageManagementProviders section in their private data

            return AlternativeModuleScan(request, requiredVersion, minimumVersion, maximumVersion, providerOption).WhereNotNull()
                .Where(modulePath => File.ReadAllText(modulePath).IndexOf("PackageManagementProviders", StringComparison.OrdinalIgnoreCase) > -1)
                .SelectMany(each => _powershell.TestModuleManifest(each))
                .SelectMany(each => GetPackageManagementModules(request, each, requiredVersion, minimumVersion, maximumVersion));
        }
コード例 #15
0
        // lock is on this instance only

        internal void ReportErrors(PsRequest request, IEnumerable<ErrorRecord> errors) {
            foreach (var error in errors) {
                request.Error(error.FullyQualifiedErrorId, error.CategoryInfo.Category.ToString(), error.TargetObject == null ? null : error.TargetObject.ToString(), error.ErrorDetails == null ? error.Exception.Message : error.ErrorDetails.Message);
                if (!string.IsNullOrWhiteSpace(error.Exception.StackTrace)) {
                    // give a debug hint if we have a script stack trace. How nice of us.
                    // the exception stack trace gives better stack than the script stack trace
                    request.Debug(Constants.ScriptStackTrace, error.Exception.StackTrace);
                }
            }
        }
コード例 #16
0
        private IEnumerable<string> AlternativeModuleScan(
            PsRequest request,
            Version requiredVersion,
            Version minimumVersion,
            Version maximumVersion,
            ProviderOption providerOption = ProviderOption.LatestVersion) {

            var psModulePath = Environment.GetEnvironmentVariable("PSModulePath") ?? "";

            IEnumerable<string> paths = psModulePath.Split(new char[] {';'}, StringSplitOptions.RemoveEmptyEntries);

            // add assumed paths just in case the environment variable isn't really set.
            try {
#if CORECLR
                paths = paths.ConcatSingleItem(Path.Combine(Environment.GetEnvironmentVariable("windir"), "system32", @"WindowsPowerShell\v1.0\Modules"));
#else
                paths = paths.ConcatSingleItem(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), @"WindowsPowerShell\v1.0\Modules"));
#endif
            } catch {
                // skip the folder if it's not valid
            }
            try {
#if CORECLR
                paths = paths.ConcatSingleItem(Path.Combine(Environment.GetEnvironmentVariable("userprofile"), "documents", @"WindowsPowerShell\Modules"));
#else
                paths = paths.ConcatSingleItem(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), @"WindowsPowerShell\Modules"));
#endif
            } catch {
                // skip the folder if it's not valid
            }

            if (!string.IsNullOrWhiteSpace(BaseFolder) && BaseFolder.DirectoryExists()) {
                paths = paths.ConcatSingleItem(BaseFolder);
            }

            var moduleFolders = paths.Distinct(new PathEqualityComparer(PathCompareOption.Full)).Where(each => each.DirectoryExists()).SelectMany(each => Directory.EnumerateDirectories(each).Where(dir => !_exclusionList.Contains(Path.GetFileName(dir))));

            foreach (var module in moduleFolders) {

                var moduleManifest = Path.Combine(module, Path.GetFileName(module) + ".psd1");
                if (File.Exists(moduleManifest)) {
                    //The version check is defered in the GetPackageManagementModules() because we do not know the version without looking into the content.
                    yield return moduleManifest;
                }

                //The following are the cases where there are multiple modules installed on the system. The file folder is the module version.
                var selectedVersions = Directory.EnumerateDirectories(module).Select(dir => new {
                    folder = dir,
                    ver = (FourPartVersion)Path.GetFileName(dir)
                }).Where(each => each.ver > 0L);

                if (requiredVersion != null) {
                    var version = selectedVersions.Where(each => each.ver == (FourPartVersion)requiredVersion).Select(each => each.folder).FirstOrDefault();
                    if (version != null) {
                        var file = Path.Combine(version, Path.GetFileName(Path.GetFileName(module)) + ".psd1");
                        if (File.Exists(file)) {
                            yield return file;
                        }
                    }
                }

                if (minimumVersion != null) {
                    selectedVersions = selectedVersions.Where(each => each.ver >= (FourPartVersion)minimumVersion);

                }
                if (maximumVersion != null) {
                    selectedVersions = selectedVersions.Where(each => each.ver <= (FourPartVersion)maximumVersion);
                }

                var results = (providerOption == PackageManagementService.ProviderOption.AllProvider) ?
                    selectedVersions.Select(version => Path.Combine(version.folder, Path.GetFileName(Path.GetFileName(module)) + ".psd1")).Where(File.Exists) :
                    new[] {
                        selectedVersions.OrderByDescending(each => each.ver)
                            .Select(version => Path.Combine(version.folder, Path.GetFileName(Path.GetFileName(module)) + ".psd1"))
                            .FirstOrDefault(File.Exists)
                    };

                foreach (var result in results.WhereNotNull()) {
                    yield return result;

                }
            }
        }
コード例 #17
0
        internal object CallPowerShell(PsRequest request, params object[] args) {
            // the lock ensures that we're not re-entrant into the same powershell runspace
            lock (_lock) {
                if (!_reentrancyLock.WaitOne(0)) {
                    // this lock is set to false, meaning we're still in a call **ON THIS THREAD**
                    // this is bad karma -- powershell won't let us call into the runspace again
                    // we're going to throw an error here because this indicates that the currently
                    // running powershell call is calling back into PM, and it has called back
                    // into this provider. That's just bad bad bad.
                    throw new Exception("Reentrancy Violation in powershell module");
                }
                
                try {
                    // otherwise, this is the first time we've been here during this call.
                    _reentrancyLock.Reset();

                    _powershell.SetVariable("request", request);
                    _powershell.Streams.ClearStreams();

                    object finalValue = null;
                    ConcurrentBag<ErrorRecord> errors = new ConcurrentBag<ErrorRecord>();

                    request.Debug("INVOKING PowerShell Fn {0} with args {1} that has length {2}", request.CommandInfo.Name, String.Join(", ", args), args.Length);

                    var result = _powershell.InvokeFunction<object>(request.CommandInfo.Name,
                        (sender, e) => output_DataAdded(sender, e, request, ref finalValue),
                        (sender, e) => error_DataAdded(sender, e, request, errors),
                        args);

                    if (result == null)
                    {
                        // result is null but it does not mean that the call fails because the command may return nothing
                        request.Debug(Messages.PowershellScriptFunctionReturnsNull.format(_module.Name, request.CommandInfo.Name));
                    }

                    if (errors.Count > 0)
                    {
                        // report the error if there are any
                        ReportErrors(request, errors);
                        _powershell.Streams.Error.Clear();
                    }

                    return finalValue;
                } catch (CmdletInvocationException cie) {
                    var error = cie.ErrorRecord;
                    request.Error(error.FullyQualifiedErrorId, error.CategoryInfo.Category.ToString(), error.TargetObject == null ? null : error.TargetObject.ToString(), error.ErrorDetails == null ? error.Exception.Message : error.ErrorDetails.Message);
                } finally {
                    lock (_stopLock) {
                        if (_stopResult != null){
                            _powershell.EndStop(_stopResult);
                            _stopResult = null;
                        }
                    }
                    _powershell.Clear();
                    _powershell.SetVariable("request", null);
                    // it's ok if someone else calls into this module now.
                    request.Debug("Done calling powershell", request.CommandInfo.Name, _module.Name);
                    _reentrancyLock.Set();
                }

                return null;
            }
        }
コード例 #18
0
        private PowerShellPackageProvider Create(PsRequest request, string modulePath, string requiredVersion, bool force, bool logWarning) {
            var ps = PowerShell.Create();
            try {
                // load the powershell provider functions into this runspace.
                if (ps.ImportModule(PowerShellProviderFunctions, false) != null) {
                    var result = ps.ImportModule(modulePath, force);
                    if (result != null) {
                        try {
                            return new PowerShellPackageProvider(ps, result, requiredVersion);
                        } catch (Exception e) {
                            e.Dump();
                        }
                    }
                }
            } catch (Exception e) {
                // something didn't go well.
                // skip it.
                e.Dump();
                if (logWarning) {
                    request.Warning(e.Message);
                }
            }

            // didn't import correctly.
            ps.Dispose();
            return null;
        }
コード例 #19
0
        private void output_DataAdded(object sender, DataAddedEventArgs e, PsRequest request, ref object finalValue)
        {
            PSDataCollection<PSObject> outputstream = sender as PSDataCollection<PSObject>;

            if (outputstream == null)
            {
                return;
            }

            PSObject psObject = outputstream[e.Index];
            if (psObject != null)
            {
                var value = psObject.ImmediateBaseObject;
                var y = value as Yieldable;
                if (y != null)
                {
                    // yield it to stream the result gradually
                    y.YieldResult(request);
                }
                else
                {
                    finalValue = value;
                    return;
                }
            }
        }
コード例 #20
0
        public void RefreshProviders(PsRequest request, string providerName, Version requiredVersion, Version minimumVersion, Version maximumVersion) {
            //find and load the latest versions of the providers if only providerName exists, e.g., get-pp -name or import-pp -name 
            //find and load the particular provider if both providerName and version are provided
            _psProviderCacheTable.Clear();

            EnsurePowerShellInitialized();

            if (!string.IsNullOrWhiteSpace(providerName)) {
                //Get the list of available providers
                var modules = ScanForModules(request, requiredVersion, minimumVersion, maximumVersion, ProviderOption.AllProvider).ReEnumerable();

                var tasks = modules.AsyncForEach(modulePath => AnalyzeModule(request, modulePath.Key, modulePath.Value.Version ?? new Version(0, 0), false));
                tasks.WaitAll();
            } else {
                //find all providers but only load the lastest if no name nor version exists, e.g. get-pp -list 

                //Scan for the all available providers
                var results = ScanForModules(request, null, null, null, ProviderOption.AllProvider).ToArray();

                if (!_psProviderCacheTable.Any()) {
                    return;
                }

                foreach (var list in _psProviderCacheTable.Values.WhereNotNull()) {
                    var psInfo = list.OrderByDescending(each => each.ProviderVersion).ToArray();
                    if (!psInfo.Any()) {
                        continue;
                    }

                    PackageProvider pkgProvider = null;
                    for (var index = 0; index < psInfo.Length; index++) {
                        var moduleInfo = psInfo[index];
                        if (moduleInfo == null) {
                            continue;
                        }
                        //load the provider that has the latest version
                        if (index == 0) {
                            pkgProvider = AnalyzeModule(request, moduleInfo.ProviderPath, moduleInfo.ProviderVersion, false);
                        } else {
                            if (pkgProvider != null) {
                                //the rest of providers under the same module will just create a provider object for the output but not loaded
                                var packageProvider = new PackageProvider(new DefaultPackageProvider(pkgProvider.ProviderName, moduleInfo.ProviderVersion.ToString())) {
                                    ProviderPath = moduleInfo.ProviderPath,
                                    Version = moduleInfo.ProviderVersion,
                                    IsLoaded = false
                                };
                                AddToPackageProviderCacheTable(packageProvider);
                            }
                        }

                    }
                }

                _psProviderCacheTable.Clear();
            }
        }