public IAsyncEnumerable <SoftwareIdentity> InstallPackage(SoftwareIdentity softwareIdentity, IHostApi requestObject) { if (requestObject == null) { throw new ArgumentNullException("requestObject"); } if (softwareIdentity == null) { throw new ArgumentNullException("softwareIdentity"); } // if the provider didn't say this was trusted, we should ask the user if it's ok. if (!softwareIdentity.FromTrustedSource) { try { if (!requestObject.ShouldContinueWithUntrustedPackageSource(softwareIdentity.Name, softwareIdentity.Source)) { requestObject.Warning(requestObject.FormatMessageString(Constants.Messages.UserDeclinedUntrustedPackageInstall, softwareIdentity.Name)); return(new EmptyAsyncEnumerable <SoftwareIdentity>()); } } catch { return(new EmptyAsyncEnumerable <SoftwareIdentity>()); } } return(new SoftwareIdentityRequestObject(this, requestObject ?? new object().As <IHostApi>(), request => Provider.InstallPackage(softwareIdentity.FastPackageReference, request), Constants.PackageStatus.Installed)); }
public IEnumerable <PackageProvider> SelectProviders(string providerName, IHostApi hostApi) { if (!string.IsNullOrWhiteSpace(providerName)) { // match with wildcards var results = _packageProviders.Values.Where(each => each.ProviderName.IsWildcardMatch(providerName)).ReEnumerable(); if (results.Any()) { return(results); } if (hostApi != null && !providerName.ContainsWildcards()) { // if the end user requested a provider that's not there. perhaps the bootstrap provider can find it. if (RequirePackageProvider(null, providerName, Constants.MinVersion, hostApi)) { // seems to think we found it. if (_packageProviders.ContainsKey(providerName)) { return(_packageProviders[providerName].SingleItemAsEnumerable()); } } // warn the user that that provider wasn't found. hostApi.Warning(hostApi.FormatMessageString(Constants.Messages.UnknownProvider, providerName)); } return(Enumerable.Empty <PackageProvider>()); } return(PackageProviders); }
/// <summary> /// Searches for the assembly, interrogates it for it's providers and then proceeds to load /// </summary> /// <param name="request"></param> /// <param name="providerAssemblyName"></param> /// <returns></returns> internal bool TryToLoadProviderAssembly(string providerAssemblyName, IHostApi request) { request.Debug(request.FormatMessageString("Trying provider assembly: {0}", providerAssemblyName)); var assemblyPath = FindAssembly(providerAssemblyName); if (assemblyPath != null) { try { byte[] hash = null; using (var stream = File.Open(assemblyPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { hash = System.Security.Cryptography.MD5.Create().ComputeHash(stream); } lock (_providerFiles) { if (_providerFiles.ContainsKey(assemblyPath)) { // have we tried this file before? if (_providerFiles[assemblyPath].SequenceEqual(hash)) { // and it's the exact same file? request.Debug(request.FormatMessageString("Skipping previously processed assembly: {0}", assemblyPath)); return(false); } request.Debug(request.FormatMessageString("New assembly in location: {0}", assemblyPath)); // it's a different file in the same path? // we're gonna let it try the new file. _providerFiles.Remove(assemblyPath); } else { request.Debug(request.FormatMessageString("Attempting loading of assembly: {0}", assemblyPath)); } // record that this file is being loaded. _providerFiles.Add(assemblyPath, hash); } if (AcquireProviders(assemblyPath, request)) { request.Debug(request.FormatMessageString("SUCCESS provider assembly: {0}", providerAssemblyName)); return(true); } } catch (Exception e) { e.Dump(); lock (_providerFiles) { // can't create hash from file? // we're not going to try and load this. // all we can do is record the name. if (!_providerFiles.ContainsKey(assemblyPath)) { _providerFiles.Add(assemblyPath, new byte[0]); } } } } request.Debug(request.FormatMessageString("FAILED provider assembly: {0}", providerAssemblyName)); return(false); }
/// <summary> /// Searches for the assembly, interrogates it for it's providers and then proceeds to load /// </summary> /// <param name="request"></param> /// <param name="providerAssemblyName"></param> /// <returns></returns> public bool LoadProviderAssembly(IHostApi request, string providerAssemblyName) { request.Debug(request.FormatMessageString("Trying provider assembly: {0}", providerAssemblyName)); var assemblyPath = FindAssembly(providerAssemblyName); if (assemblyPath != null) { try { byte[] hash = null; using (var stream = File.Open(assemblyPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { hash = MD5.Create().ComputeHash(stream); } lock (_providerFiles) { if (_providerFiles.ContainsKey(assemblyPath)) { // have we tried this file before? if (_providerFiles[assemblyPath].SequenceEqual(hash)) { // and it's the exact same file? request.Debug(request.FormatMessageString("Skipping previously processed assembly: {0}", assemblyPath)); return false; } request.Debug(request.FormatMessageString("New assembly in location: {0}", assemblyPath)); // it's a different file in the same path? // we're gonna let it try the new file. _providerFiles.Remove(assemblyPath); } else { request.Debug(request.FormatMessageString("Attempting loading of assembly: {0}", assemblyPath)); } // record that this file is being loaded. _providerFiles.Add(assemblyPath, hash); } if (AcquireProviders(assemblyPath, request)) { request.Debug(request.FormatMessageString("SUCCESS provider assembly: {0}", providerAssemblyName)); return true; } } catch (Exception e) { e.Dump(); lock (_providerFiles) { // can't create hash from file? // we're not going to try and load this. // all we can do is record the name. if (!_providerFiles.ContainsKey(assemblyPath)) { _providerFiles.Add(assemblyPath, new byte[0]); } } } } request.Debug(request.FormatMessageString("FAILED provider assembly: {0}", providerAssemblyName)); return false; }
private IMetaProvider GetMetaProviderObject(IHostApi requestObject) { if (_metaProviders.ContainsKey("powershell")) { var powerShellMetaProvider = _metaProviders["powershell"]; if (powerShellMetaProvider != null) { return powerShellMetaProvider; } } requestObject.Error(Constants.Messages.FailedPowerShellMetaProvider, ErrorCategory.InvalidOperation.ToString(), "LoadProvider", requestObject.FormatMessageString(Constants.Messages.FailedPowerShellMetaProvider)); return null; }
private PackageProvider ImportProvider(IHostApi request, string providerName, IMetaProvider powerShellMetaProvider) { //foreach (var providerName in providers) { //var matchedProviderName = provider.As<DefaultPackageProvider>().GetPackageProviderName(); //TODO pass in Maxi, mini, and requiredVersion to LoadAvailableProvider var instance = powerShellMetaProvider.LoadAvailableProvider(request.As<IRequest>(), providerName); if (instance == null) { return null; } //Register newly created provider if (typeof(IPackageProvider).CanDynamicCastFrom(instance)) { var packageProvider = RegisterPackageProvider(instance.As<IPackageProvider>(), providerName, String.Empty, request); if (packageProvider != null) { packageProvider.ProviderPath = powerShellMetaProvider.GetProviderPath(providerName); return packageProvider; } } else { //A provider is not found request.Error(Constants.Messages.UnknownProvider, ErrorCategory.InvalidOperation.ToString(), providerName, request.FormatMessageString(Constants.Messages.UnknownProvider, providerName)); } } }
private IEnumerable<PackageProvider> ImportPackageProviderViaName(IHostApi request, string providerName) { var powerShellMetaProvider = GetMetaProviderObject(request); if (powerShellMetaProvider == null) { yield break; } //var availableProvider = powerShellMetaProvider.GetAvailableLocallyProviders(request.As<IRequest>()).ReEnumerable(); var availableProviderNames = powerShellMetaProvider.GetProviderNames(); //.ReEnumerable(); if (!availableProviderNames.Any()) { //No available providers. if (!String.IsNullOrWhiteSpace(providerName)) { //Error out if a user specific -Name request.Error(Constants.Messages.UnknownProvider, ErrorCategory.InvalidOperation.ToString(), providerName, request.FormatMessageString(Constants.Messages.UnknownProvider, providerName)); } yield break; } // a user inputs "-Name" property, we load the specific provider //Find if it exists in the available list var matches = availableProviderNames.Where(each => each.IsWildcardMatch(providerName)).ReEnumerable(); if (!matches.Any()) { request.Error(Constants.Messages.UnknownProvider, ErrorCategory.InvalidOperation.ToString(), providerName, request.FormatMessageString(Constants.Messages.UnknownProvider, providerName)); } foreach (var match in matches) { //var matchedProviderName = match.As<DefaultPackageProvider>().GetPackageProviderName(); yield return ImportProvider(request, match, powerShellMetaProvider); //var instance = powerShellMetaProvider.LoadAvailableProvider(request.As<IRequest>(), matchedProviderName); //if (instance == null) { // yield break; //} ////Register newly created provider //if (typeof (IPackageProvider).CanDynamicCastFrom(instance)) { // var packageProvider = RegisterPackageProvider(instance.As<IPackageProvider>(), String.Empty, request); // if (packageProvider != null) { // packageProvider.ProviderPath = powerShellMetaProvider.GetProviderPath(matchedProviderName); // yield return packageProvider; // } //} else { // //A provider is not found // request.Error(Constants.Messages.UnknownProvider, ErrorCategory.InvalidOperation.ToString(), // providerName, request.FormatMessageString(Constants.Messages.UnknownProvider, providerName)); //} } }
/// <summary> /// Get available provider if -ListAvailable present;load a provider specified in providerName. /// </summary> /// <param name="request"></param> /// <param name="providerName">provider to be loaded.</param> /// <param name="powerShellMetaProvider"></param> private IEnumerable<PackageProvider> GetAvailableProvider(IHostApi request, string providerName, IMetaProvider powerShellMetaProvider) { var results = _packageProviders.Values.Where(each => each.ProviderName.IsWildcardMatch(providerName)).ReEnumerable(); if (results.Any()) { //the provider is already loaded and tracked in the loaded master list: _packageProviders yield break; } //Get available powershell providers var availableProviders = powerShellMetaProvider.GetAvailableLocallyProviders(request.As<IRequest>()).ReEnumerable(); if (!availableProviders.Any()) { //No available providers. if (!String.IsNullOrWhiteSpace(providerName)) { //Error out if a user specific -Name request.Error(Constants.Messages.UnknownProvider, ErrorCategory.InvalidOperation.ToString(), providerName, request.FormatMessageString(Constants.Messages.UnknownProvider, providerName)); } yield break; } if (String.IsNullOrWhiteSpace(providerName)) { // "-Name" does not exist, we return all we can find foreach (var module in availableProviders) { yield return new PackageProvider(module.As<DefaultPackageProvider>()); } } else { //A user inputs both -Name and -ListAvailable var matches = powerShellMetaProvider.GetProviderNames().Where(each => each.IsWildcardMatch(providerName)).ReEnumerable(); if (!matches.Any()) { request.Error(Constants.Messages.UnknownProvider, ErrorCategory.InvalidOperation.ToString(), providerName, request.FormatMessageString(Constants.Messages.UnknownProvider, providerName)); } foreach (var match in matches) { yield return new PackageProvider(powerShellMetaProvider.GetAvailableLocallyProvider(match).As<DefaultPackageProvider>()); //yield return new PackageProvider(availableProviders[match].As<DefaultPackageProvider>()); } } }
public bool RequirePackageProvider(string requestor, string packageProviderName, string minimumVersion, IHostApi hostApi) { // check if the package provider is already installed if (_packageProviders.ContainsKey(packageProviderName)) { var current = _packageProviders[packageProviderName].Version; if (current >= minimumVersion) { return true; } } var currentCallCount = hostApi.CallCount; if (_lastCallCount >= currentCallCount) { // we've already been here this call. // are they asking for the same provider again? if (_providersTriedThisCall.Contains(packageProviderName)) { hostApi.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 (!hostApi.IsInteractive) { hostApi.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. if (!_packageProviders.ContainsKey(packageProviderName)){ return false; } var bootstrap = _packageProviders["Bootstrap"]; if (bootstrap == null) { hostApi.Debug("Skipping RequirePackageProvider due to missing bootstrap provider"); return false; } var pkg = bootstrap.FindPackage(packageProviderName, null, minimumVersion, null, hostApi).OrderByDescending(p => p, SoftwareIdentityVersionComparer.Instance).GroupBy(package => package.Name).ToArray(); if (pkg.Length == 1) { // Yeah? Install it. var package = pkg[0].FirstOrDefault(); var metaWithProviderType = package.Meta.FirstOrDefault(each => each.ContainsKey("providerType")); var providerType = metaWithProviderType == null ? "unknown" : metaWithProviderType.GetAttribute("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.ToString(); } // what can't find an installationmedia link? // todo: what should we say here? if (hostApi.ShouldBootstrapProvider(requestor, package.Name, package.Version, providerType, location, destination)) { var newRequest = hostApi.Extend<IHostApi>(new { GetOptionValues = new Func<string, IEnumerable<string>>(key => { if (key == "DestinationPath") { return new[] { destination }; } return new string[0]; }) }); var packagesInstalled = bootstrap.InstallPackage(package, newRequest).LastOrDefault(); if (packagesInstalled == null) { // that's sad. hostApi.Error(Constants.Messages.FailedProviderBootstrap, ErrorCategory.InvalidOperation.ToString(), package.Name, hostApi.FormatMessageString(Constants.Messages.FailedProviderBootstrap, package.Name)); return false; } // so it installed something // we must tell the plugin loader to reload the plugins again. LoadProviders(hostApi); return true; } } return false; }
/// <summary> /// Searches for the assembly, interrogates it for it's providers and then proceeds to load /// </summary> /// <param name="request"></param> /// <param name="providerAssemblyName"></param> /// <param name="shouldRefreshCache"></param> /// <returns></returns> internal bool LoadProviderAssembly(IHostApi request, string providerAssemblyName, bool shouldRefreshCache) { request.Debug(request.FormatMessageString("Trying provider assembly: {0}", providerAssemblyName)); var assemblyPath = FindAssembly(providerAssemblyName); if (assemblyPath != null) { try { byte[] hash = null; using (var stream = File.Open(assemblyPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { hash = System.Security.Cryptography.MD5.Create().ComputeHash(stream); } lock (_providerFiles) { if (_providerFiles.ContainsKey(assemblyPath)) { // have we tried this file before? //if the exactly same provider is loaded already, skip the processed assembly. if (_providerFiles[assemblyPath].SequenceEqual(hash) && !shouldRefreshCache) { // and it's the exact same file? request.Verbose(string.Format(CultureInfo.CurrentCulture, Resources.Messages.SkippingProcessedAssembly, assemblyPath)); return false; } // it's a different file in the same path? -force exists? // we're gonna let it try the new file. _providerFiles.Remove(assemblyPath); } request.Debug(request.FormatMessageString("Attempting loading of assembly: {0}", assemblyPath)); // record that this file is being loaded. _providerFiles.Add(assemblyPath, hash); } if (AcquireProviders(assemblyPath, request, shouldRefreshCache)) { request.Debug(request.FormatMessageString("SUCCESS provider assembly: {0}", providerAssemblyName)); return true; } } catch (Exception e) { e.Dump(); lock (_providerFiles) { // can't create hash from file? // we're not going to try and load this. // all we can do is record the name. if (!_providerFiles.ContainsKey(assemblyPath)) { _providerFiles.Add(assemblyPath, new byte[0]); } } } } request.Debug(request.FormatMessageString("FAILED provider assembly: {0}", providerAssemblyName)); return false; }
public IEnumerable<PackageProvider> SelectProviders(string providerName, IHostApi hostApi) { if (!string.IsNullOrWhiteSpace(providerName)) { // match with wildcards var results = _packageProviders.Values.Where(each => each.ProviderName.IsWildcardMatch(providerName)).ReEnumerable(); if (results.Any()) { return results; } if (hostApi != null && !providerName.ContainsWildcards()) { // if the end user requested a provider that's not there. perhaps the bootstrap provider can find it. if (RequirePackageProvider(null, providerName, Constants.MinVersion, hostApi)) { // seems to think we found it. if (_packageProviders.ContainsKey(providerName)) { return _packageProviders[providerName].SingleItemAsEnumerable(); } } // warn the user that that provider wasn't found. hostApi.Warning(hostApi.FormatMessageString(Constants.Messages.UnknownProvider, providerName)); } return Enumerable.Empty<PackageProvider>(); } return PackageProviders; }
public bool RequirePackageProvider(string requestor, string packageProviderName, string minimumVersion, IHostApi hostApi) { // check if the package provider is already installed if (_packageProviders.ContainsKey(packageProviderName)) { var current = _packageProviders[packageProviderName].Version; if (current >= minimumVersion) { return(true); } } var currentCallCount = hostApi.CallCount; if (_lastCallCount >= currentCallCount) { // we've already been here this call. // are they asking for the same provider again? if (_providersTriedThisCall.Contains(packageProviderName)) { hostApi.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 (!hostApi.IsInteractive) { hostApi.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) { hostApi.Debug("Skipping RequirePackageProvider due to missing bootstrap provider"); return(false); } var pkg = bootstrap.FindPackage(packageProviderName, null, minimumVersion, null, hostApi).OrderByDescending(p => p, SoftwareIdentityVersionComparer.Instance).GroupBy(package => package.Name).ToArray(); if (pkg.Length == 1) { // Yeah? Install it. var package = pkg[0].FirstOrDefault(); var metaWithProviderType = package.Meta.FirstOrDefault(each => each.ContainsKey("providerType")); var providerType = metaWithProviderType == null ? "unknown" : metaWithProviderType.GetAttribute("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.ToString(); } // what can't find an installationmedia link? // todo: what should we say here? if (hostApi.ShouldBootstrapProvider(requestor, package.Name, package.Version, providerType, location, destination)) { var newRequest = hostApi.Extend <IHostApi>(new { GetOptionValues = new Func <string, IEnumerable <string> >(key => { if (key == "DestinationPath") { return(new[] { destination }); } return(new string[0]); }) }); var packagesInstalled = bootstrap.InstallPackage(package, newRequest).LastOrDefault(); if (packagesInstalled == null) { // that's sad. hostApi.Error(Constants.Messages.FailedProviderBootstrap, ErrorCategory.InvalidOperation.ToString(), package.Name, hostApi.FormatMessageString(Constants.Messages.FailedProviderBootstrap, package.Name)); return(false); } // so it installed something // we must tell the plugin loader to reload the plugins again. LoadProviders(hostApi); return(true); } } return(false); }
/// <summary> /// This initializes the provider registry with the list of package providers. /// (currently a hardcoded list, soon, registry driven) /// </summary> /// <param name="request"></param> internal void LoadProviders(IHostApi request) { if (request == null) { throw new ArgumentNullException("request"); } var baseDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var providerAssemblies = (_initialized ? Enumerable.Empty <string>() : _defaultProviders) .Concat(GetProvidersFromRegistry(Registry.LocalMachine, "SOFTWARE\\MICROSOFT\\ONEGET")) .Concat(GetProvidersFromRegistry(Registry.CurrentUser, "SOFTWARE\\MICROSOFT\\ONEGET")) .Concat(AutoloadedAssemblyLocations.SelectMany(location => { if (Directory.Exists(location)) { return(Directory.EnumerateFiles(location).Where(each => !IsExcluded(each) && (each.EndsWith(".exe", StringComparison.CurrentCultureIgnoreCase) || each.EndsWith(".dll", StringComparison.CurrentCultureIgnoreCase)))); } return(Enumerable.Empty <string>()); })); #if DEEP_DEBUG providerAssemblies = providerAssemblies.ToArray(); foreach (var each in providerAssemblies) { request.Debug("possible assembly: {0}".format(each)); } #endif // find modules that have manifests // todo: expand this out to validate the assembly is ok for this instance of OneGet. providerAssemblies = providerAssemblies.Where(each => Manifest.LoadFrom(each).Any(manifest => Swidtag.IsSwidtag(manifest) && new Swidtag(manifest).IsApplicable(new Hashtable()))); // add inbox assemblies (don't require manifests, because they are versioned with the core) #if !COMMUNITY_BUILD // todo: these should just be strong-named references. for now, just load them from the same directory. providerAssemblies = providerAssemblies.Concat(new[] { Path.Combine(baseDir, "Microsoft.OneGet.MetaProvider.PowerShell.dll"), Path.Combine(baseDir, "Microsoft.OneGet.ArchiverProviders.dll"), Path.Combine(baseDir, "Microsoft.OneGet.CoreProviders.dll"), Path.Combine(baseDir, "Microsoft.OneGet.MsuProvider.dll"), #if !CORE_CLR // can't load these providers here. Path.Combine(baseDir, "Microsoft.OneGet.MsiProvider.dll"), #endif }); #endif #if DEEP_DEBUG providerAssemblies = providerAssemblies.ToArray(); foreach (var each in providerAssemblies) { request.Debug("possible assembly with manifest: {0}".format(each)); } #endif providerAssemblies = providerAssemblies.OrderByDescending(each => { try { // try to get a version from the file first return((ulong)(FourPartVersion)FileVersionInfo.GetVersionInfo(each)); } catch { // otherwise we can't make a distinction. return((ulong)0); } }); providerAssemblies = providerAssemblies.Distinct(new PathEqualityComparer(PathCompareOption.FileWithoutExtension)); #if BEFORE_WE_HAD_MANIFESTS // hack to make sure we don't load the old version of the nuget provider // when we have the ability to examine a plugin without dragging it into the // primary appdomain, this won't be needed. FourPartVersion minimumnugetversion = "2.8.3.6"; providerAssemblies = providerAssemblies.Where(assemblyFile => { try { if ("nuget-anycpu".EqualsIgnoreCase(Path.GetFileNameWithoutExtension(assemblyFile)) && ((FourPartVersion)FileVersionInfo.GetVersionInfo(assemblyFile)) < minimumnugetversion) { return(false); } } catch { } return(true); }); #endif // there is no trouble with loading providers concurrently. #if DEBUG providerAssemblies.SerialForEach(providerAssemblyName => { #else providerAssemblies.ParallelForEach(providerAssemblyName => { #endif try { request.Debug(request.FormatMessageString("Trying provider assembly: {0}", providerAssemblyName)); if (TryToLoadProviderAssembly(providerAssemblyName, request)) { request.Debug(request.FormatMessageString("SUCCESS provider assembly: {0}", providerAssemblyName)); } else { request.Debug(request.FormatMessageString("FAILED provider assembly: {0}", providerAssemblyName)); } } catch { request.Error(Constants.Messages.ProviderPluginLoadFailure, ErrorCategory.InvalidOperation.ToString(), providerAssemblyName, request.FormatMessageString(Constants.Messages.ProviderPluginLoadFailure, providerAssemblyName)); } }); }