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, 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)); } }
// 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); } } }
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)); } }
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; } }
// 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); } } }
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; }
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)); } }
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)); } }
private PackageProvider AnalyzeModule(PsRequest request, string modulePath, Version requiredVersion, bool force, 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); 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 }; // 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); }
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); } }
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; }
private PowerShellPackageProvider Create(PsRequest request, string modulePath, string requiredVersion, bool force) { 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(); request.Debug(e.Message); } // didn't import correctly. ps.Dispose(); return null; }