mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
removed RunspaceConfiguration support (#4942)
For PSCore 6, we are only supporting InitialSessionState. The RunspaceConfiguration APIs were already made internal. This PR removes all the code related to RunspaceConfiguration. This also means that some public APIs have changed. Was deciding between leaving the RunspaceConfiguration parameters and throwing Unsupported, but thought it was better to have it a compile-time error. This should simplify the code base.
This commit is contained in:
@@ -366,17 +366,13 @@ namespace Microsoft.PowerShell.Commands
|
||||
else
|
||||
{
|
||||
// Update successfully, we add the TypeData into cache
|
||||
if (Context.RunspaceConfiguration != null)
|
||||
{
|
||||
Context.RunspaceConfiguration.Types.Append(new TypeConfigurationEntry(type, false));
|
||||
}
|
||||
else if (Context.InitialSessionState != null)
|
||||
if (Context.InitialSessionState != null)
|
||||
{
|
||||
Context.InitialSessionState.Types.Add(new SessionStateTypeEntry(type, false));
|
||||
}
|
||||
else
|
||||
{
|
||||
Dbg.Assert(false, "Either RunspaceConfiguration or InitialSessionState must be non-null for Update-Typedata to work");
|
||||
Dbg.Assert(false, "InitialSessionState must be non-null for Update-Typedata to work");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -484,17 +480,13 @@ namespace Microsoft.PowerShell.Commands
|
||||
else
|
||||
{
|
||||
// Update successfully, we add the TypeData into cache
|
||||
if (Context.RunspaceConfiguration != null)
|
||||
{
|
||||
Context.RunspaceConfiguration.Types.Append(new TypeConfigurationEntry(type, false));
|
||||
}
|
||||
else if (Context.InitialSessionState != null)
|
||||
if (Context.InitialSessionState != null)
|
||||
{
|
||||
Context.InitialSessionState.Types.Add(new SessionStateTypeEntry(type, false));
|
||||
}
|
||||
else
|
||||
{
|
||||
Dbg.Assert(false, "Either RunspaceConfiguration or InitialSessionState must be non-null for Update-Typedata to work");
|
||||
Dbg.Assert(false, "InitialSessionState must be non-null for Update-Typedata to work");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -757,38 +749,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
// filename is available
|
||||
string target = UpdateDataStrings.UpdateTarget;
|
||||
|
||||
if (Context.RunspaceConfiguration != null)
|
||||
{
|
||||
for (int i = prependPathTotal.Count - 1; i >= 0; i--)
|
||||
{
|
||||
string formattedTarget = string.Format(CultureInfo.InvariantCulture, target, prependPathTotal[i]);
|
||||
|
||||
if (ShouldProcess(formattedTarget, action))
|
||||
{
|
||||
this.Context.RunspaceConfiguration.Types.Prepend(new TypeConfigurationEntry(prependPathTotal[i]));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string appendPathTotalItem in appendPathTotal)
|
||||
{
|
||||
string formattedTarget = string.Format(CultureInfo.InvariantCulture, target, appendPathTotalItem);
|
||||
|
||||
if (ShouldProcess(formattedTarget, action))
|
||||
{
|
||||
this.Context.RunspaceConfiguration.Types.Append(new TypeConfigurationEntry(appendPathTotalItem));
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.Context.CurrentRunspace.RunspaceConfiguration.Types.Update(true);
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
this.WriteError(new ErrorRecord(e, "TypesXmlUpdateException", ErrorCategory.InvalidOperation, null));
|
||||
}
|
||||
}
|
||||
else if (Context.InitialSessionState != null)
|
||||
if (Context.InitialSessionState != null)
|
||||
{
|
||||
// This hashSet is to detect if there are duplicate type files
|
||||
var fullFileNameHash = new HashSet<string>(StringComparer.CurrentCultureIgnoreCase);
|
||||
@@ -887,7 +848,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
else
|
||||
{
|
||||
Dbg.Assert(false, "Either RunspaceConfiguration or InitialSessionState must be non-null for Update-Typedata to work");
|
||||
Dbg.Assert(false, "InitialSessionState must be non-null for Update-Typedata to work");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -931,38 +892,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
// filename is available
|
||||
string target = UpdateDataStrings.UpdateTarget;
|
||||
|
||||
if (Context.RunspaceConfiguration != null)
|
||||
{
|
||||
for (int i = prependPathTotal.Count - 1; i >= 0; i--)
|
||||
{
|
||||
string formattedTarget = string.Format(CultureInfo.CurrentCulture, target, prependPathTotal[i]);
|
||||
|
||||
if (ShouldProcess(formattedTarget, action))
|
||||
{
|
||||
this.Context.RunspaceConfiguration.Formats.Prepend(new FormatConfigurationEntry(prependPathTotal[i]));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string appendPathTotalItem in appendPathTotal)
|
||||
{
|
||||
string formattedTarget = string.Format(CultureInfo.CurrentCulture, target, appendPathTotalItem);
|
||||
|
||||
if (ShouldProcess(formattedTarget, action))
|
||||
{
|
||||
this.Context.RunspaceConfiguration.Formats.Append(new FormatConfigurationEntry(appendPathTotalItem));
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.Context.CurrentRunspace.RunspaceConfiguration.Formats.Update(true);
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
this.WriteError(new ErrorRecord(e, "FormatXmlUpdateException", ErrorCategory.InvalidOperation, null));
|
||||
}
|
||||
}
|
||||
else if (Context.InitialSessionState != null)
|
||||
if (Context.InitialSessionState != null)
|
||||
{
|
||||
if (Context.InitialSessionState.DisableFormatUpdates)
|
||||
{
|
||||
@@ -1055,12 +985,11 @@ namespace Microsoft.PowerShell.Commands
|
||||
if (entries.Count > 0)
|
||||
{
|
||||
Context.FormatDBManager.UpdateDataBase(entries, this.Context.AuthorizationManager, this.Context.EngineHostInterface, false);
|
||||
FormatAndTypeDataHelper.ThrowExceptionOnError(
|
||||
"ErrorsUpdatingFormats",
|
||||
null,
|
||||
entries,
|
||||
RunspaceConfigurationCategory.Formats);
|
||||
}
|
||||
FormatAndTypeDataHelper.ThrowExceptionOnError( "ErrorsUpdatingFormats",
|
||||
null,
|
||||
entries,
|
||||
RunspaceConfigurationCategory.Formats);
|
||||
}
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
@@ -1069,7 +998,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
else
|
||||
{
|
||||
Dbg.Assert(false, "Either RunspaceConfiguration or InitialSessionState must be non-null for Update-FormatData to work");
|
||||
Dbg.Assert(false, "InitialSessionState must be non-null for Update-FormatData to work");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1154,17 +1083,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
Dictionary<string, List<int>> fileToIndexMap = new Dictionary<string, List<int>>(StringComparer.OrdinalIgnoreCase);
|
||||
List<int> indicesToRemove = new List<int>();
|
||||
|
||||
if (Context.RunspaceConfiguration != null)
|
||||
{
|
||||
for (int index = 0; index < Context.RunspaceConfiguration.Types.Count; index++)
|
||||
{
|
||||
string fileName = Context.RunspaceConfiguration.Types[index].FileName;
|
||||
if (fileName == null) { continue; }
|
||||
|
||||
ConstructFileToIndexMap(fileName, index, fileToIndexMap);
|
||||
}
|
||||
}
|
||||
else if (Context.InitialSessionState != null)
|
||||
if (Context.InitialSessionState != null)
|
||||
{
|
||||
for (int index = 0; index < Context.InitialSessionState.Types.Count; index++)
|
||||
{
|
||||
@@ -1200,11 +1119,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
indicesToRemove.Sort();
|
||||
for (int i = indicesToRemove.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (Context.RunspaceConfiguration != null)
|
||||
{
|
||||
Context.RunspaceConfiguration.Types.RemoveItem(indicesToRemove[i]);
|
||||
}
|
||||
else if (Context.InitialSessionState != null)
|
||||
if (Context.InitialSessionState != null)
|
||||
{
|
||||
Context.InitialSessionState.Types.RemoveItem(indicesToRemove[i]);
|
||||
}
|
||||
@@ -1212,11 +1127,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
|
||||
try
|
||||
{
|
||||
if (Context.RunspaceConfiguration != null)
|
||||
{
|
||||
Context.RunspaceConfiguration.Types.Update();
|
||||
}
|
||||
else if (Context.InitialSessionState != null)
|
||||
if (Context.InitialSessionState != null)
|
||||
{
|
||||
bool oldRefreshTypeFormatSetting = Context.InitialSessionState.RefreshTypeAndFormatSetting;
|
||||
try
|
||||
@@ -1279,17 +1190,13 @@ namespace Microsoft.PowerShell.Commands
|
||||
else
|
||||
{
|
||||
// Type is removed successfully, add it into the cache
|
||||
if (Context.RunspaceConfiguration != null)
|
||||
{
|
||||
Context.RunspaceConfiguration.Types.Append(new TypeConfigurationEntry(type, true));
|
||||
}
|
||||
else if (Context.InitialSessionState != null)
|
||||
if (Context.InitialSessionState != null)
|
||||
{
|
||||
Context.InitialSessionState.Types.Add(new SessionStateTypeEntry(type, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
Dbg.Assert(false, "Either RunspaceConfiguration or InitialSessionState must be non-null for Remove-Typedata to work");
|
||||
Dbg.Assert(false, "InitialSessionState must be non-null for Remove-Typedata to work");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,10 +66,6 @@ namespace Microsoft.PowerShell
|
||||
///
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="configuration">
|
||||
/// Configuration information to use for creating runspace.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="bannerText">
|
||||
/// Banner text to be displayed by ConsoleHost
|
||||
/// </param>
|
||||
@@ -78,12 +74,6 @@ namespace Microsoft.PowerShell
|
||||
/// Help text for minishell. This is displayed on 'minishell -?'.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="preStartWarning">
|
||||
///
|
||||
/// Warning occurred prior to this point, for example, a snap-in fails to load beforehand.
|
||||
/// This string will be printed out.
|
||||
///
|
||||
/// </param>
|
||||
/// <param name = "args">
|
||||
///
|
||||
/// Command line parameters to pwsh.exe
|
||||
@@ -118,10 +108,8 @@ namespace Microsoft.PowerShell
|
||||
///
|
||||
/// </returns>
|
||||
internal static int Start(
|
||||
RunspaceConfiguration configuration,
|
||||
string bannerText,
|
||||
string helpText,
|
||||
string preStartWarning,
|
||||
string[] args)
|
||||
{
|
||||
#if DEBUG
|
||||
@@ -178,7 +166,7 @@ namespace Microsoft.PowerShell
|
||||
HostException hostException = null;
|
||||
try
|
||||
{
|
||||
s_theConsoleHost = ConsoleHost.CreateSingletonInstance(configuration);
|
||||
s_theConsoleHost = ConsoleHost.CreateSingletonInstance();
|
||||
}
|
||||
catch (HostException e)
|
||||
{
|
||||
@@ -257,11 +245,6 @@ namespace Microsoft.PowerShell
|
||||
s_theConsoleHost.BindBreakHandler();
|
||||
PSHost.IsStdOutputRedirected = Console.IsOutputRedirected;
|
||||
|
||||
if (!string.IsNullOrEmpty(preStartWarning))
|
||||
{
|
||||
s_theConsoleHost.UI.WriteWarningLine(preStartWarning);
|
||||
}
|
||||
|
||||
// Send startup telemetry for ConsoleHost startup
|
||||
ApplicationInsightsTelemetry.SendPSCoreStartupTelemetry();
|
||||
|
||||
@@ -269,7 +252,7 @@ namespace Microsoft.PowerShell
|
||||
s_theConsoleHost.LoadPSReadline()
|
||||
? "StartupProfileData-Interactive"
|
||||
: "StartupProfileData-NonInteractive");
|
||||
exitCode = s_theConsoleHost.Run(s_cpp, !string.IsNullOrEmpty(preStartWarning));
|
||||
exitCode = s_theConsoleHost.Run(s_cpp, false);
|
||||
}
|
||||
}
|
||||
finally
|
||||
@@ -415,10 +398,6 @@ namespace Microsoft.PowerShell
|
||||
|
||||
lock (host.hostGlobalLock)
|
||||
{
|
||||
if (host._isCtrlCDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
bht = host._breakHandlerThread;
|
||||
if (!host.ShouldEndSession && shouldEndSession)
|
||||
{
|
||||
@@ -517,10 +496,10 @@ namespace Microsoft.PowerShell
|
||||
/// <summary>
|
||||
/// Create single instance of ConsoleHost.
|
||||
/// </summary>
|
||||
internal static ConsoleHost CreateSingletonInstance(RunspaceConfiguration configuration)
|
||||
internal static ConsoleHost CreateSingletonInstance()
|
||||
{
|
||||
Dbg.Assert(s_theConsoleHost == null, "CreateSingletonInstance should not be called multiple times");
|
||||
s_theConsoleHost = new ConsoleHost(configuration);
|
||||
s_theConsoleHost = new ConsoleHost();
|
||||
return s_theConsoleHost;
|
||||
}
|
||||
|
||||
@@ -1080,7 +1059,7 @@ namespace Microsoft.PowerShell
|
||||
/// Constructs a new instance
|
||||
///
|
||||
/// </summary>
|
||||
internal ConsoleHost(RunspaceConfiguration configuration)
|
||||
internal ConsoleHost()
|
||||
{
|
||||
#if !UNIX
|
||||
try
|
||||
@@ -1106,7 +1085,6 @@ namespace Microsoft.PowerShell
|
||||
InDebugMode = false;
|
||||
_displayDebuggerBanner = true;
|
||||
|
||||
_configuration = configuration;
|
||||
this.ui = new ConsoleHostUserInterface(this);
|
||||
_consoleWriter = new ConsoleTextWriter(ui);
|
||||
|
||||
@@ -1590,10 +1568,7 @@ namespace Microsoft.PowerShell
|
||||
private void DoCreateRunspace(string initialCommand, bool skipProfiles, bool staMode, string configurationName, Collection<CommandParameter> initialCommandArgs)
|
||||
{
|
||||
Dbg.Assert(_runspaceRef == null, "runspace should be null");
|
||||
#if !DEBUG
|
||||
Dbg.Assert(_configuration != null, "configuration should be set");
|
||||
#endif
|
||||
|
||||
Dbg.Assert(DefaultInitialSessionState != null, "DefaultInitialSessionState should not be null");
|
||||
s_runspaceInitTracer.WriteLine("Calling RunspaceFactory.CreateRunspace");
|
||||
|
||||
try
|
||||
@@ -1601,50 +1576,41 @@ namespace Microsoft.PowerShell
|
||||
Runspace consoleRunspace = null;
|
||||
bool psReadlineFailed = false;
|
||||
|
||||
// Use InitialSessionState if available.
|
||||
if (DefaultInitialSessionState != null)
|
||||
// Load PSReadline by default unless there is no use:
|
||||
// - we're running a command/file and just exiting
|
||||
// - stdin is redirected by a parent process
|
||||
// - we're not interactive
|
||||
// - we're explicitly reading from stdin (the '-' argument)
|
||||
// It's also important to have a scenario where PSReadline is not loaded so it can be updated, e.g.
|
||||
// powershell -command "Update-Module PSReadline"
|
||||
// This should work just fine as long as no other instances of PowerShell are running.
|
||||
ReadOnlyCollection<Microsoft.PowerShell.Commands.ModuleSpecification> defaultImportModulesList = null;
|
||||
if (LoadPSReadline())
|
||||
{
|
||||
// Load PSReadline by default unless there is no use:
|
||||
// - we're running a command/file and just exiting
|
||||
// - stdin is redirected by a parent process
|
||||
// - we're not interactive
|
||||
// - we're explicitly reading from stdin (the '-' argument)
|
||||
// It's also important to have a scenario where PSReadline is not loaded so it can be updated, e.g.
|
||||
// powershell -command "Update-Module PSReadline"
|
||||
// This should work just fine as long as no other instances of PowerShell are running.
|
||||
ReadOnlyCollection<Microsoft.PowerShell.Commands.ModuleSpecification> defaultImportModulesList = null;
|
||||
if (LoadPSReadline())
|
||||
// Create and open Runspace with PSReadline.
|
||||
defaultImportModulesList = DefaultInitialSessionState.Modules;
|
||||
DefaultInitialSessionState.ImportPSModule(new[] { "PSReadLine" });
|
||||
consoleRunspace = RunspaceFactory.CreateRunspace(this, DefaultInitialSessionState);
|
||||
try
|
||||
{
|
||||
// Create and open Runspace with PSReadline.
|
||||
defaultImportModulesList = DefaultInitialSessionState.Modules;
|
||||
DefaultInitialSessionState.ImportPSModule(new[] { "PSReadLine" });
|
||||
consoleRunspace = RunspaceFactory.CreateRunspace(this, DefaultInitialSessionState);
|
||||
try
|
||||
{
|
||||
OpenConsoleRunspace(consoleRunspace, staMode);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
consoleRunspace = null;
|
||||
psReadlineFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (consoleRunspace == null)
|
||||
{
|
||||
if (psReadlineFailed)
|
||||
{
|
||||
// Try again but without importing the PSReadline module.
|
||||
DefaultInitialSessionState.ClearPSModules();
|
||||
DefaultInitialSessionState.ImportPSModule(defaultImportModulesList);
|
||||
}
|
||||
consoleRunspace = RunspaceFactory.CreateRunspace(this, DefaultInitialSessionState);
|
||||
OpenConsoleRunspace(consoleRunspace, staMode);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
consoleRunspace = null;
|
||||
psReadlineFailed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (consoleRunspace == null)
|
||||
{
|
||||
consoleRunspace = RunspaceFactory.CreateRunspace(this, _configuration);
|
||||
if (psReadlineFailed)
|
||||
{
|
||||
// Try again but without importing the PSReadline module.
|
||||
DefaultInitialSessionState.ClearPSModules();
|
||||
DefaultInitialSessionState.ImportPSModule(defaultImportModulesList);
|
||||
}
|
||||
consoleRunspace = RunspaceFactory.CreateRunspace(this, DefaultInitialSessionState);
|
||||
OpenConsoleRunspace(consoleRunspace, staMode);
|
||||
}
|
||||
|
||||
@@ -1728,46 +1694,7 @@ namespace Microsoft.PowerShell
|
||||
}
|
||||
else
|
||||
{
|
||||
// Run the built-in scripts
|
||||
RunspaceConfigurationEntryCollection<ScriptConfigurationEntry> scripts = new RunspaceConfigurationEntryCollection<ScriptConfigurationEntry>();
|
||||
if (_configuration != null)
|
||||
scripts = _configuration.InitializationScripts;
|
||||
|
||||
if ((scripts == null) || (scripts.Count == 0))
|
||||
{
|
||||
s_runspaceInitTracer.WriteLine("There are no built-in scripts to run");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (ScriptConfigurationEntry s in scripts)
|
||||
{
|
||||
s_runspaceInitTracer.WriteLine("Running script: '{0}'", s.Name);
|
||||
|
||||
// spec claims that Ctrl-C is not supposed to stop these.
|
||||
|
||||
try
|
||||
{
|
||||
_isCtrlCDisabled = true;
|
||||
Exception e = InitializeRunspaceHelper(s.Definition, exec, Executor.ExecutionOptions.AddOutputter);
|
||||
if (e != null)
|
||||
{
|
||||
throw new ConsoleHostStartupException(ConsoleHostStrings.InitScriptFailed, e);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isCtrlCDisabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If -iss has been specified, then there won't be a runspace
|
||||
// configuration to get the shell ID from, so we'll use the default...
|
||||
string shellId = null;
|
||||
if (_configuration != null)
|
||||
shellId = _configuration.ShellId;
|
||||
else
|
||||
shellId = "Microsoft.PowerShell"; // TODO: what will happen for custom shells built using Make-Shell.exe
|
||||
string shellId = "Microsoft.PowerShell";
|
||||
|
||||
// If the system lockdown policy says "Enforce", do so. Do this after types / formatting, default functions, etc
|
||||
// are loaded so that they are trusted. (Validation of their signatures is done in F&O)
|
||||
@@ -2928,11 +2855,9 @@ namespace Microsoft.PowerShell
|
||||
private Version _ver = PSVersionInfo.PSVersion;
|
||||
private int _exitCodeFromRunspace;
|
||||
private bool _noExit = true;
|
||||
private bool _isCtrlCDisabled;
|
||||
private bool _setShouldExitCalled;
|
||||
private bool _isRunningPromptLoop;
|
||||
private bool _wasInitialCommandEncoded;
|
||||
private RunspaceConfiguration _configuration;
|
||||
|
||||
// hostGlobalLock is used to sync public method calls (in case multiple threads call into the host) and access to
|
||||
// state that persists across method calls, like progress data. It's internal because the ui object also
|
||||
|
||||
@@ -21,55 +21,13 @@ namespace Microsoft.PowerShell
|
||||
/// <param name="args">Commandline parameters specified by user.</param>
|
||||
/// <returns>An integer value which should be used as exit code for the process.</returns>
|
||||
public static int Start(string bannerText, string helpText, string[] args)
|
||||
{
|
||||
return Start(null, bannerText, helpText, null, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Entry point in to ConsoleShell. This method is called from the native or managed exe host application
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="configuration">
|
||||
/// Configuration information which is used to create Runspace.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="bannerText">
|
||||
/// Banner text to be displayed by ConsoleHost
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="helpText">
|
||||
/// Help text for minishell. This is displayed on 'minishell -?'.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="preStartWarning">
|
||||
/// Warning occurred prior to this point, for example, a snap-in fails to load beforehand.
|
||||
/// This string will be printed out.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="args">
|
||||
/// Commandline parameters specified by user.
|
||||
/// </param>
|
||||
///
|
||||
/// <returns>
|
||||
/// An integer value which should be used as exit code for the
|
||||
/// process.
|
||||
/// </returns>
|
||||
|
||||
internal static
|
||||
int
|
||||
Start(RunspaceConfiguration configuration,
|
||||
string bannerText,
|
||||
string helpText,
|
||||
string preStartWarning,
|
||||
string[] args)
|
||||
{
|
||||
if (args == null)
|
||||
{
|
||||
throw PSTraceSource.NewArgumentNullException("args");
|
||||
}
|
||||
|
||||
return ConsoleHost.Start(configuration, bannerText, helpText, preStartWarning, args);
|
||||
return ConsoleHost.Start(bannerText, helpText, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Microsoft.PowerShell
|
||||
/// Starts managed MSH
|
||||
/// </summary>
|
||||
/// <param name="consoleFilePath">
|
||||
/// Console file used to create a runspace configuration to start MSH
|
||||
/// Deprecated: Console file used to create a runspace configuration to start MSH
|
||||
/// </param>
|
||||
/// <param name="args">
|
||||
/// Command line arguments to the managed MSH
|
||||
@@ -55,54 +55,26 @@ namespace Microsoft.PowerShell
|
||||
Thread.CurrentThread.CurrentUICulture = NativeCultureResolver.UICulture;
|
||||
Thread.CurrentThread.CurrentCulture = NativeCultureResolver.Culture;
|
||||
|
||||
RunspaceConfigForSingleShell configuration = null;
|
||||
PSConsoleLoadException warning = null;
|
||||
// PSSnapInException will cause the control to return back to the native code
|
||||
// and stuff the EXCEPINFO field with the message of the exception.
|
||||
// The native code will print this out and exit the process.
|
||||
if (string.IsNullOrEmpty(consoleFilePath))
|
||||
{
|
||||
#if DEBUG
|
||||
// Special switches for debug mode to allow self-hosting on InitialSessionState instead
|
||||
// of runspace configuration...
|
||||
if (args.Length > 0 && !String.IsNullOrEmpty(args[0]) && args[0].Equals("-iss", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
ConsoleHost.DefaultInitialSessionState = InitialSessionState.CreateDefault2();
|
||||
configuration = null;
|
||||
}
|
||||
else if (args.Length > 0 && !String.IsNullOrEmpty(args[0]) && args[0].Equals("-isswait", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Console.WriteLine("Attach the debugger and hit enter to continue:");
|
||||
Console.ReadLine();
|
||||
ConsoleHost.DefaultInitialSessionState = InitialSessionState.CreateDefault2();
|
||||
configuration = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleHost.DefaultInitialSessionState = InitialSessionState.CreateDefault2();
|
||||
configuration = null;
|
||||
}
|
||||
#else
|
||||
ConsoleHost.DefaultInitialSessionState = InitialSessionState.CreateDefault2();
|
||||
configuration = null;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
if (args.Length > 0 && !String.IsNullOrEmpty(args[0]) && args[0].Equals("-isswait", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
//TODO : Deprecate RunspaceConfiguration and use InitialSessionState
|
||||
configuration =
|
||||
RunspaceConfigForSingleShell.Create(consoleFilePath, out warning);
|
||||
Console.WriteLine("Attach the debugger to continue...");
|
||||
while (!System.Diagnostics.Debugger.IsAttached) {
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
System.Diagnostics.Debugger.Break();
|
||||
}
|
||||
#endif
|
||||
ConsoleHost.DefaultInitialSessionState = InitialSessionState.CreateDefault2();
|
||||
|
||||
int exitCode = 0;
|
||||
try
|
||||
{
|
||||
var banner = ManagedEntranceStrings.ShellBannerNonWindowsPowerShell;
|
||||
var formattedBanner = string.Format(CultureInfo.InvariantCulture, banner, PSVersionInfo.GitCommitId);
|
||||
exitCode = Microsoft.PowerShell.ConsoleShell.Start(
|
||||
configuration,
|
||||
formattedBanner,
|
||||
ManagedEntranceStrings.ShellHelp,
|
||||
warning == null ? null : warning.Message,
|
||||
args);
|
||||
}
|
||||
catch (System.Management.Automation.Host.HostException e)
|
||||
|
||||
@@ -37,60 +37,15 @@ namespace System.Management.Automation
|
||||
/// an instance of the automation engine. It allows you to pass in an
|
||||
/// instance of PSHost that provides the host-specific I/O routines, etc.
|
||||
/// </summary>
|
||||
internal AutomationEngine(PSHost hostInterface, RunspaceConfiguration runspaceConfiguration, InitialSessionState iss)
|
||||
internal AutomationEngine(PSHost hostInterface, InitialSessionState iss)
|
||||
{
|
||||
#if !CORECLR// There is no control panel items in CSS
|
||||
// Update the env variable PathEXT to contain .CPL
|
||||
var pathext = Environment.GetEnvironmentVariable("PathEXT");
|
||||
pathext = pathext ?? string.Empty;
|
||||
bool cplExist = false;
|
||||
if (pathext != string.Empty)
|
||||
{
|
||||
string[] entries = pathext.Split(Utils.Separators.Semicolon);
|
||||
foreach (string entry in entries)
|
||||
{
|
||||
string ext = entry.Trim();
|
||||
if (ext.Equals(".CPL", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
cplExist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cplExist)
|
||||
{
|
||||
pathext = (pathext == string.Empty) ? ".CPL" :
|
||||
pathext.EndsWith(";", StringComparison.OrdinalIgnoreCase)
|
||||
? (pathext + ".CPL") : (pathext + ";.CPL");
|
||||
Environment.SetEnvironmentVariable("PathEXT", pathext);
|
||||
}
|
||||
#endif
|
||||
if (runspaceConfiguration != null)
|
||||
{
|
||||
Context = new ExecutionContext(this, hostInterface, runspaceConfiguration);
|
||||
}
|
||||
else
|
||||
{
|
||||
Context = new ExecutionContext(this, hostInterface, iss);
|
||||
}
|
||||
Context = new ExecutionContext(this, hostInterface, iss);
|
||||
|
||||
EngineParser = new Language.Parser();
|
||||
CommandDiscovery = new CommandDiscovery(Context);
|
||||
|
||||
// Initialize providers before loading types so that any ScriptBlocks in the
|
||||
// types.ps1xml file can be parsed.
|
||||
|
||||
// Bind the execution context with RunspaceConfiguration.
|
||||
// This has the side effect of initializing cmdlet cache and providers from runspace configuration.
|
||||
if (runspaceConfiguration != null)
|
||||
{
|
||||
runspaceConfiguration.Bind(Context);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Load the iss, resetting everything to it's defaults...
|
||||
iss.Bind(Context, /*updateOnly*/ false);
|
||||
}
|
||||
// Load the iss, resetting everything to it's defaults...
|
||||
iss.Bind(Context, /*updateOnly*/ false);
|
||||
|
||||
InitialSessionState.SetSessionStateDrive(Context, true);
|
||||
}
|
||||
|
||||
@@ -138,13 +138,6 @@ namespace System.Management.Automation
|
||||
|
||||
Context = context;
|
||||
discoveryTracer.ShowHeaders = false;
|
||||
|
||||
// Cache the ScriptInfo for the scripts defined in the RunspaceConfiguration
|
||||
|
||||
_cachedScriptInfo =
|
||||
new Dictionary<string, ScriptInfo>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
LoadScriptInfo();
|
||||
}
|
||||
|
||||
private void AddCmdletToCache(CmdletConfigurationEntry entry)
|
||||
@@ -274,28 +267,6 @@ namespace System.Management.Automation
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadScriptInfo()
|
||||
{
|
||||
if (Context.RunspaceConfiguration != null)
|
||||
{
|
||||
foreach (ScriptConfigurationEntry entry in Context.RunspaceConfiguration.Scripts)
|
||||
{
|
||||
try
|
||||
{
|
||||
_cachedScriptInfo.Add(entry.Name, new ScriptInfo(entry.Name, ScriptBlock.Create(Context, entry.Definition), Context));
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
PSNotSupportedException notSupported =
|
||||
PSTraceSource.NewNotSupportedException(
|
||||
DiscoveryExceptions.DuplicateScriptName,
|
||||
entry.Name);
|
||||
|
||||
throw notSupported;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion ctor
|
||||
|
||||
#region internal methods
|
||||
@@ -358,56 +329,6 @@ namespace System.Management.Automation
|
||||
return processor;
|
||||
}
|
||||
|
||||
//Minishell ExternalScriptInfo scriptInfo
|
||||
|
||||
internal CommandProcessorBase CreateScriptProcessorForMiniShell(ExternalScriptInfo scriptInfo, bool useLocalScope, SessionStateInternal sessionState)
|
||||
{
|
||||
VerifyScriptRequirements(scriptInfo, Context);
|
||||
|
||||
if (String.IsNullOrEmpty(scriptInfo.RequiresApplicationID))
|
||||
{
|
||||
if (scriptInfo.RequiresPSSnapIns != null && scriptInfo.RequiresPSSnapIns.Any())
|
||||
{
|
||||
Collection<string> requiresMissingPSSnapIns = GetPSSnapinNames(scriptInfo.RequiresPSSnapIns);
|
||||
|
||||
ScriptRequiresException scriptRequiresException =
|
||||
new ScriptRequiresException(
|
||||
scriptInfo.Name,
|
||||
requiresMissingPSSnapIns,
|
||||
"ScriptRequiresMissingPSSnapIns",
|
||||
true);
|
||||
throw scriptRequiresException;
|
||||
}
|
||||
|
||||
return CreateCommandProcessorForScript(scriptInfo, Context, useLocalScope, sessionState);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (String.Equals(
|
||||
Context.ShellID,
|
||||
scriptInfo.RequiresApplicationID,
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return CreateCommandProcessorForScript(scriptInfo, Context, useLocalScope, sessionState);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Throw a runtime exception
|
||||
|
||||
string shellPath = GetShellPathFromRegistry(scriptInfo.RequiresApplicationID);
|
||||
|
||||
ScriptRequiresException sre =
|
||||
new ScriptRequiresException(
|
||||
scriptInfo.Name,
|
||||
scriptInfo.RequiresApplicationID,
|
||||
shellPath,
|
||||
"ScriptRequiresUnmatchedShellId");
|
||||
|
||||
throw sre;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void VerifyRequiredModules(ExternalScriptInfo scriptInfo, ExecutionContext context)
|
||||
{
|
||||
// Check Required Modules
|
||||
@@ -492,33 +413,12 @@ namespace System.Management.Automation
|
||||
private static void VerifyRequiredSnapins(IEnumerable<PSSnapInSpecification> requiresPSSnapIns, ExecutionContext context, out Collection<string> requiresMissingPSSnapIns)
|
||||
{
|
||||
requiresMissingPSSnapIns = null;
|
||||
bool isHostedWithInitialSessionState = false;
|
||||
RunspaceConfigForSingleShell rs = null;
|
||||
if (context.InitialSessionState != null)
|
||||
{
|
||||
isHostedWithInitialSessionState = true;
|
||||
}
|
||||
else if (context.RunspaceConfiguration != null)
|
||||
{
|
||||
rs = context.RunspaceConfiguration as RunspaceConfigForSingleShell;
|
||||
Dbg.Assert(rs != null, "RunspaceConfiguration should not be null");
|
||||
}
|
||||
else
|
||||
{
|
||||
Dbg.Assert(false, "PowerShell should be hosted with either InitialSessionState or RunspaceConfiguration");
|
||||
}
|
||||
Dbg.Assert(context.InitialSessionState != null, "PowerShell should be hosted with InitialSessionState");
|
||||
|
||||
foreach (var requiresPSSnapIn in requiresPSSnapIns)
|
||||
{
|
||||
IEnumerable<PSSnapInInfo> loadedPSSnapIns = null;
|
||||
if (isHostedWithInitialSessionState)
|
||||
{
|
||||
loadedPSSnapIns = context.InitialSessionState.GetPSSnapIn(requiresPSSnapIn.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
loadedPSSnapIns = rs.ConsoleInfo.GetPSSnapIn(requiresPSSnapIn.Name, false);
|
||||
}
|
||||
loadedPSSnapIns = context.InitialSessionState.GetPSSnapIn(requiresPSSnapIn.Name);
|
||||
if (loadedPSSnapIns == null || loadedPSSnapIns.Count() == 0)
|
||||
{
|
||||
if (requiresMissingPSSnapIns == null)
|
||||
@@ -758,16 +658,7 @@ namespace System.Management.Automation
|
||||
scriptInfo.SignatureChecked = true;
|
||||
try
|
||||
{
|
||||
if (!Context.IsSingleShell)
|
||||
{
|
||||
// in minishell mode
|
||||
processor = CreateScriptProcessorForMiniShell(scriptInfo, useLocalScope ?? true, sessionState);
|
||||
}
|
||||
else
|
||||
{
|
||||
// single shell mode
|
||||
processor = CreateScriptProcessorForSingleShell(scriptInfo, Context, useLocalScope ?? true, sessionState);
|
||||
}
|
||||
processor = CreateScriptProcessorForSingleShell(scriptInfo, Context, useLocalScope ?? true, sessionState);
|
||||
}
|
||||
catch (ScriptRequiresSyntaxException reqSyntaxException)
|
||||
{
|
||||
@@ -1724,51 +1615,6 @@ namespace System.Management.Automation
|
||||
}
|
||||
} // GetCmdletInfo
|
||||
|
||||
private bool _cmdletCacheInitialized = false;
|
||||
|
||||
/// <summary>
|
||||
/// Called by the RunspaceConfiguration when a PSSnapIn gets added to the
|
||||
/// console to update the list of available cmdlets.
|
||||
/// </summary>
|
||||
///
|
||||
internal void UpdateCmdletCache()
|
||||
{
|
||||
if (!_cmdletCacheInitialized)
|
||||
{
|
||||
foreach (CmdletConfigurationEntry entry in Context.RunspaceConfiguration.Cmdlets)
|
||||
{
|
||||
AddCmdletToCache(entry);
|
||||
}
|
||||
|
||||
_cmdletCacheInitialized = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (CmdletConfigurationEntry entry in Context.RunspaceConfiguration.Cmdlets.UpdateList)
|
||||
{
|
||||
if (entry == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (entry.Action)
|
||||
{
|
||||
case UpdateAction.Add:
|
||||
AddCmdletToCache(entry);
|
||||
break;
|
||||
|
||||
case UpdateAction.Remove:
|
||||
RemoveCmdletFromCache(entry);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // UpdateCmdletCache
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Removes a cmdlet from the cmdlet cache.
|
||||
/// </summary>
|
||||
@@ -1814,46 +1660,6 @@ namespace System.Management.Automation
|
||||
return removalIndex;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cached ScriptInfo for a command using the script name.
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="name">
|
||||
/// The name of the script.
|
||||
/// </param>
|
||||
///
|
||||
/// <returns>
|
||||
/// A reference to the ScriptInfo for the command if its in the cache,
|
||||
/// or null otherwise.
|
||||
/// </returns>
|
||||
///
|
||||
internal ScriptInfo GetScriptInfo(string name)
|
||||
{
|
||||
Dbg.Assert(
|
||||
!String.IsNullOrEmpty(name),
|
||||
"The caller should verify the name");
|
||||
|
||||
ScriptInfo result;
|
||||
_cachedScriptInfo.TryGetValue(name, out result);
|
||||
return result;
|
||||
} // GetScriptInfo
|
||||
|
||||
/// <summary>
|
||||
/// Gets the script cache
|
||||
/// </summary>
|
||||
///
|
||||
internal Dictionary<string, ScriptInfo> ScriptCache
|
||||
{
|
||||
get { return _cachedScriptInfo; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The cache for the ScriptInfo.
|
||||
/// </summary>
|
||||
///
|
||||
private Dictionary<string, ScriptInfo> _cachedScriptInfo;
|
||||
|
||||
internal ExecutionContext Context { get; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -132,18 +132,6 @@ namespace System.Management.Automation
|
||||
return true;
|
||||
}
|
||||
|
||||
// Advance the state
|
||||
_currentState = SearchState.SearchingBuiltinScripts;
|
||||
}
|
||||
|
||||
if (_currentState == SearchState.SearchingBuiltinScripts)
|
||||
{
|
||||
_currentMatch = SearchForBuiltinScripts();
|
||||
if (_currentMatch != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Advance the state
|
||||
_currentState = SearchState.StartSearchingForExternalCommands;
|
||||
}
|
||||
@@ -301,18 +289,6 @@ namespace System.Management.Automation
|
||||
return currentMatch;
|
||||
}
|
||||
|
||||
private CommandInfo SearchForBuiltinScripts()
|
||||
{
|
||||
CommandInfo currentMatch = null;
|
||||
|
||||
if ((_commandTypes & CommandTypes.Script) != 0)
|
||||
{
|
||||
currentMatch = GetNextBuiltinScript();
|
||||
}
|
||||
|
||||
return currentMatch;
|
||||
}
|
||||
|
||||
private CommandInfo ProcessBuiltinScriptState()
|
||||
{
|
||||
CommandInfo currentMatch = null;
|
||||
@@ -1043,7 +1019,7 @@ namespace System.Management.Automation
|
||||
if (!_matchingCmdlet.MoveNext())
|
||||
{
|
||||
// Advance the state
|
||||
_currentState = SearchState.SearchingBuiltinScripts;
|
||||
_currentState = SearchState.StartSearchingForExternalCommands;
|
||||
|
||||
_matchingCmdlet = null;
|
||||
}
|
||||
@@ -1068,86 +1044,6 @@ namespace System.Management.Automation
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the next builtin script from the collection of matching scripts.
|
||||
/// If the collection doesn't exist yet it is created and the
|
||||
/// enumerator is moved to the first item in the collection.
|
||||
/// </summary>
|
||||
///
|
||||
/// <returns>
|
||||
/// A ScriptInfo for the next matching script or null if there are
|
||||
/// no more matches.
|
||||
/// </returns>
|
||||
///
|
||||
private ScriptInfo GetNextBuiltinScript()
|
||||
{
|
||||
ScriptInfo result = null;
|
||||
|
||||
if ((_commandResolutionOptions & SearchResolutionOptions.CommandNameIsPattern) != 0)
|
||||
{
|
||||
if (_matchingScript == null)
|
||||
{
|
||||
// Generate the enumerator of matching script names
|
||||
|
||||
Collection<string> matchingScripts =
|
||||
new Collection<string>();
|
||||
|
||||
WildcardPattern scriptMatcher =
|
||||
WildcardPattern.Get(
|
||||
_commandName,
|
||||
WildcardOptions.IgnoreCase);
|
||||
|
||||
WildcardPattern scriptExtensionMatcher =
|
||||
WildcardPattern.Get(
|
||||
_commandName + StringLiterals.PowerShellScriptFileExtension,
|
||||
WildcardOptions.IgnoreCase);
|
||||
|
||||
// Get the script cache enumerator. This acquires the cache lock,
|
||||
// so be sure to dispose.
|
||||
|
||||
foreach (string scriptName in _context.CommandDiscovery.ScriptCache.Keys)
|
||||
{
|
||||
if (scriptMatcher.IsMatch(scriptName) ||
|
||||
scriptExtensionMatcher.IsMatch(scriptName))
|
||||
{
|
||||
matchingScripts.Add(scriptName);
|
||||
}
|
||||
}
|
||||
_matchingScript = matchingScripts.GetEnumerator();
|
||||
}
|
||||
|
||||
if (!_matchingScript.MoveNext())
|
||||
{
|
||||
// Advance the state
|
||||
_currentState = SearchState.StartSearchingForExternalCommands;
|
||||
|
||||
_matchingScript = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = _context.CommandDiscovery.GetScriptInfo(_matchingScript.Current);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Advance the state
|
||||
_currentState = SearchState.StartSearchingForExternalCommands;
|
||||
|
||||
result = _context.CommandDiscovery.GetScriptInfo(_commandName) ??
|
||||
_context.CommandDiscovery.GetScriptInfo(_commandName + StringLiterals.PowerShellScriptFileExtension);
|
||||
}
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
CommandDiscovery.discoveryTracer.WriteLine(
|
||||
"Script found: {0}",
|
||||
result.Name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private IEnumerator<string> _matchingScript;
|
||||
|
||||
|
||||
private string DoPowerShellRelativePathLookup()
|
||||
{
|
||||
string result = null;
|
||||
@@ -1632,7 +1528,6 @@ namespace System.Management.Automation
|
||||
_currentState = SearchState.SearchingAliases;
|
||||
_matchingAlias = null;
|
||||
_matchingCmdlet = null;
|
||||
_matchingScript = null;
|
||||
} // Reset
|
||||
|
||||
internal CommandOrigin CommandOrigin
|
||||
@@ -1676,9 +1571,6 @@ namespace System.Management.Automation
|
||||
// the searcher has finished function resolution and is now searching for cmdlets
|
||||
SearchingCmdlets,
|
||||
|
||||
// the search has finished cmdlet resolution and is now searching for builtin scripts
|
||||
SearchingBuiltinScripts,
|
||||
|
||||
// the search has finished builtin script resolution and is now searching for external commands
|
||||
StartSearchingForExternalCommands,
|
||||
|
||||
|
||||
@@ -169,26 +169,8 @@ namespace System.Management.Automation
|
||||
/// </summary>
|
||||
internal AutomationEngine Engine { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the RunspaceConfiguration instance
|
||||
/// </summary>
|
||||
internal RunspaceConfiguration RunspaceConfiguration { get; }
|
||||
|
||||
internal InitialSessionState InitialSessionState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// True if the RunspaceConfiguration/InitialSessionState is for a single shell or false otherwise.
|
||||
/// </summary>
|
||||
///
|
||||
internal bool IsSingleShell
|
||||
{
|
||||
get
|
||||
{
|
||||
RunspaceConfigForSingleShell runSpace = RunspaceConfiguration as RunspaceConfigForSingleShell;
|
||||
return runSpace != null || InitialSessionState != null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Added for Win8: 336382
|
||||
/// Contains the name of the previous module that was processed. This
|
||||
@@ -259,14 +241,7 @@ namespace System.Management.Automation
|
||||
{
|
||||
if (_providerNames == null)
|
||||
{
|
||||
if (IsSingleShell)
|
||||
{
|
||||
_providerNames = new SingleShellProviderNames();
|
||||
}
|
||||
else
|
||||
{
|
||||
_providerNames = new CustomShellProviderNames();
|
||||
}
|
||||
_providerNames = new SingleShellProviderNames();
|
||||
}
|
||||
return _providerNames;
|
||||
}
|
||||
@@ -293,11 +268,6 @@ namespace System.Management.Automation
|
||||
{
|
||||
_shellId = AuthorizationManager.ShellId;
|
||||
}
|
||||
else if (RunspaceConfiguration != null && !String.IsNullOrEmpty(RunspaceConfiguration.ShellId))
|
||||
{
|
||||
// Otherwise fall back to the runspace shell id if it's there...
|
||||
_shellId = RunspaceConfiguration.ShellId;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Finally fall back to the default shell id...
|
||||
@@ -1090,13 +1060,8 @@ namespace System.Management.Automation
|
||||
|
||||
internal void RunspaceClosingNotification()
|
||||
{
|
||||
if (this.RunspaceConfiguration != null)
|
||||
{
|
||||
this.RunspaceConfiguration.Unbind(this);
|
||||
}
|
||||
|
||||
EngineSessionState.RunspaceClosingNotification();
|
||||
|
||||
|
||||
if (_debugger != null)
|
||||
{
|
||||
_debugger.Dispose();
|
||||
@@ -1114,10 +1079,7 @@ namespace System.Management.Automation
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type table instance for this engine. This is somewhat
|
||||
/// complicated by the need to have a single type table in RunspaceConfig
|
||||
/// shared across all bound runspaces, as well as individual tables for
|
||||
/// instances created from InitialSessionState.
|
||||
/// Gets the type table instance for this engine.
|
||||
/// </summary>
|
||||
internal TypeTable TypeTable
|
||||
{
|
||||
@@ -1125,22 +1087,15 @@ namespace System.Management.Automation
|
||||
{
|
||||
if (_typeTable == null)
|
||||
{
|
||||
// Always use the type table from the RunspaceConfig if there is one, otherwise create a default one
|
||||
_typeTable = (this.RunspaceConfiguration != null && RunspaceConfiguration.TypeTable != null)
|
||||
? RunspaceConfiguration.TypeTable
|
||||
: new TypeTable();
|
||||
_typeTable = new TypeTable();
|
||||
_typeTableWeakReference = new WeakReference<TypeTable>(_typeTable);
|
||||
}
|
||||
return _typeTable;
|
||||
}
|
||||
// This needs to exist so that RunspaceConfiguration can
|
||||
// push it's shared type table into ExecutionContext
|
||||
set
|
||||
{
|
||||
if (this.RunspaceConfiguration != null)
|
||||
throw new NotImplementedException("set_TypeTable()");
|
||||
_typeTable = value;
|
||||
_typeTableWeakReference = value != null ? new WeakReference<TypeTable>(value) : null;
|
||||
_typeTableWeakReference = (value != null) ? new WeakReference<TypeTable>(value) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1163,21 +1118,12 @@ namespace System.Management.Automation
|
||||
private WeakReference<TypeTable> _typeTableWeakReference;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the format info database for this engine. This is significantly
|
||||
/// complicated by the need to have a single type table in RunspaceConfig
|
||||
/// shared across all bound runspaces, as well as individual tables for
|
||||
/// instances created from InitialSessionState.
|
||||
/// Gets the format info database for this engine.
|
||||
/// </summary>
|
||||
internal TypeInfoDataBaseManager FormatDBManager
|
||||
{
|
||||
get
|
||||
{
|
||||
// Use the format DB from the RunspaceConfig if there is one.
|
||||
if (this.RunspaceConfiguration != null && RunspaceConfiguration.FormatDBManager != null)
|
||||
{
|
||||
return RunspaceConfiguration.FormatDBManager;
|
||||
}
|
||||
|
||||
if (_formatDBManager == null)
|
||||
{
|
||||
// If no Formatter database has been created, then
|
||||
@@ -1193,13 +1139,9 @@ namespace System.Management.Automation
|
||||
}
|
||||
return _formatDBManager;
|
||||
}
|
||||
|
||||
// This needs to exist so that RunspaceConfiguration can
|
||||
// push it's shared format database table into ExecutionContext
|
||||
|
||||
set
|
||||
{
|
||||
if (this.RunspaceConfiguration != null)
|
||||
throw new NotImplementedException("set_FormatDBManager()");
|
||||
_formatDBManager = value;
|
||||
}
|
||||
}
|
||||
@@ -1218,69 +1160,6 @@ namespace System.Management.Automation
|
||||
}
|
||||
internal PSTransactionManager transactionManager;
|
||||
|
||||
|
||||
private bool _assemblyCacheInitialized = false;
|
||||
|
||||
/// <summary>
|
||||
/// This function is called by RunspaceConfiguration.Assemblies.Update call back.
|
||||
/// It's not used when constructing a runspace from an InitialSessionState object.
|
||||
/// </summary>
|
||||
internal void UpdateAssemblyCache()
|
||||
{
|
||||
string errors = "";
|
||||
|
||||
if (this.RunspaceConfiguration != null)
|
||||
{
|
||||
if (!_assemblyCacheInitialized)
|
||||
{
|
||||
foreach (AssemblyConfigurationEntry entry in this.RunspaceConfiguration.Assemblies)
|
||||
{
|
||||
Exception error = null;
|
||||
AddAssembly(entry.Name, entry.FileName, out error);
|
||||
|
||||
if (error != null)
|
||||
{
|
||||
errors += "\n" + error.Message;
|
||||
}
|
||||
}
|
||||
|
||||
_assemblyCacheInitialized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (AssemblyConfigurationEntry entry in this.RunspaceConfiguration.Assemblies.UpdateList)
|
||||
{
|
||||
switch (entry.Action)
|
||||
{
|
||||
case UpdateAction.Add:
|
||||
Exception error = null;
|
||||
AddAssembly(entry.Name, entry.FileName, out error);
|
||||
|
||||
if (error != null)
|
||||
{
|
||||
errors += "\n" + error.Message;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case UpdateAction.Remove:
|
||||
RemoveAssembly(entry.Name);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!String.IsNullOrEmpty(errors))
|
||||
{
|
||||
string message = StringUtil.Format(MiniShellErrors.UpdateAssemblyErrors, errors);
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal Assembly AddAssembly(string name, string filename, out Exception error)
|
||||
{
|
||||
Assembly loadedAssembly = LoadAssembly(name, filename, out error);
|
||||
@@ -1537,27 +1416,6 @@ namespace System.Management.Automation
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an Execution context object for Automation Engine
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="engine">
|
||||
/// Engine that hosts this execution context
|
||||
/// </param>
|
||||
/// <param name="hostInterface">
|
||||
/// Interface that should be used for interaction with host
|
||||
/// </param>
|
||||
/// <param name="runspaceConfiguration">
|
||||
/// RunspaceConfiguration information
|
||||
/// </param>
|
||||
internal ExecutionContext(AutomationEngine engine, PSHost hostInterface, RunspaceConfiguration runspaceConfiguration)
|
||||
{
|
||||
RunspaceConfiguration = runspaceConfiguration;
|
||||
AuthorizationManager = runspaceConfiguration.AuthorizationManager;
|
||||
|
||||
InitializeCommon(engine, hostInterface);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an Execution context object for Automation Engine
|
||||
/// </summary>
|
||||
|
||||
@@ -1600,6 +1600,7 @@ namespace System.Management.Automation.Runspaces
|
||||
/// <summary>
|
||||
/// Creates the default PowerShell one with default cmdlets, provider etc.
|
||||
/// The default cmdlets, provider, etc are loaded via Modules
|
||||
/// For loading Microsoft.PowerShell.Core module only.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static InitialSessionState CreateDefault2()
|
||||
@@ -3704,7 +3705,6 @@ namespace System.Management.Automation.Runspaces
|
||||
return coreSnapin;
|
||||
}
|
||||
|
||||
// WARNING: THIS CODE IS COMPLETELY DUPLICATED IN RunspaceConfigForSingleShell
|
||||
internal PSSnapInInfo ImportPSSnapIn(PSSnapInInfo psSnapInInfo, out PSSnapInException warning)
|
||||
{
|
||||
// See if the snapin is already loaded. If has been then there will be an entry in the
|
||||
@@ -4766,10 +4766,6 @@ end
|
||||
"Clear-Host", "", ScopedItemOptions.AllScope),
|
||||
//#if !CORECLR is used to disable aliases for cmdlets which are not available on OneCore
|
||||
#if !CORECLR
|
||||
new SessionStateAliasEntry("asnp",
|
||||
"Add-PSSnapIn", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
|
||||
new SessionStateAliasEntry("gsnp",
|
||||
"Get-PSSnapIn", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
|
||||
new SessionStateAliasEntry("gwmi",
|
||||
"Get-WmiObject", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
|
||||
new SessionStateAliasEntry("iwmi",
|
||||
@@ -5048,22 +5044,6 @@ if($paths) {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void SaveAsConsoleFile(string path)
|
||||
{
|
||||
if (null == path)
|
||||
{
|
||||
throw PSTraceSource.NewArgumentNullException("path");
|
||||
}
|
||||
|
||||
if (!path.EndsWith(StringLiterals.PowerShellConsoleFileExtension, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw PSTraceSource.NewArgumentException("path", ConsoleInfoErrorStrings.BadConsoleExtension);
|
||||
}
|
||||
|
||||
//ConsoleFileElement will write to file
|
||||
PSConsoleFileElement.WriteToFile(path, PSVersionInfo.PSVersion, this.ImportedSnapins.Values);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -5083,7 +5063,6 @@ if($paths) {
|
||||
|
||||
try
|
||||
{
|
||||
// WARNING: DUPLICATE CODE see RunspaceConfigForSingleShell
|
||||
assembly = Assembly.Load(new AssemblyName(psSnapInInfo.AssemblyName));
|
||||
}
|
||||
catch (BadImageFormatException e)
|
||||
|
||||
@@ -2150,8 +2150,6 @@ namespace Microsoft.PowerShell.Commands
|
||||
|
||||
// Indicates the ISS.Bind() should be called...
|
||||
bool doBind = false;
|
||||
// Indicates that RunspaceConfig.Update() should be called.
|
||||
bool doUpdate = false;
|
||||
|
||||
// Set up to load any required assemblies that have been specified...
|
||||
List<string> tmpAssemblyList;
|
||||
@@ -2233,36 +2231,28 @@ namespace Microsoft.PowerShell.Commands
|
||||
string loadMessage = StringUtil.Format(Modules.LoadingFile, "TypesToProcess", fileName);
|
||||
WriteVerbose(loadMessage);
|
||||
|
||||
if (Context.RunspaceConfiguration != null)
|
||||
bool isAlreadyLoaded = false;
|
||||
string resolvedFileName = ResolveRootedFilePath(fileName, Context) ?? fileName;
|
||||
foreach (var entry in Context.InitialSessionState.Types)
|
||||
{
|
||||
this.Context.RunspaceConfiguration.Types.Append(new TypeConfigurationEntry(fileName));
|
||||
doUpdate = true;
|
||||
if (entry.FileName == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string resolvedEntryFileName = ResolveRootedFilePath(entry.FileName, Context) ??
|
||||
entry.FileName;
|
||||
if (resolvedEntryFileName.Equals(resolvedFileName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
isAlreadyLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (!isAlreadyLoaded)
|
||||
{
|
||||
bool isAlreadyLoaded = false;
|
||||
string resolvedFileName = ResolveRootedFilePath(fileName, Context) ?? fileName;
|
||||
foreach (var entry in Context.InitialSessionState.Types)
|
||||
{
|
||||
if (entry.FileName == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string resolvedEntryFileName = ResolveRootedFilePath(entry.FileName, Context) ??
|
||||
entry.FileName;
|
||||
if (resolvedEntryFileName.Equals(resolvedFileName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
isAlreadyLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isAlreadyLoaded)
|
||||
{
|
||||
iss.Types.Add(new SessionStateTypeEntry(fileName));
|
||||
doBind = true;
|
||||
}
|
||||
iss.Types.Add(new SessionStateTypeEntry(fileName));
|
||||
doBind = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2286,32 +2276,24 @@ namespace Microsoft.PowerShell.Commands
|
||||
string loadMessage = StringUtil.Format(Modules.LoadingFile, "FormatsToProcess", fileName);
|
||||
WriteVerbose(loadMessage);
|
||||
|
||||
if (Context.RunspaceConfiguration != null)
|
||||
bool isAlreadyLoaded = false;
|
||||
foreach (var entry in Context.InitialSessionState.Formats)
|
||||
{
|
||||
this.Context.RunspaceConfiguration.Formats.Append(new FormatConfigurationEntry(fileName));
|
||||
doUpdate = true;
|
||||
if (entry.FileName == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (entry.FileName.Equals(fileName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
isAlreadyLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isAlreadyLoaded = false;
|
||||
foreach (var entry in Context.InitialSessionState.Formats)
|
||||
{
|
||||
if (entry.FileName == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (entry.FileName.Equals(fileName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
isAlreadyLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isAlreadyLoaded)
|
||||
{
|
||||
iss.Formats.Add(new SessionStateFormatEntry(fileName));
|
||||
doBind = true;
|
||||
}
|
||||
if (!isAlreadyLoaded)
|
||||
{
|
||||
iss.Formats.Add(new SessionStateFormatEntry(fileName));
|
||||
doBind = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2422,30 +2404,6 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do the runspaceconfig binding...
|
||||
if (doUpdate)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.Context.CurrentRunspace.RunspaceConfiguration.Types.Update(true);
|
||||
this.Context.CurrentRunspace.RunspaceConfiguration.Formats.Update(true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.RemoveTypesAndFormatting(exportedFormatFiles, exportedTypeFiles);
|
||||
ErrorRecord er = new ErrorRecord(e, "FormatXmlUpdateException", ErrorCategory.InvalidOperation,
|
||||
null);
|
||||
if (bailOnFirstError)
|
||||
{
|
||||
this.ThrowTerminatingError(er);
|
||||
}
|
||||
else if (writingErrors)
|
||||
{
|
||||
this.WriteError(er);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a PSModuleInfo for psd1 file or take one from ModuleToProcess manifest field
|
||||
@@ -4039,7 +3997,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
}
|
||||
|
||||
// If the RequiredModule is one of the Engine modules, then they could have been loaded as snapins (using RunspaceConfiguration or InitialSessionState.CreateDefault())
|
||||
// If the RequiredModule is one of the Engine modules, then they could have been loaded as snapins (using InitialSessionState.CreateDefault())
|
||||
if (result == null && InitialSessionState.IsEngineModule(requiredModule.Name))
|
||||
{
|
||||
result = ModuleCmdletBase.GetEngineSnapIn(context, requiredModule.Name);
|
||||
@@ -5082,68 +5040,18 @@ namespace Microsoft.PowerShell.Commands
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.Context.InitialSessionState != null)
|
||||
if (((formatFilesToRemove != null) && formatFilesToRemove.Count > 0) ||
|
||||
((typeFilesToRemove != null) && typeFilesToRemove.Count > 0))
|
||||
{
|
||||
if (((formatFilesToRemove != null) && formatFilesToRemove.Count > 0) ||
|
||||
((typeFilesToRemove != null) && typeFilesToRemove.Count > 0))
|
||||
bool oldRefreshTypeFormatSetting = this.Context.InitialSessionState.RefreshTypeAndFormatSetting;
|
||||
try
|
||||
{
|
||||
bool oldRefreshTypeFormatSetting = this.Context.InitialSessionState.RefreshTypeAndFormatSetting;
|
||||
try
|
||||
{
|
||||
this.Context.InitialSessionState.RefreshTypeAndFormatSetting = true;
|
||||
InitialSessionState.RemoveTypesAndFormats(this.Context, formatFilesToRemove, typeFilesToRemove);
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.Context.InitialSessionState.RefreshTypeAndFormatSetting = oldRefreshTypeFormatSetting;
|
||||
}
|
||||
this.Context.InitialSessionState.RefreshTypeAndFormatSetting = true;
|
||||
InitialSessionState.RemoveTypesAndFormats(this.Context, formatFilesToRemove, typeFilesToRemove);
|
||||
}
|
||||
}
|
||||
else // RunspaceConfiguration
|
||||
{
|
||||
if (formatFilesToRemove != null && formatFilesToRemove.Count > 0)
|
||||
finally
|
||||
{
|
||||
HashSet<string> formatRemoveSet = new HashSet<string>(formatFilesToRemove, StringComparer.OrdinalIgnoreCase);
|
||||
List<int> formatIndicesToRemove = new List<int>();
|
||||
|
||||
for (int index = 0; index < this.Context.RunspaceConfiguration.Formats.Count; index++)
|
||||
{
|
||||
string fileName = Context.RunspaceConfiguration.Formats[index].FileName;
|
||||
if (fileName != null && formatRemoveSet.Contains(fileName))
|
||||
{
|
||||
formatIndicesToRemove.Add(index);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = formatIndicesToRemove.Count - 1; i >= 0; i--)
|
||||
{
|
||||
Context.RunspaceConfiguration.Formats.RemoveItem(formatIndicesToRemove[i]);
|
||||
}
|
||||
|
||||
this.Context.RunspaceConfiguration.Formats.Update();
|
||||
}
|
||||
|
||||
// Remove the imported types.ps1xml files
|
||||
if (typeFilesToRemove != null && typeFilesToRemove.Count > 0)
|
||||
{
|
||||
HashSet<string> typeRemoveSet = new HashSet<string>(typeFilesToRemove, StringComparer.OrdinalIgnoreCase);
|
||||
List<int> typeIndicesToRemove = new List<int>();
|
||||
|
||||
for (int index = 0; index < this.Context.RunspaceConfiguration.Types.Count; index++)
|
||||
{
|
||||
string fileName = Context.RunspaceConfiguration.Types[index].FileName;
|
||||
if (fileName != null && typeRemoveSet.Contains(fileName))
|
||||
{
|
||||
typeIndicesToRemove.Add(index);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = typeIndicesToRemove.Count - 1; i >= 0; i--)
|
||||
{
|
||||
Context.RunspaceConfiguration.Types.RemoveItem(typeIndicesToRemove[i]);
|
||||
}
|
||||
|
||||
this.Context.RunspaceConfiguration.Types.Update();
|
||||
this.Context.InitialSessionState.RefreshTypeAndFormatSetting = oldRefreshTypeFormatSetting;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,89 +49,6 @@ namespace System.Management.Automation
|
||||
internal abstract string Registry { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The provider names for custom shells
|
||||
/// </summary>
|
||||
internal class CustomShellProviderNames : ProviderNames
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name of the EnvironmentProvider
|
||||
/// </summary>
|
||||
internal override string Environment
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Environment";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the Certificate
|
||||
/// </summary>
|
||||
internal override string Certificate
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Certificate";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the VariableProvider
|
||||
/// </summary>
|
||||
internal override string Variable
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Variable";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the AliasProvider
|
||||
/// </summary>
|
||||
internal override string Alias
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Alias";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the FunctionProvider
|
||||
/// </summary>
|
||||
internal override string Function
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Function";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the FileSystemProvider
|
||||
/// </summary>
|
||||
internal override string FileSystem
|
||||
{
|
||||
get
|
||||
{
|
||||
return "FileSystem";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the RegistryProvider
|
||||
/// </summary>
|
||||
internal override string Registry
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Registry";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The provider names for the single shell
|
||||
/// </summary>
|
||||
|
||||
+41
@@ -7,6 +7,47 @@ Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
namespace System.Management.Automation.Runspaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Enum for describing different kind information that can be configured in runspace configuration.
|
||||
/// </summary>
|
||||
internal enum RunspaceConfigurationCategory
|
||||
{
|
||||
/// <summary>
|
||||
/// Cmdlets
|
||||
/// </summary>
|
||||
Cmdlets,
|
||||
|
||||
/// <summary>
|
||||
/// Providers
|
||||
/// </summary>
|
||||
Providers,
|
||||
|
||||
/// <summary>
|
||||
/// Assemblies
|
||||
/// </summary>
|
||||
Assemblies,
|
||||
|
||||
/// <summary>
|
||||
/// Scripts
|
||||
/// </summary>
|
||||
Scripts,
|
||||
|
||||
/// <summary>
|
||||
/// Initialization scripts
|
||||
/// </summary>
|
||||
InitializationScripts,
|
||||
|
||||
/// <summary>
|
||||
/// Types
|
||||
/// </summary>
|
||||
Types,
|
||||
|
||||
/// <summary>
|
||||
/// Formats
|
||||
/// </summary>
|
||||
Formats,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Define class for runspace configuration entry.
|
||||
/// </summary>
|
||||
@@ -379,28 +379,6 @@ namespace System.Management.Automation
|
||||
RunspaceInit.PSHOMEDescription);
|
||||
|
||||
this.GlobalScope.SetVariable(v.Name, v, false, true, this, CommandOrigin.Internal, fastPath: true);
|
||||
|
||||
// $Console - set the console file for this shell, if there is one, "" otherwise...
|
||||
SetConsoleVariable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the $Console variable in this session state instance...
|
||||
/// </summary>
|
||||
internal void SetConsoleVariable()
|
||||
{
|
||||
// $Console - set the console file for this shell, if there is one, "" otherwise...
|
||||
string consoleFileName = string.Empty;
|
||||
RunspaceConfigForSingleShell rcss = ExecutionContext.RunspaceConfiguration as RunspaceConfigForSingleShell;
|
||||
if (rcss != null && rcss.ConsoleInfo != null && !string.IsNullOrEmpty(rcss.ConsoleInfo.Filename))
|
||||
{
|
||||
consoleFileName = rcss.ConsoleInfo.Filename;
|
||||
}
|
||||
PSVariable v = new PSVariable(SpecialVariables.ConsoleFileName,
|
||||
consoleFileName,
|
||||
ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope,
|
||||
RunspaceInit.ConsoleDescription);
|
||||
this.GlobalScope.SetVariable(v.Name, v, false, true, this, CommandOrigin.Internal, fastPath: true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -500,13 +478,7 @@ namespace System.Management.Automation
|
||||
|
||||
CmdletProviderContext context = new CmdletProviderContext(this.ExecutionContext);
|
||||
|
||||
Collection<string> keys = new Collection<string>();
|
||||
foreach (string key in Providers.Keys)
|
||||
{
|
||||
keys.Add(key);
|
||||
}
|
||||
|
||||
foreach (string providerName in keys)
|
||||
foreach (string providerName in Providers.Keys)
|
||||
{
|
||||
// All errors are ignored.
|
||||
|
||||
|
||||
@@ -52,48 +52,6 @@ namespace System.Management.Automation
|
||||
}
|
||||
private Dictionary<ProviderInfo, PSDriveInfo> _providersCurrentWorkingDrive = new Dictionary<ProviderInfo, PSDriveInfo>();
|
||||
|
||||
private bool _providersInitialized = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets called by the RunspaceConfiguration when a PSSnapin gets added or removed.
|
||||
/// </summary>
|
||||
///
|
||||
internal void UpdateProviders()
|
||||
{
|
||||
// This should only be called from Update() on a runspace configuration q.e.d. runspace configuration
|
||||
// should never be null when this gets called...
|
||||
if (this.ExecutionContext.RunspaceConfiguration == null)
|
||||
throw PSTraceSource.NewInvalidOperationException();
|
||||
|
||||
if (this == ExecutionContext.TopLevelSessionState && !_providersInitialized)
|
||||
{
|
||||
foreach (ProviderConfigurationEntry providerConfig in this.ExecutionContext.RunspaceConfiguration.Providers)
|
||||
{
|
||||
AddProvider(providerConfig);
|
||||
}
|
||||
|
||||
_providersInitialized = true;
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (ProviderConfigurationEntry providerConfig in this.ExecutionContext.RunspaceConfiguration.Providers.UpdateList)
|
||||
{
|
||||
switch (providerConfig.Action)
|
||||
{
|
||||
case UpdateAction.Add:
|
||||
AddProvider(providerConfig);
|
||||
break;
|
||||
|
||||
case UpdateAction.Remove:
|
||||
RemoveProvider(providerConfig);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Entrypoint used by to add a provider to the current session state
|
||||
/// based on a SessionStateProviderEntry.
|
||||
@@ -109,20 +67,6 @@ namespace System.Management.Automation
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal method used by RunspaceConfig for updating providers.
|
||||
/// </summary>
|
||||
/// <param name="providerConfig"></param>
|
||||
private ProviderInfo AddProvider(ProviderConfigurationEntry providerConfig)
|
||||
{
|
||||
return AddProvider(providerConfig.ImplementingType,
|
||||
providerConfig.Name,
|
||||
providerConfig.HelpFileName,
|
||||
providerConfig.PSSnapIn,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
private ProviderInfo AddProvider(Type implementingType, string name, string helpFileName, PSSnapInInfo psSnapIn, PSModuleInfo module)
|
||||
{
|
||||
ProviderInfo provider = null;
|
||||
@@ -1028,7 +972,7 @@ namespace System.Management.Automation
|
||||
}
|
||||
}
|
||||
|
||||
if (ExecutionContext.IsSingleShell && !String.IsNullOrEmpty(providerName.PSSnapInName))
|
||||
if (!String.IsNullOrEmpty(providerName.PSSnapInName))
|
||||
{
|
||||
// Be sure the PSSnapin/Module name matches
|
||||
|
||||
@@ -1234,8 +1178,6 @@ namespace System.Management.Automation
|
||||
}
|
||||
} // InitializeProvider
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates and adds a provider to the provider container
|
||||
/// </summary>
|
||||
@@ -1512,51 +1454,6 @@ namespace System.Management.Automation
|
||||
|
||||
#region Remove Provider
|
||||
|
||||
private void RemoveProvider(ProviderConfigurationEntry entry)
|
||||
{
|
||||
try
|
||||
{
|
||||
CmdletProviderContext context = new CmdletProviderContext(this.ExecutionContext);
|
||||
|
||||
string providerName = GetProviderName(entry);
|
||||
RemoveProvider(providerName, true, context);
|
||||
|
||||
context.ThrowFirstErrorOrDoNothing();
|
||||
}
|
||||
catch (LoopFlowException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (PipelineStoppedException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (ActionPreferenceStopException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception e) // Catch-all OK, 3rd party callout
|
||||
{
|
||||
// NTRAID#Windows OS Bugs-1009281-2004/02/11-JeffJon
|
||||
this.ExecutionContext.ReportEngineStartupError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private string GetProviderName(ProviderConfigurationEntry entry)
|
||||
{
|
||||
string name = entry.Name;
|
||||
if (entry.PSSnapIn != null)
|
||||
{
|
||||
name =
|
||||
string.Format(
|
||||
System.Globalization.CultureInfo.InvariantCulture,
|
||||
"{0}\\{1}",
|
||||
entry.PSSnapIn.Name,
|
||||
entry.Name);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the provider of the given name.
|
||||
/// </summary>
|
||||
|
||||
@@ -217,7 +217,6 @@ namespace System.Management.Automation
|
||||
|
||||
#region AllScope variables created in every session
|
||||
|
||||
internal const string ConsoleFileName = "ConsoleFileName";
|
||||
internal const string ExecutionContext = "ExecutionContext";
|
||||
internal const string Home = "HOME";
|
||||
internal const string Host = "Host";
|
||||
@@ -232,7 +231,6 @@ namespace System.Management.Automation
|
||||
|
||||
internal static List<string> AllScopeSessionVariables = new List<string>
|
||||
{
|
||||
ConsoleFileName,
|
||||
ExecutionContext,
|
||||
Home,
|
||||
Host,
|
||||
@@ -297,7 +295,6 @@ namespace System.Management.Automation
|
||||
// also exists.
|
||||
internal static readonly string[] AllScopeVariables = {
|
||||
SpecialVariables.Question,
|
||||
SpecialVariables.ConsoleFileName,
|
||||
SpecialVariables.ExecutionContext,
|
||||
SpecialVariables.False,
|
||||
SpecialVariables.Home,
|
||||
|
||||
@@ -4218,7 +4218,6 @@ namespace System.Management.Automation.Runspaces
|
||||
|
||||
Update(errors, typeData, false);
|
||||
StandardMembersUpdated();
|
||||
|
||||
// Throw exception if there are any errors
|
||||
FormatAndTypeDataHelper.ThrowExceptionOnError("ErrorsUpdatingTypes", errors, RunspaceConfigurationCategory.Types);
|
||||
}
|
||||
@@ -4245,7 +4244,6 @@ namespace System.Management.Automation.Runspaces
|
||||
|
||||
Update(errors, typeData, true);
|
||||
StandardMembersUpdated();
|
||||
|
||||
// Throw exception if there are any errors
|
||||
FormatAndTypeDataHelper.ThrowExceptionOnError("ErrorsUpdatingTypes", errors, RunspaceConfigurationCategory.Types);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace System.Management.Automation.Runspaces
|
||||
#region Exceptions
|
||||
|
||||
/// <summary>
|
||||
/// Exception thrown when state of the runspace is different from
|
||||
/// Exception thrown when state of the runspace is different from
|
||||
/// expected state of runspace.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
@@ -34,10 +34,10 @@ namespace System.Management.Automation.Runspaces
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of InvalidRunspaceStateException with a specified error message.
|
||||
/// Initializes a new instance of InvalidRunspaceStateException with a specified error message.
|
||||
/// </summary>
|
||||
/// <param name="message">
|
||||
/// The message that describes the error.
|
||||
/// The message that describes the error.
|
||||
/// </param>
|
||||
public InvalidRunspaceStateException(string message)
|
||||
: base(message)
|
||||
@@ -45,12 +45,12 @@ namespace System.Management.Automation.Runspaces
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the InvalidRunspaceStateException class
|
||||
/// with a specified error message and a reference to the inner exception
|
||||
/// that is the cause of this exception.
|
||||
/// Initializes a new instance of the InvalidRunspaceStateException class
|
||||
/// with a specified error message and a reference to the inner exception
|
||||
/// that is the cause of this exception.
|
||||
/// </summary>
|
||||
/// <param name="message">
|
||||
/// The message that describes the error.
|
||||
/// The message that describes the error.
|
||||
/// </param>
|
||||
/// <param name="innerException">
|
||||
/// The exception that is the cause of the current exception.
|
||||
@@ -61,7 +61,7 @@ namespace System.Management.Automation.Runspaces
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the InvalidRunspaceStateException
|
||||
/// Initializes a new instance of the InvalidRunspaceStateException
|
||||
/// with a specified error message and current and expected state.
|
||||
/// </summary>
|
||||
/// <param name="message">The message that describes the error. </param>
|
||||
@@ -90,11 +90,11 @@ namespace System.Management.Automation.Runspaces
|
||||
/// class with serialized data.
|
||||
/// </summary>
|
||||
/// <param name="info">
|
||||
/// The <see cref="SerializationInfo"/> that holds the serialized object
|
||||
/// The <see cref="SerializationInfo"/> that holds the serialized object
|
||||
/// data about the exception being thrown.
|
||||
/// </param>
|
||||
/// <param name="context">
|
||||
/// The <see cref="StreamingContext"/> that contains contextual information
|
||||
/// The <see cref="StreamingContext"/> that contains contextual information
|
||||
/// about the source or destination.
|
||||
/// </param>
|
||||
protected InvalidRunspaceStateException(SerializationInfo info, StreamingContext context)
|
||||
@@ -214,13 +214,13 @@ namespace System.Management.Automation.Runspaces
|
||||
UseNewThread = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new thread for the first invocation and then re-uses
|
||||
/// Creates a new thread for the first invocation and then re-uses
|
||||
/// that thread in subsequent invocations.
|
||||
/// </summary>
|
||||
ReuseThread = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Doesn't create a new thread; the execution occurs on the
|
||||
/// Doesn't create a new thread; the execution occurs on the
|
||||
/// thread that calls Invoke.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
@@ -250,7 +250,7 @@ namespace System.Management.Automation.Runspaces
|
||||
/// Constructor for state changes with an optional error
|
||||
/// </summary>
|
||||
/// <param name="state">The state of runspace.</param>
|
||||
/// <param name="reason">A non-null exception if the state change was
|
||||
/// <param name="reason">A non-null exception if the state change was
|
||||
/// caused by an error, otherwise; null.
|
||||
/// </param>
|
||||
internal RunspaceStateInfo(RunspaceState state, Exception reason)
|
||||
@@ -263,7 +263,7 @@ namespace System.Management.Automation.Runspaces
|
||||
/// <summary>
|
||||
/// Copy constructor to support cloning.
|
||||
/// </summary>
|
||||
/// <param name="runspaceStateInfo">The source
|
||||
/// <param name="runspaceStateInfo">The source
|
||||
/// RunspaceStateInfo
|
||||
/// </param>
|
||||
internal RunspaceStateInfo(RunspaceStateInfo runspaceStateInfo)
|
||||
@@ -284,8 +284,8 @@ namespace System.Management.Automation.Runspaces
|
||||
/// The reason for the state change, if caused by an error.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The value of this property is non-null if the state
|
||||
/// changed due to an error. Otherwise, the value of this
|
||||
/// The value of this property is non-null if the state
|
||||
/// changed due to an error. Otherwise, the value of this
|
||||
/// property is null.
|
||||
/// </remarks>
|
||||
public Exception Reason { get; }
|
||||
@@ -326,7 +326,7 @@ namespace System.Management.Automation.Runspaces
|
||||
/// <summary>
|
||||
/// Constructs RunspaceStateEventArgs using RunspaceStateInfo
|
||||
/// </summary>
|
||||
/// <param name="runspaceStateInfo">The information about
|
||||
/// <param name="runspaceStateInfo">The information about
|
||||
/// current state of the runspace.</param>
|
||||
/// <exception cref="ArgumentNullException">runspaceStateInfo is null
|
||||
/// </exception>
|
||||
@@ -347,8 +347,8 @@ namespace System.Management.Automation.Runspaces
|
||||
/// Information about state of the runspace
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This value indicates the state of the runspace after the
|
||||
/// change.
|
||||
/// This value indicates the state of the runspace after the
|
||||
/// change.
|
||||
/// </remarks>
|
||||
public RunspaceStateInfo RunspaceStateInfo { get; }
|
||||
|
||||
@@ -647,19 +647,6 @@ namespace System.Management.Automation.Runspaces
|
||||
protected set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RunspaceConfiguration information for this runspace.
|
||||
/// </summary>
|
||||
#if CORECLR
|
||||
internal
|
||||
#else
|
||||
public
|
||||
#endif
|
||||
abstract RunspaceConfiguration RunspaceConfiguration
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// InitialSessionState information for this runspace.
|
||||
/// </summary>
|
||||
@@ -669,7 +656,7 @@ namespace System.Management.Automation.Runspaces
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get unique id for this instance of runspace. It is primarily used
|
||||
/// Get unique id for this instance of runspace. It is primarily used
|
||||
/// for logging purposes
|
||||
/// </summary>
|
||||
public Guid InstanceId { get;
|
||||
@@ -941,7 +928,7 @@ namespace System.Management.Automation.Runspaces
|
||||
((pipelineState == PipelineState.Stopped) && (this.RunspaceStateInfo.State == RunspaceState.Opened)))
|
||||
&& (remoteCommand != null) && (cmdInstanceId != null) && (remoteCommand.CommandId == cmdInstanceId))
|
||||
{
|
||||
// Completed, Failed, and Stopped with Runspace.Opened states are command finish states and we know
|
||||
// Completed, Failed, and Stopped with Runspace.Opened states are command finish states and we know
|
||||
// that the command is finished on the server.
|
||||
// Setting ConnectCommands to null indicates that the runspace is free to run other
|
||||
// commands.
|
||||
@@ -1255,12 +1242,12 @@ namespace System.Management.Automation.Runspaces
|
||||
/// Disconnects the runspace synchronously.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Disconnects the remote runspace and any running command from the server
|
||||
/// Disconnects the remote runspace and any running command from the server
|
||||
/// machine. Any data generated by the running command on the server is
|
||||
/// cached on the server machine. This runspace object goes to the disconnected
|
||||
/// state. This object can be reconnected to the server by calling the
|
||||
/// state. This object can be reconnected to the server by calling the
|
||||
/// Connect() method.
|
||||
/// If the remote runspace on the server remains disconnected for the IdleTimeout
|
||||
/// If the remote runspace on the server remains disconnected for the IdleTimeout
|
||||
/// value (as defined in the WSManConnectionInfo object) then it is closed and
|
||||
/// torn down on the server.
|
||||
/// </remarks>
|
||||
@@ -1273,12 +1260,12 @@ namespace System.Management.Automation.Runspaces
|
||||
/// Disconnects the runspace asynchronously.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Disconnects the remote runspace and any running command from the server
|
||||
/// Disconnects the remote runspace and any running command from the server
|
||||
/// machine. Any data generated by the running command on the server is
|
||||
/// cached on the server machine. This runspace object goes to the disconnected
|
||||
/// state. This object can be reconnected to the server by calling the
|
||||
/// state. This object can be reconnected to the server by calling the
|
||||
/// Connect() method.
|
||||
/// If the remote runspace on the server remains disconnected for the IdleTimeout
|
||||
/// If the remote runspace on the server remains disconnected for the IdleTimeout
|
||||
/// value (as defined in the WSManConnectionInfo object) then it is closed and
|
||||
/// torn down on the server.
|
||||
/// </remarks>
|
||||
@@ -1316,8 +1303,8 @@ namespace System.Management.Automation.Runspaces
|
||||
public abstract void ConnectAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a PipeLine object in the disconnected state for the currently disconnected
|
||||
/// remote running command associated with this runspace.
|
||||
/// Creates a PipeLine object in the disconnected state for the currently disconnected
|
||||
/// remote running command associated with this runspace.
|
||||
/// </summary>
|
||||
/// <returns>Pipeline object in disconnected state.</returns>
|
||||
public abstract Pipeline CreateDisconnectedPipeline();
|
||||
@@ -1370,7 +1357,7 @@ namespace System.Management.Automation.Runspaces
|
||||
/// Close the runspace Asynchronously.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Attempts to execute pipelines after a call to
|
||||
/// Attempts to execute pipelines after a call to
|
||||
/// close will fail.
|
||||
/// </remarks>
|
||||
/// <exception cref="InvalidRunspaceStateException">
|
||||
@@ -1410,7 +1397,7 @@ namespace System.Management.Automation.Runspaces
|
||||
public abstract Pipeline CreatePipeline(string command, bool addToHistory);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a nested pipeline.
|
||||
/// Creates a nested pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Nested pipelines are needed for nested prompt scenario. Nested
|
||||
@@ -1420,7 +1407,7 @@ namespace System.Management.Automation.Runspaces
|
||||
public abstract Pipeline CreateNestedPipeline();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a nested pipeline.
|
||||
/// Creates a nested pipeline.
|
||||
/// </summary>
|
||||
/// <param name="command">A valid command string</param>
|
||||
/// <param name="addToHistory">if true command is added to history</param>
|
||||
@@ -1438,14 +1425,14 @@ namespace System.Management.Automation.Runspaces
|
||||
internal abstract Pipeline GetCurrentlyRunningPipeline();
|
||||
|
||||
/// <summary>
|
||||
/// Private data to be used by applications built on top of PowerShell.
|
||||
///
|
||||
/// Private data to be used by applications built on top of PowerShell.
|
||||
///
|
||||
/// Local runspace is created with application private data set to an empty <see cref="PSPrimitiveDictionary"/>.
|
||||
///
|
||||
/// Remote runspace gets its application private data from the server (set when creating a remote runspace pool)
|
||||
/// Calling this method on a remote runspace will block until the data is received from the server.
|
||||
///
|
||||
/// Remote runspace gets its application private data from the server (set when creating a remote runspace pool)
|
||||
/// Calling this method on a remote runspace will block until the data is received from the server.
|
||||
/// The server will send application private data before reaching <see cref="RunspacePoolState.Opened"/> state.
|
||||
///
|
||||
///
|
||||
/// Runspaces that are part of a <see cref="RunspacePool"/> inherit application private data from the pool.
|
||||
/// </summary>
|
||||
public abstract PSPrimitiveDictionary GetApplicationPrivateData();
|
||||
@@ -1639,7 +1626,7 @@ namespace System.Management.Automation.Runspaces
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This class provides subset of functionality provided by
|
||||
/// This class provides subset of functionality provided by
|
||||
/// session state.
|
||||
/// </summary>
|
||||
public class SessionStateProxy
|
||||
@@ -1658,23 +1645,23 @@ namespace System.Management.Automation.Runspaces
|
||||
/// <summary>
|
||||
/// Set a variable in session state.
|
||||
/// </summary>
|
||||
///
|
||||
///
|
||||
/// <param name="name">
|
||||
/// The name of the item to set.
|
||||
/// </param>
|
||||
///
|
||||
///
|
||||
/// <param name="value">
|
||||
/// The new value of the item being set.
|
||||
/// </param>
|
||||
///
|
||||
///
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// name is null
|
||||
/// </exception>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidRunspaceStateException">
|
||||
/// Runspace is not open.
|
||||
/// </exception>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Another SessionStateProxy call or another pipeline is in progress.
|
||||
/// </exception>
|
||||
@@ -1688,25 +1675,25 @@ namespace System.Management.Automation.Runspaces
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a variable out of session state.
|
||||
/// Get a variable out of session state.
|
||||
/// </summary>
|
||||
///
|
||||
///
|
||||
/// <param name="name">
|
||||
/// name of variable to look up
|
||||
/// </param>
|
||||
///
|
||||
///
|
||||
/// <returns>
|
||||
/// The value of the specified variable.
|
||||
/// </returns>
|
||||
///
|
||||
///
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// name is null
|
||||
/// </exception>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidRunspaceStateException">
|
||||
/// Runspace is not open.
|
||||
/// </exception>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Another SessionStateProxy call or another pipeline is in progress.
|
||||
/// </exception>
|
||||
@@ -1727,11 +1714,11 @@ namespace System.Management.Automation.Runspaces
|
||||
/// <summary>
|
||||
/// Get the list of applications out of session state.
|
||||
/// </summary>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidRunspaceStateException">
|
||||
/// Runspace is not open.
|
||||
/// </exception>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Another SessionStateProxy call or another pipeline is in progress.
|
||||
/// </exception>
|
||||
@@ -1746,11 +1733,11 @@ namespace System.Management.Automation.Runspaces
|
||||
/// <summary>
|
||||
/// Get the list of scripts out of session state.
|
||||
/// </summary>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidRunspaceStateException">
|
||||
/// Runspace is not open.
|
||||
/// </exception>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Another SessionStateProxy call or another pipeline is in progress.
|
||||
/// </exception>
|
||||
@@ -1765,11 +1752,11 @@ namespace System.Management.Automation.Runspaces
|
||||
/// <summary>
|
||||
/// Get the APIs to access drives out of session state
|
||||
/// </summary>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidRunspaceStateException">
|
||||
/// Runspace is not open.
|
||||
/// </exception>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Another SessionStateProxy call or another pipeline is in progress.
|
||||
/// </exception>
|
||||
@@ -1781,11 +1768,11 @@ namespace System.Management.Automation.Runspaces
|
||||
/// <summary>
|
||||
/// Get/Set the language mode out of session state.
|
||||
/// </summary>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidRunspaceStateException">
|
||||
/// Runspace is not open.
|
||||
/// </exception>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Another SessionStateProxy call or another pipeline is in progress.
|
||||
/// </exception>
|
||||
@@ -1798,11 +1785,11 @@ namespace System.Management.Automation.Runspaces
|
||||
/// <summary>
|
||||
/// Get the module info out of session state.
|
||||
/// </summary>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidRunspaceStateException">
|
||||
/// Runspace is not open.
|
||||
/// </exception>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Another SessionStateProxy call or another pipeline is in progress.
|
||||
/// </exception>
|
||||
@@ -1815,11 +1802,11 @@ namespace System.Management.Automation.Runspaces
|
||||
/// <summary>
|
||||
/// Get the APIs to access paths and locations out of session state.
|
||||
/// </summary>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidRunspaceStateException">
|
||||
/// Runspace is not open.
|
||||
/// </exception>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Another SessionStateProxy call or another pipeline is in progress.
|
||||
/// </exception>
|
||||
@@ -1831,11 +1818,11 @@ namespace System.Management.Automation.Runspaces
|
||||
/// <summary>
|
||||
/// Get the APIs to access a provider out of session state.
|
||||
/// </summary>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidRunspaceStateException">
|
||||
/// Runspace is not open.
|
||||
/// </exception>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Another SessionStateProxy call or another pipeline is in progress.
|
||||
/// </exception>
|
||||
@@ -1847,11 +1834,11 @@ namespace System.Management.Automation.Runspaces
|
||||
/// <summary>
|
||||
/// Get the APIs to access variables out of session state.
|
||||
/// </summary>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidRunspaceStateException">
|
||||
/// Runspace is not open.
|
||||
/// </exception>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Another SessionStateProxy call or another pipeline is in progress.
|
||||
/// </exception>
|
||||
@@ -1863,14 +1850,14 @@ namespace System.Management.Automation.Runspaces
|
||||
/// <summary>
|
||||
/// Get the APIs to build script blocks and execute script out of session state.
|
||||
/// </summary>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidRunspaceStateException">
|
||||
/// Runspace is not open.
|
||||
/// </exception>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Another SessionStateProxy call or another pipeline is in progress.
|
||||
/// </exception>
|
||||
/// </exception>
|
||||
public virtual CommandInvocationIntrinsics InvokeCommand
|
||||
{
|
||||
get { return _runspace.InvokeCommand; }
|
||||
@@ -1879,11 +1866,11 @@ namespace System.Management.Automation.Runspaces
|
||||
/// <summary>
|
||||
/// Gets the instance of the provider interface APIs out of session state.
|
||||
/// </summary>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidRunspaceStateException">
|
||||
/// Runspace is not open.
|
||||
/// </exception>
|
||||
///
|
||||
///
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Another SessionStateProxy call or another pipeline is in progress.
|
||||
/// </exception>
|
||||
|
||||
@@ -37,22 +37,14 @@ namespace System.Management.Automation.Runspaces
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// host is null.
|
||||
/// </exception>
|
||||
/// <param name="runspaceConfiguration">
|
||||
/// configuration information for this minshell.
|
||||
/// </param>
|
||||
protected RunspaceBase(PSHost host, RunspaceConfiguration runspaceConfiguration)
|
||||
protected RunspaceBase(PSHost host)
|
||||
{
|
||||
if (host == null)
|
||||
{
|
||||
throw PSTraceSource.NewArgumentNullException("host");
|
||||
}
|
||||
if (runspaceConfiguration == null)
|
||||
{
|
||||
throw PSTraceSource.NewArgumentNullException("runspaceConfiguration");
|
||||
}
|
||||
|
||||
InitialSessionState = InitialSessionState.CreateDefault();
|
||||
Host = host;
|
||||
RunspaceConfiguration = runspaceConfiguration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -143,17 +135,7 @@ namespace System.Management.Automation.Runspaces
|
||||
protected PSHost Host { get; }
|
||||
|
||||
/// <summary>
|
||||
/// runspaceConfiguration information for this runspace
|
||||
/// </summary>
|
||||
#if CORECLR
|
||||
internal
|
||||
#else
|
||||
public
|
||||
#endif
|
||||
override RunspaceConfiguration RunspaceConfiguration { get; }
|
||||
|
||||
/// <summary>
|
||||
/// runspaceConfiguration information for this runspace
|
||||
/// InitialSessionState information for this runspace
|
||||
/// </summary>
|
||||
public override InitialSessionState InitialSessionState { get; }
|
||||
|
||||
|
||||
@@ -34,8 +34,6 @@ namespace System.Management.Automation.Runspaces
|
||||
|
||||
/// <summary>
|
||||
/// Creates a runspace using host of type <see cref="DefaultHost"/>.
|
||||
/// This runspace is created using the <see cref="RunspaceConfiguration"/> information
|
||||
/// from EntryAssembly.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A runspace object.
|
||||
@@ -67,69 +65,9 @@ namespace System.Management.Automation.Runspaces
|
||||
throw PSTraceSource.NewArgumentNullException("host");
|
||||
}
|
||||
|
||||
return CreateRunspace(host, RunspaceConfiguration.Create());
|
||||
return new LocalRunspace(host, InitialSessionState.CreateDefault());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a runspace using <see cref="DefaultHost"/>
|
||||
/// </summary>
|
||||
/// <param name="runspaceConfiguration">
|
||||
/// RunspaceConfiguration information for the runspace.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A runspace object
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Thrown when runspaceConfiguration is null
|
||||
/// </exception>
|
||||
internal static Runspace CreateRunspace(RunspaceConfiguration runspaceConfiguration)
|
||||
{
|
||||
if (runspaceConfiguration == null)
|
||||
{
|
||||
throw PSTraceSource.NewArgumentNullException("runspaceConfiguration");
|
||||
}
|
||||
|
||||
PSHost host = new DefaultHost(CultureInfo.CurrentCulture, CultureInfo.CurrentUICulture);
|
||||
|
||||
return CreateRunspace(host, runspaceConfiguration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a runspace using specified PSHost and RunspaceConfiguration
|
||||
/// </summary>
|
||||
/// <param name="host">
|
||||
/// Host implementation for runspace.
|
||||
/// </param>
|
||||
/// <param name="runspaceConfiguration">
|
||||
/// RunspaceConfiguration information for the runspace.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A runspace object
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Thrown when host is null
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Thrown when runspaceConfiguration is null
|
||||
/// </exception>
|
||||
internal static Runspace CreateRunspace(PSHost host, RunspaceConfiguration runspaceConfiguration)
|
||||
{
|
||||
if (host == null)
|
||||
{
|
||||
throw PSTraceSource.NewArgumentNullException("host");
|
||||
}
|
||||
|
||||
if (runspaceConfiguration == null)
|
||||
{
|
||||
throw PSTraceSource.NewArgumentNullException("runspaceConfiguration");
|
||||
}
|
||||
|
||||
return new LocalRunspace(host, runspaceConfiguration);
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Create runspaces with InitialSessionState instead of RunspaceConfig objects...
|
||||
|
||||
/// <summary>
|
||||
/// Creates a runspace using <see cref="DefaultHost"/>
|
||||
/// </summary>
|
||||
@@ -228,22 +166,15 @@ namespace System.Management.Automation.Runspaces
|
||||
#region RunspacePool Factory
|
||||
|
||||
/// <summary>
|
||||
/// Creates a RunspacePool using default RunspaceConfiguration
|
||||
/// with MaxRunspaces 1 and MinRunspaces 1.
|
||||
/// Creates a RunspacePool with MaxRunspaces 1 and MinRunspaces 1.
|
||||
/// </summary>
|
||||
public static RunspacePool CreateRunspacePool()
|
||||
{
|
||||
return CreateRunspacePool(1, 1,
|
||||
RunspaceConfiguration.Create(),
|
||||
new DefaultHost
|
||||
(
|
||||
CultureInfo.CurrentCulture,
|
||||
CultureInfo.CurrentUICulture
|
||||
));
|
||||
return CreateRunspacePool(1, 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a RunspacePool using default RunspaceConfiguration.
|
||||
/// Creates a RunspacePool
|
||||
/// <paramref name="maxRunspaces"/>
|
||||
/// limits the number of Runspaces that can exist in this
|
||||
/// pool. The minimum pool size is set to <paramref name="minPoolSoze"/>.
|
||||
@@ -263,7 +194,6 @@ namespace System.Management.Automation.Runspaces
|
||||
public static RunspacePool CreateRunspacePool(int minRunspaces, int maxRunspaces)
|
||||
{
|
||||
return CreateRunspacePool(minRunspaces, maxRunspaces,
|
||||
RunspaceConfiguration.Create(),
|
||||
new DefaultHost
|
||||
(
|
||||
CultureInfo.CurrentCulture,
|
||||
@@ -281,7 +211,7 @@ namespace System.Management.Automation.Runspaces
|
||||
/// Runspace in the pool.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// RunspaceConfiguration is null.
|
||||
/// InitialSessionState is null.
|
||||
/// </exception>
|
||||
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Runspace")]
|
||||
public static RunspacePool CreateRunspacePool(InitialSessionState initialSessionState)
|
||||
@@ -318,44 +248,7 @@ namespace System.Management.Automation.Runspaces
|
||||
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Runspaces")]
|
||||
public static RunspacePool CreateRunspacePool(int minRunspaces, int maxRunspaces, PSHost host)
|
||||
{
|
||||
return CreateRunspacePool(minRunspaces, maxRunspaces, RunspaceConfiguration.Create(), host);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a RunspacePool using the supplied <paramref name="configuration"/>,
|
||||
/// <paramref name="minRunspaces"/> and <paramref name="maxRunspaces"/>
|
||||
/// </summary>
|
||||
/// <param name="minRunspaces">
|
||||
/// The minimum number of Runspaces that can exist in this pool.
|
||||
/// Should be greater than or equal to 1.
|
||||
/// </param>
|
||||
/// <param name="maxRunspaces">
|
||||
/// The maximum number of Runspaces that can exist in this pool.
|
||||
/// Should be greater than or equal to 1.
|
||||
/// </param>
|
||||
/// <param name="runspaceConfiguration">
|
||||
/// RunspaceConfiguration to use when creating a new Runspace in the
|
||||
/// pool.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// RunspaceConfiguration is null.
|
||||
/// </exception>
|
||||
/// <param name="host">
|
||||
/// The explicit PSHost implementation.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="runspaceConfiguration"/> is null.
|
||||
/// <paramref name="host"/> is null.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Maximum runspaces is less than 1.
|
||||
/// Minimum runspaces is less than 1.
|
||||
/// </exception>
|
||||
private static RunspacePool CreateRunspacePool(int minRunspaces, int maxRunspaces,
|
||||
RunspaceConfiguration runspaceConfiguration, PSHost host)
|
||||
{
|
||||
return new RunspacePool(minRunspaces,
|
||||
maxRunspaces, runspaceConfiguration, host);
|
||||
return new RunspacePool(minRunspaces, maxRunspaces, host);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -375,13 +268,13 @@ namespace System.Management.Automation.Runspaces
|
||||
/// pool.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// RunspaceConfiguration is null.
|
||||
/// InitialSessionState is null.
|
||||
/// </exception>
|
||||
/// <param name="host">
|
||||
/// The explicit PSHost implementation.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="runspaceConfiguration"/> is null.
|
||||
/// <paramref name="initialSessionState"/> is null.
|
||||
/// <paramref name="host"/> is null.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
|
||||
@@ -31,22 +31,6 @@ namespace System.Management.Automation.Runspaces
|
||||
{
|
||||
#region constructors
|
||||
|
||||
/// <summary>
|
||||
/// Construct an instance of an Runspace using a custom implementation
|
||||
/// of PSHost.
|
||||
/// </summary>
|
||||
/// <param name="host">
|
||||
/// The explicit PSHost implementation
|
||||
/// </param>
|
||||
/// <param name="runspaceConfig">
|
||||
/// configuration information for this minshell.
|
||||
/// </param>
|
||||
[SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
|
||||
internal LocalRunspace(PSHost host, RunspaceConfiguration runspaceConfig)
|
||||
: base(host, runspaceConfig)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct an instance of an Runspace using a custom implementation
|
||||
/// of PSHost.
|
||||
@@ -641,6 +625,7 @@ namespace System.Management.Automation.Runspaces
|
||||
/// </summary>
|
||||
private void DoOpenHelper()
|
||||
{
|
||||
Dbg.Assert(InitialSessionState != null, "InitialSessionState should not be null");
|
||||
// NTRAID#Windows Out Of Band Releases-915851-2005/09/13
|
||||
if (_disposed)
|
||||
{
|
||||
@@ -653,17 +638,10 @@ namespace System.Management.Automation.Runspaces
|
||||
{
|
||||
_transcriptionData = new TranscriptionData();
|
||||
|
||||
if (InitialSessionState != null)
|
||||
{
|
||||
// All ISS-based configuration of the engine itself is done by AutomationEngine,
|
||||
// which calls InitialSessionState.Bind(). Anything that doesn't
|
||||
// require an active and open runspace should be done in ISS.Bind()
|
||||
_engine = new AutomationEngine(Host, null, InitialSessionState);
|
||||
}
|
||||
else
|
||||
{
|
||||
_engine = new AutomationEngine(Host, RunspaceConfiguration, null);
|
||||
}
|
||||
// All ISS-based configuration of the engine itself is done by AutomationEngine,
|
||||
// which calls InitialSessionState.Bind(). Anything that doesn't
|
||||
// require an active and open runspace should be done in ISS.Bind()
|
||||
_engine = new AutomationEngine(Host, InitialSessionState);
|
||||
_engine.Context.CurrentRunspace = this;
|
||||
|
||||
//Log engine for start of engine life
|
||||
@@ -773,14 +751,7 @@ namespace System.Management.Automation.Runspaces
|
||||
logContext.HostVersion = Host.Version.ToString();
|
||||
logContext.RunspaceId = InstanceId.ToString();
|
||||
logContext.Severity = severity.ToString();
|
||||
if (this.RunspaceConfiguration == null)
|
||||
{
|
||||
logContext.ShellId = Utils.DefaultPowerShellShellID;
|
||||
}
|
||||
else
|
||||
{
|
||||
logContext.ShellId = this.RunspaceConfiguration.ShellId;
|
||||
}
|
||||
logContext.ShellId = Utils.DefaultPowerShellShellID;
|
||||
MshLog.LogEngineHealthEvent(
|
||||
logContext,
|
||||
id,
|
||||
@@ -867,7 +838,7 @@ namespace System.Management.Automation.Runspaces
|
||||
}
|
||||
|
||||
if ((hostRunspace == null) || (this == hostRunspace))
|
||||
{
|
||||
{
|
||||
// We should close transcripting only if we are closing the last opened runspace.
|
||||
foreach (Runspace runspace in RunspaceList)
|
||||
{
|
||||
@@ -883,7 +854,6 @@ namespace System.Management.Automation.Runspaces
|
||||
{
|
||||
host.StopAllTranscribing();
|
||||
}
|
||||
|
||||
AmsiUtils.Uninitialize();
|
||||
}
|
||||
}
|
||||
@@ -929,7 +899,7 @@ namespace System.Management.Automation.Runspaces
|
||||
|
||||
//Log engine lifecycle event.
|
||||
MshLog.LogEngineLifecycleEvent(_engine.Context, EngineState.Stopped);
|
||||
|
||||
|
||||
//All pipelines have been canceled. Close the runspace.
|
||||
_engine = null;
|
||||
_commandFactory = null;
|
||||
|
||||
@@ -31,24 +31,6 @@ namespace System.Management.Automation.Runspaces
|
||||
|
||||
// Add the variables that must always be there...
|
||||
ss.InitializeFixedVariables();
|
||||
|
||||
// If this is being built from a runspace configuration, then
|
||||
// add all of the default entries. When initializing from an InitialSessionState
|
||||
// object, it will contain the defaults if so desired.
|
||||
if (this.RunspaceConfiguration != null)
|
||||
{
|
||||
bool addSetStrictMode = true;
|
||||
foreach (RunspaceConfigurationEntry entry in this.RunspaceConfiguration.Cmdlets)
|
||||
{
|
||||
if (entry.Name.Equals("Set-StrictMode", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
addSetStrictMode = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Add all of the built-in variable, function and alias definitions...
|
||||
ss.AddBuiltInEntries(addSetStrictMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,64 +27,7 @@ namespace System.Management.Automation
|
||||
/// </summary>
|
||||
public RunspaceInvoke()
|
||||
{
|
||||
RunspaceConfiguration rc = RunspaceConfiguration.Create();
|
||||
_runspace = RunspaceFactory.CreateRunspace(rc);
|
||||
_runspace.Open();
|
||||
if (Runspace.DefaultRunspace == null)
|
||||
{
|
||||
Runspace.DefaultRunspace = _runspace;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a RunspaceInvoke for invoking commands. Underlying Runspace is created using
|
||||
/// specified RunspaceConfiguration
|
||||
/// </summary>
|
||||
/// <param name="runspaceConfiguration">RunspaceConfiguration used for creating the runspace
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Thrown when runspaceConfiguration is null
|
||||
/// </exception>
|
||||
public RunspaceInvoke(RunspaceConfiguration runspaceConfiguration)
|
||||
{
|
||||
if (runspaceConfiguration == null)
|
||||
{
|
||||
throw PSTraceSource.NewArgumentNullException("runspaceConfiguration");
|
||||
}
|
||||
_runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
|
||||
_runspace.Open();
|
||||
if (Runspace.DefaultRunspace == null)
|
||||
{
|
||||
Runspace.DefaultRunspace = _runspace;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a RunspaceInvoke for invoking commands. Underlying Runspace is created using the
|
||||
/// specified console file.
|
||||
/// </summary>
|
||||
/// <param name="consoleFilePath">Console file used for creating the underlying
|
||||
/// runspace.</param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Thrown when consoleFilePath is null
|
||||
/// </exception>
|
||||
/// <exception cref="PSConsoleLoadException">
|
||||
/// Thrown when errors occurs in loading one or more PSSnapins.
|
||||
/// </exception>
|
||||
public RunspaceInvoke(string consoleFilePath)
|
||||
{
|
||||
if (consoleFilePath == null)
|
||||
{
|
||||
throw PSTraceSource.NewArgumentNullException("consoleFilePath");
|
||||
}
|
||||
|
||||
PSConsoleLoadException warnings;
|
||||
RunspaceConfiguration rc = RunspaceConfiguration.Create(consoleFilePath, out warnings);
|
||||
if (warnings != null)
|
||||
{
|
||||
throw warnings;
|
||||
}
|
||||
_runspace = RunspaceFactory.CreateRunspace(rc);
|
||||
_runspace = RunspaceFactory.CreateRunspace();
|
||||
_runspace.Open();
|
||||
if (Runspace.DefaultRunspace == null)
|
||||
{
|
||||
|
||||
@@ -528,29 +528,23 @@ namespace System.Management.Automation.Runspaces
|
||||
/// The maximum number of Runspaces that can exist in this pool.
|
||||
/// Should be greater than or equal to 1.
|
||||
/// </param>
|
||||
/// <param name="runspaceConfiguration">
|
||||
/// RunspaceConfiguration to use when creating a new Runspace.
|
||||
/// </param>
|
||||
/// <param name="host">
|
||||
/// The explicit PSHost implementation.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// RunspaceConfiguration is null.
|
||||
/// Host is null.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Maximum runspaces is less than 1.
|
||||
/// Minimum runspaces is less than 1.
|
||||
/// </exception>
|
||||
internal RunspacePool(int minRunspaces, int maxRunspaces,
|
||||
RunspaceConfiguration runspaceConfiguration, PSHost host)
|
||||
internal RunspacePool(int minRunspaces, int maxRunspaces, PSHost host)
|
||||
{
|
||||
// Currently we support only Local Runspace Pool..
|
||||
// this needs to be changed once remote runspace pool
|
||||
// is implemented
|
||||
|
||||
_internalPool = new RunspacePoolInternal(minRunspaces,
|
||||
maxRunspaces, runspaceConfiguration, host);
|
||||
_internalPool = new RunspacePoolInternal(minRunspaces, maxRunspaces, host);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -31,7 +31,6 @@ namespace System.Management.Automation.Runspaces.Internal
|
||||
// pool services on this queue.
|
||||
protected Queue<GetRunspaceAsyncResult> ultimateRequestQueue;
|
||||
protected RunspacePoolStateInfo stateInfo;
|
||||
protected RunspaceConfiguration rsConfig;
|
||||
protected InitialSessionState _initialSessionState;
|
||||
protected PSHost host;
|
||||
protected Guid instanceId;
|
||||
@@ -52,9 +51,6 @@ namespace System.Management.Automation.Runspaces.Internal
|
||||
/// supplied <paramref name="configuration"/>, <paramref name="minRunspaces"/>
|
||||
/// and <paramref name="maxRunspaces"/>
|
||||
/// </summary>
|
||||
/// <param name="runspaceConfiguration">
|
||||
/// RunspaceConfiguration to use when creating a new Runspace.
|
||||
/// </param>
|
||||
/// <param name="maxRunspaces">
|
||||
/// The maximum number of Runspaces that can exist in this pool.
|
||||
/// Should be greater than or equal to 1.
|
||||
@@ -76,25 +72,19 @@ namespace System.Management.Automation.Runspaces.Internal
|
||||
/// </exception>
|
||||
public RunspacePoolInternal(int minRunspaces,
|
||||
int maxRunspaces,
|
||||
RunspaceConfiguration runspaceConfiguration,
|
||||
PSHost host)
|
||||
: this(minRunspaces, maxRunspaces)
|
||||
{
|
||||
if (runspaceConfiguration == null)
|
||||
{
|
||||
throw PSTraceSource.NewArgumentNullException("runspaceConfiguration");
|
||||
}
|
||||
|
||||
if (host == null)
|
||||
{
|
||||
throw PSTraceSource.NewArgumentNullException("host");
|
||||
}
|
||||
|
||||
rsConfig = runspaceConfiguration;
|
||||
this.host = host;
|
||||
pool = new Stack<Runspace>();
|
||||
runspaceRequestQueue = new Queue<GetRunspaceAsyncResult>();
|
||||
ultimateRequestQueue = new Queue<GetRunspaceAsyncResult>();
|
||||
_initialSessionState = InitialSessionState.CreateDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -262,18 +252,6 @@ namespace System.Management.Automation.Runspaces.Internal
|
||||
|
||||
private PSPrimitiveDictionary _applicationPrivateData;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the RunspaceConfiguration object that this pool uses
|
||||
/// to create the runspaces.
|
||||
/// </summary>
|
||||
public RunspaceConfiguration RunspaceConfiguration
|
||||
{
|
||||
get
|
||||
{
|
||||
return rsConfig;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the InitialSessionState object that this pool uses
|
||||
/// to create the runspaces.
|
||||
@@ -1272,21 +1250,10 @@ namespace System.Management.Automation.Runspaces.Internal
|
||||
/// </remarks>
|
||||
protected Runspace CreateRunspace()
|
||||
{
|
||||
Dbg.Assert(null != _initialSessionState, "_initialSessionState should not be null");
|
||||
// TODO: exceptions thrown here need to be documented
|
||||
// runspace.Open() did not document all the exceptions.
|
||||
Runspace result = null;
|
||||
|
||||
// if host is null we are already throwing an
|
||||
// exception, hence a check is not required at this
|
||||
// point
|
||||
if (rsConfig != null)
|
||||
{
|
||||
result = RunspaceFactory.CreateRunspace(host, rsConfig);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = RunspaceFactory.CreateRunspaceFromSessionStateNoClone(host, _initialSessionState);
|
||||
}
|
||||
Runspace result = RunspaceFactory.CreateRunspaceFromSessionStateNoClone(host, _initialSessionState);
|
||||
|
||||
result.ThreadOptions = this.ThreadOptions == PSThreadOptions.Default ? PSThreadOptions.ReuseThread : this.ThreadOptions;
|
||||
#if !CORECLR // No ApartmentState In CoreCLR
|
||||
|
||||
@@ -217,22 +217,6 @@ namespace System.Management.Automation
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// runspaceConfiguration information for this runspace
|
||||
/// </summary>
|
||||
internal override RunspaceConfiguration RunspaceConfiguration
|
||||
{
|
||||
get
|
||||
{
|
||||
#pragma warning disable 56503
|
||||
|
||||
throw PSTraceSource.NewNotImplementedException();
|
||||
|
||||
#pragma warning restore 56503
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// initialsessionstate information for this runspace
|
||||
/// </summary>
|
||||
|
||||
@@ -240,17 +240,6 @@ namespace System.Management.Automation
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function which checks whether PSSnapIns are supported in current invocation.
|
||||
/// </summary>
|
||||
/// <returns>true if supported,false otherwise.</returns>
|
||||
internal bool AreSnapInsSupported()
|
||||
{
|
||||
RunspaceConfigForSingleShell runspace = _helpSystem.ExecutionContext.RunspaceConfiguration as RunspaceConfigForSingleShell;
|
||||
|
||||
return (null == runspace ? false : true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the search paths. If the current shell is single-shell based, then the returned
|
||||
/// search path contains all the directories of currently active PSSnapIns
|
||||
|
||||
@@ -34,10 +34,7 @@ namespace System.Management.Automation
|
||||
/// <returns>The HelpInfo found. Null if nothing is found</returns>
|
||||
internal sealed override IEnumerable<HelpInfo> ExactMatchHelp(HelpRequest helpRequest)
|
||||
{
|
||||
// If the current invocation is a singleshell based
|
||||
// then we have to constantly update the cache as
|
||||
// snapins might get added / removed.
|
||||
if (!this.CacheFullyLoaded || AreSnapInsSupported())
|
||||
if (!this.CacheFullyLoaded)
|
||||
{
|
||||
LoadCache();
|
||||
}
|
||||
@@ -69,10 +66,7 @@ namespace System.Management.Automation
|
||||
/// <returns>a collection of help info objects</returns>
|
||||
internal sealed override IEnumerable<HelpInfo> SearchHelp(HelpRequest helpRequest, bool searchOnlyContent)
|
||||
{
|
||||
// If the current invocation is a singleshell based
|
||||
// then we have to constantly update the cache as
|
||||
// snapins might get added / removed.
|
||||
if (!this.CacheFullyLoaded || AreSnapInsSupported())
|
||||
if (!this.CacheFullyLoaded)
|
||||
{
|
||||
LoadCache();
|
||||
}
|
||||
|
||||
@@ -254,24 +254,6 @@ namespace System.Management.Automation
|
||||
}
|
||||
_searchPaths = new Collection<String>();
|
||||
|
||||
RunspaceConfigForSingleShell runspace = this.ExecutionContext.RunspaceConfiguration as RunspaceConfigForSingleShell;
|
||||
|
||||
if (null != runspace)
|
||||
{
|
||||
// SingleShell case. Check active snapins...
|
||||
MshConsoleInfo currentConsole = runspace.ConsoleInfo;
|
||||
|
||||
if ((null == currentConsole) || (null == currentConsole.ExternalPSSnapIns))
|
||||
{
|
||||
return _searchPaths;
|
||||
}
|
||||
|
||||
foreach (PSSnapInInfo snapin in currentConsole.ExternalPSSnapIns)
|
||||
{
|
||||
_searchPaths.Add(snapin.ApplicationBase);
|
||||
}
|
||||
}
|
||||
|
||||
// add loaded modules paths to the search path
|
||||
if (null != ExecutionContext.Modules)
|
||||
{
|
||||
|
||||
@@ -138,7 +138,7 @@ namespace System.Management.Automation
|
||||
{
|
||||
string fileName = Path.GetFileName(filePath);
|
||||
if (wildcardPattern.IsMatch(fileName))
|
||||
{
|
||||
{
|
||||
result.Add(filePath);
|
||||
}
|
||||
}
|
||||
@@ -335,8 +335,7 @@ namespace System.Management.Automation
|
||||
/// Get the file in different search paths corresponding to current culture.
|
||||
///
|
||||
/// The file name to search is the filename part of path parameter. (Normally path
|
||||
/// parameter should contain only the filename part. But it is possible for
|
||||
/// RunspaceConfiguration to directly specify a hard coded path for help file there).
|
||||
/// parameter should contain only the filename part).
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="file">This is the path to the file. If it has a path, we need to search under that path first</param>
|
||||
|
||||
@@ -1,791 +0,0 @@
|
||||
/********************************************************************++
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
#pragma warning disable 1634, 1691
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Reflection;
|
||||
using System.Security;
|
||||
using System.Management.Automation.Host;
|
||||
using Microsoft.PowerShell.Commands.Internal.Format;
|
||||
|
||||
namespace System.Management.Automation.Runspaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines configuration information for runspace.
|
||||
///
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
///
|
||||
/// Developers may want to derive from this class when writing their own
|
||||
/// host to host monad engine. This will allow host to control the behaviour
|
||||
/// of monad engine through customized runspace configuration.
|
||||
///
|
||||
///
|
||||
/// </remarks>
|
||||
/// <!--
|
||||
/// RunspaceConfiguration class encompass configuration information
|
||||
/// used to tailor the behaviour of mini-shell run time.
|
||||
///
|
||||
/// Information that defines mini-shell run time includes following
|
||||
/// categories:
|
||||
///
|
||||
/// 1. cmdlets: the list of cmdlets that are strong-bond with
|
||||
/// the mini-shell executable.
|
||||
/// 2. providers: the list of providers that are strong-bond with
|
||||
/// the mini-shell executable.
|
||||
/// 3. relationships: the list of relationships that are strong-bond
|
||||
/// with the mini-shell executable.
|
||||
/// 4. types: these are the format.ps1xml which are embedded as resources
|
||||
/// in mini-shell executable.
|
||||
/// 5. formats: these are the display.xml which are embedded as resources
|
||||
/// in mini-shell executable.
|
||||
/// 6. scripts: these are the scripts that are embedded as resources in
|
||||
/// mini-shell executable.
|
||||
/// 7. profile: this is a special kind of script to be executed at monad
|
||||
/// engine start-up.
|
||||
/// 8. help related information: help banner and minishell help. These are
|
||||
/// embedded as a resource in mini-shell.
|
||||
/// 9. assemblies: this is a set of assemblies that will be loaded at
|
||||
/// engine start up time. This will make sure that a set of
|
||||
/// CLR types will be available to monad scripts.
|
||||
/// 10. security manager: this is the security manager to be used for
|
||||
/// enforcing script running, assembly loading policies.
|
||||
///
|
||||
/// Runspace configuration information mentioned above comes into the
|
||||
/// system at different stages,
|
||||
///
|
||||
/// 1. Intrinsic: these are the cmdlets, providers, relationships, types,
|
||||
/// formats which are integrated parts of monad release and present in
|
||||
/// every mini-shell executable. These information come into system at
|
||||
/// design time.
|
||||
///
|
||||
/// 2. BuiltIn: these are the cmdlets, providers, relationships, types, formats,
|
||||
/// scripts, profile, help which are provided when mini-shell executable
|
||||
/// is built when running make-kit. These information come into system at
|
||||
/// compile time.
|
||||
///
|
||||
/// 3. Addon: these are the cmdlets, providers, relationships etc that are added
|
||||
/// and mini-shell run time, either through RunspaceConfigurationModifier
|
||||
/// or directly changing the data in RunspaceConfiguration itself.
|
||||
/// These information come into system at run time.
|
||||
///
|
||||
/// RunspaceConfiguration class is an abstracted class including limited implementation
|
||||
/// on some interfaces related with format, type, script, profile and help.
|
||||
///
|
||||
/// Concrete classes can be derived from this class. In most cases, concrete classes
|
||||
/// are directly generated by makekit with implementation of cmdlets, providers etc filled
|
||||
/// in.
|
||||
///
|
||||
/// Implementation of RunspaceConfiguration focus on following apects,
|
||||
///
|
||||
/// 1. RunspaceConfiguration Information: these are instance-based interfaces to
|
||||
/// to return information from different configuration categories mentioned above.
|
||||
/// 2. RunspaceConfiguration Factories: these are static interfaces for creating
|
||||
/// one instance of RunspaceConfiguration-derived class. Implementation of these
|
||||
/// functions normally has some logic about,
|
||||
///
|
||||
/// a. finding appropriate RunspaceConfiguration class from which to create
|
||||
/// an instance.
|
||||
/// b. call RunspaceConfigurationModifier when necessary.
|
||||
/// c. some caching capability.
|
||||
///
|
||||
/// This class will be built with monad engine code. Following monad engine components
|
||||
/// will likely use this class,
|
||||
///
|
||||
/// 1. Monad host will use configuration information like help banner and shell help.
|
||||
/// 2. Runspace api will use a RunspaceConfiguration instance and store it as
|
||||
/// a member of execution context for use by command discovery, ETS, Format/Output
|
||||
/// 3. Engine start up will use information in profile and scripts.
|
||||
/// 4. Command Discovery will use cmdlet and provider information.
|
||||
/// 5. ETS will use assembly list for finding types accessible to monad scripts.
|
||||
/// 6. ETS will use type information.
|
||||
/// 7. Format and output will use format information.
|
||||
/// -->
|
||||
internal abstract class RunspaceConfiguration
|
||||
{
|
||||
#region RunspaceConfiguration Factory
|
||||
|
||||
/// <summary>
|
||||
/// Create an instance of RunspaceConfiguration type implemented from an assembly.
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">Assembly name from which to find runspace configuration implementation</param>
|
||||
/// <returns>Runspace configuration instance created</returns>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// Exception thrown when <paramref name="assemblyName"/> is null or empty.
|
||||
/// </exception>
|
||||
/// <!--
|
||||
/// This is a RunspaceConfiguration factory function which will create an instance
|
||||
/// of default RunspaceConfiguration-derived type, whose name is decided by an
|
||||
/// assembly attribute in the assembly specified.
|
||||
/// -->
|
||||
public static RunspaceConfiguration Create(string assemblyName)
|
||||
{
|
||||
if (String.IsNullOrEmpty(assemblyName))
|
||||
{
|
||||
throw PSTraceSource.NewArgumentNullException("assemblyName");
|
||||
}
|
||||
|
||||
// If this assembly can't be loaded, Assembly.Load will throw an exception.
|
||||
// Just let the exception bubble up.
|
||||
|
||||
Assembly assembly = null;
|
||||
foreach (Assembly asm in ClrFacade.GetAssemblies())
|
||||
{
|
||||
if (string.Equals(asm.GetName().Name, assemblyName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
assembly = asm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (assembly == null)
|
||||
{
|
||||
assembly = Assembly.Load(new AssemblyName(assemblyName));
|
||||
}
|
||||
|
||||
return Create(assembly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create one single shell runspace configuration object from console file
|
||||
/// </summary>
|
||||
/// <param name="consoleFilePath"></param>
|
||||
/// <param name="warnings"></param>
|
||||
/// <returns></returns>
|
||||
public static RunspaceConfiguration Create(string consoleFilePath, out PSConsoleLoadException warnings)
|
||||
{
|
||||
return RunspaceConfigForSingleShell.Create(consoleFilePath, out warnings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create one single shell runspace configuration object for a msh version.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static RunspaceConfiguration Create()
|
||||
{
|
||||
return RunspaceConfigForSingleShell.CreateDefaultConfiguration();
|
||||
}
|
||||
|
||||
#if V2
|
||||
/// <summary>
|
||||
/// This is a RunspaceConfiguration factory function which will create an instance
|
||||
/// based on a type specified in a particular assembly.
|
||||
///
|
||||
/// This function will likely being exposed as a public interface in v2.
|
||||
/// </summary>
|
||||
/// <param name="assemblyName"></param>
|
||||
/// <param name="runspaceConfigTypeName"></param>
|
||||
/// <returns></returns>
|
||||
private static RunspaceConfiguration Create(string assemblyName, string runspaceConfigTypeName)
|
||||
{
|
||||
// If this assembly can't be loaded, Assembly.Load will throw an exception.
|
||||
// Just let the exception bubble up.
|
||||
Assembly assembly = Assembly.Load(assemblyName);
|
||||
|
||||
try
|
||||
{
|
||||
Type runspaceConfigType = assembly.GetType(runspaceConfigTypeName, true);
|
||||
return Create(runspaceConfigType);
|
||||
}
|
||||
catch (SecurityException)
|
||||
{
|
||||
throw new RunspaceConfigurationTypeException(assembly.FullName, runspaceConfigTypeName);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Create an RunspaceConfiguration-derived instance based an RunspaceConfiguration-derived type
|
||||
/// in specified assembly. The type name is defined by assembly attribute:
|
||||
/// RunspaceConfigurationTypeAttribute.
|
||||
/// </summary>
|
||||
/// <param name="assembly"></param>
|
||||
/// <returns>Runspace configuration instance created</returns>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// Exception thrown when <paramref name="assembly"/> is null or empty.
|
||||
/// </exception>
|
||||
private static RunspaceConfiguration Create(Assembly assembly)
|
||||
{
|
||||
if (assembly == null)
|
||||
throw PSTraceSource.NewArgumentNullException("assembly");
|
||||
|
||||
object[] attributes = assembly.GetCustomAttributes(typeof(RunspaceConfigurationTypeAttribute), false);
|
||||
|
||||
if (attributes == null || attributes.Length == 0)
|
||||
{
|
||||
throw new RunspaceConfigurationAttributeException("RunspaceConfigurationAttributeNotExist", assembly.FullName);
|
||||
}
|
||||
|
||||
if (attributes.Length > 1)
|
||||
{
|
||||
throw new RunspaceConfigurationAttributeException("RunspaceConfigurationAttributeDuplicate", assembly.FullName);
|
||||
}
|
||||
|
||||
RunspaceConfigurationTypeAttribute runspaceConfigTypeAttribute = (RunspaceConfigurationTypeAttribute)attributes[0];
|
||||
|
||||
try
|
||||
{
|
||||
Type runspaceConfigType = assembly.GetType(runspaceConfigTypeAttribute.RunspaceConfigurationType, true, false);
|
||||
return Create(runspaceConfigType);
|
||||
}
|
||||
catch (SecurityException)
|
||||
{
|
||||
throw new RunspaceConfigurationTypeException(assembly.FullName, runspaceConfigTypeAttribute.RunspaceConfigurationType);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create RunspaceConfiguration-derived instance based on a derived type.
|
||||
/// </summary>
|
||||
/// <param name="runspaceConfigType">A type that is derived from RunspaceConfiguration</param>
|
||||
/// <returns></returns>
|
||||
private static RunspaceConfiguration Create(Type runspaceConfigType)
|
||||
{
|
||||
MethodInfo method =
|
||||
runspaceConfigType.GetMethod("Create", BindingFlags.Public | BindingFlags.Static);
|
||||
|
||||
if (method == null)
|
||||
return null;
|
||||
|
||||
return (RunspaceConfiguration)method.Invoke(null, null);
|
||||
}
|
||||
|
||||
#endregion RunspaceConfiguration Factory
|
||||
|
||||
#region Shell Id
|
||||
|
||||
/// <summary>
|
||||
/// Gets the shell id for current runspace configuration.
|
||||
/// </summary>
|
||||
public abstract string ShellId
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PSSnapin Api's
|
||||
|
||||
/// <summary>
|
||||
/// Add a PSSnapin to runspace configuration.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This member provides logic for adding PSSnapin.
|
||||
///
|
||||
/// RunspaceConfiguration derived class should not override this member.
|
||||
///
|
||||
/// </remarks>
|
||||
/// <param name="name">name of the PSSnapin</param>
|
||||
/// <param name="warning">warning message</param>
|
||||
/// <returns></returns>
|
||||
public PSSnapInInfo AddPSSnapIn(string name, out PSSnapInException warning)
|
||||
{
|
||||
return DoAddPSSnapIn(name, out warning);
|
||||
}
|
||||
|
||||
internal virtual PSSnapInInfo DoAddPSSnapIn(string name, out PSSnapInException warning)
|
||||
{
|
||||
throw PSTraceSource.NewNotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove a PSSnapin from runspace configuration.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This member provides logic for removing PSSnapin.
|
||||
///
|
||||
/// RunspaceConfiguration derived class should not override this member.
|
||||
/// </remarks>
|
||||
/// <param name="name">name of the PSSnapin</param>
|
||||
/// <param name="warning">warning message</param>
|
||||
/// <returns></returns>
|
||||
public PSSnapInInfo RemovePSSnapIn(string name, out PSSnapInException warning)
|
||||
{
|
||||
return DoRemovePSSnapIn(name, out warning);
|
||||
}
|
||||
|
||||
internal virtual PSSnapInInfo DoRemovePSSnapIn(string name, out PSSnapInException warning)
|
||||
{
|
||||
throw PSTraceSource.NewNotSupportedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Cmdlet, Provider, Relationship
|
||||
|
||||
private RunspaceConfigurationEntryCollection<CmdletConfigurationEntry> _cmdlets;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cmdlets defined in runspace configuration.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// RunspaceConfiguration derived class can override this member to provide its own cmdlet list.
|
||||
/// </remarks>
|
||||
public virtual RunspaceConfigurationEntryCollection<CmdletConfigurationEntry> Cmdlets
|
||||
{
|
||||
get {
|
||||
return _cmdlets ?? (_cmdlets = new RunspaceConfigurationEntryCollection<CmdletConfigurationEntry>());
|
||||
}
|
||||
}
|
||||
|
||||
private RunspaceConfigurationEntryCollection<ProviderConfigurationEntry> _providers;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the providers defined in runspace configuration.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// RunspaceConfiguration derived class can override this member to provide its own provider list.
|
||||
/// </remarks>
|
||||
public virtual RunspaceConfigurationEntryCollection<ProviderConfigurationEntry> Providers
|
||||
{
|
||||
get {
|
||||
return _providers ??
|
||||
(_providers = new RunspaceConfigurationEntryCollection<ProviderConfigurationEntry>());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// Gets the relationships defined in runspace configuration.
|
||||
/// </summary>
|
||||
public virtual Collection<RelationshipConfigurationEntry> RelationshipData
|
||||
{
|
||||
get;
|
||||
}
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Types and Formats
|
||||
|
||||
/// <summary>
|
||||
/// types.ps1xml information
|
||||
/// </summary>
|
||||
///
|
||||
internal TypeTable TypeTable
|
||||
{
|
||||
get { return _typeTable ?? (_typeTable = new TypeTable()); }
|
||||
}
|
||||
private TypeTable _typeTable;
|
||||
|
||||
private RunspaceConfigurationEntryCollection<TypeConfigurationEntry> _types;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type data files defined in runspace configuration.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// RunspaceConfiguration derived class can override this member to provide its own types to be
|
||||
/// loaded at engine start up.
|
||||
/// </remarks>
|
||||
public virtual RunspaceConfigurationEntryCollection<TypeConfigurationEntry> Types
|
||||
{
|
||||
get { return _types ?? (_types = new RunspaceConfigurationEntryCollection<TypeConfigurationEntry>()); }
|
||||
}
|
||||
|
||||
private RunspaceConfigurationEntryCollection<FormatConfigurationEntry> _formats;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the format data files defined in runspace configuration.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// RunspaceConfiguration derived class can override this member to provide its own formats to be
|
||||
/// loaded at engine start up.
|
||||
/// </remarks>
|
||||
public virtual RunspaceConfigurationEntryCollection<FormatConfigurationEntry> Formats
|
||||
{
|
||||
get {
|
||||
return _formats ?? (_formats = new RunspaceConfigurationEntryCollection<FormatConfigurationEntry>());
|
||||
}
|
||||
}
|
||||
|
||||
internal TypeInfoDataBaseManager FormatDBManager { get; } = new TypeInfoDataBaseManager();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Script Data
|
||||
|
||||
private RunspaceConfigurationEntryCollection<ScriptConfigurationEntry> _scripts;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scripts defined in runspace configuration.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// RunspaceConfiguration derived class can override this member to provide its own scripts
|
||||
/// to be include in monad engine.
|
||||
/// </remarks>
|
||||
public virtual RunspaceConfigurationEntryCollection<ScriptConfigurationEntry> Scripts
|
||||
{
|
||||
get {
|
||||
return _scripts ?? (_scripts = new RunspaceConfigurationEntryCollection<ScriptConfigurationEntry>());
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Profile configuration
|
||||
|
||||
private RunspaceConfigurationEntryCollection<ScriptConfigurationEntry> _initializationScripts;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the initialization scripts defined in runspace configuration.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// RunspaceConfiguration derived class can override this member to provide its own initialization scripts
|
||||
/// to be run at the start up of monad engine.
|
||||
/// </remarks>
|
||||
public virtual RunspaceConfigurationEntryCollection<ScriptConfigurationEntry> InitializationScripts
|
||||
{
|
||||
get {
|
||||
return _initializationScripts ??
|
||||
(_initializationScripts = new RunspaceConfigurationEntryCollection<ScriptConfigurationEntry>());
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Assemblies
|
||||
|
||||
private RunspaceConfigurationEntryCollection<AssemblyConfigurationEntry> _assemblies;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the assemblies defined in runspace configuration.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// RunspaceConfiguration derived class can override this member to provide its own assemblies
|
||||
/// to be loaded at the start up of monad engine.
|
||||
/// </remarks>
|
||||
public virtual RunspaceConfigurationEntryCollection<AssemblyConfigurationEntry> Assemblies
|
||||
{
|
||||
get {
|
||||
return _assemblies ??
|
||||
(_assemblies = new RunspaceConfigurationEntryCollection<AssemblyConfigurationEntry>());
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Security Manager
|
||||
|
||||
private AuthorizationManager _authorizationManager = null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the authorization manager to be used for runspace.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// RunspaceConfiguration derived class can override this member to provide its own authorization
|
||||
/// manager for monad engine.
|
||||
/// </remarks>
|
||||
public virtual AuthorizationManager AuthorizationManager
|
||||
{
|
||||
get {
|
||||
return _authorizationManager ??
|
||||
(_authorizationManager = new Microsoft.PowerShell.PSAuthorizationManager(this.ShellId));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Configuration Update
|
||||
|
||||
private PSHost _host = null;
|
||||
internal void Bind(ExecutionContext executionContext)
|
||||
{
|
||||
_host = executionContext.EngineHostInterface;
|
||||
|
||||
Initialize(executionContext);
|
||||
|
||||
this.Assemblies.OnUpdate += executionContext.UpdateAssemblyCache;
|
||||
|
||||
s_runspaceInitTracer.WriteLine("initializing assembly list");
|
||||
try
|
||||
{
|
||||
this.Assemblies.Update(true);
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
s_runspaceInitTracer.WriteLine("assembly list initialization failed");
|
||||
MshLog.LogEngineHealthEvent(
|
||||
executionContext,
|
||||
MshLog.EVENT_ID_CONFIGURATION_FAILURE,
|
||||
e,
|
||||
Severity.Error);
|
||||
executionContext.ReportEngineStartupError(e.Message);
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
if (executionContext.CommandDiscovery != null)
|
||||
{
|
||||
this.Cmdlets.OnUpdate += executionContext.CommandDiscovery.UpdateCmdletCache;
|
||||
|
||||
// Force an update here so that cmdlet cache is updated in engine.
|
||||
s_runspaceInitTracer.WriteLine("initializing cmdlet list");
|
||||
try
|
||||
{
|
||||
this.Cmdlets.Update(true);
|
||||
}
|
||||
catch (PSNotSupportedException e)
|
||||
{
|
||||
s_runspaceInitTracer.WriteLine("cmdlet list initialization failed");
|
||||
MshLog.LogEngineHealthEvent(
|
||||
executionContext,
|
||||
MshLog.EVENT_ID_CONFIGURATION_FAILURE,
|
||||
e,
|
||||
Severity.Error);
|
||||
executionContext.ReportEngineStartupError(e.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
if (executionContext.EngineSessionState != null)
|
||||
{
|
||||
this.Providers.OnUpdate += executionContext.EngineSessionState.UpdateProviders;
|
||||
|
||||
// Force an update here so that provider cache is updated in engine.
|
||||
s_runspaceInitTracer.WriteLine("initializing provider list");
|
||||
try
|
||||
{
|
||||
this.Providers.Update(true);
|
||||
}
|
||||
catch (PSNotSupportedException e)
|
||||
{
|
||||
s_runspaceInitTracer.WriteLine("provider list initialization failed");
|
||||
MshLog.LogEngineHealthEvent(
|
||||
executionContext,
|
||||
MshLog.EVENT_ID_CONFIGURATION_FAILURE,
|
||||
e,
|
||||
Severity.Error);
|
||||
executionContext.ReportEngineStartupError(e.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void Unbind(ExecutionContext executionContext)
|
||||
{
|
||||
if (executionContext == null)
|
||||
return;
|
||||
|
||||
if (executionContext.CommandDiscovery != null)
|
||||
{
|
||||
this.Cmdlets.OnUpdate -= executionContext.CommandDiscovery.UpdateCmdletCache;
|
||||
}
|
||||
|
||||
if (executionContext.EngineSessionState != null)
|
||||
{
|
||||
this.Providers.OnUpdate -= executionContext.EngineSessionState.UpdateProviders;
|
||||
}
|
||||
|
||||
this.Assemblies.OnUpdate -= executionContext.UpdateAssemblyCache;
|
||||
}
|
||||
|
||||
private bool _initialized = false;
|
||||
private Object _syncObject = new Object();
|
||||
internal void Initialize(ExecutionContext executionContext)
|
||||
{
|
||||
#pragma warning disable 56517
|
||||
|
||||
lock (_syncObject)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
_initialized = true;
|
||||
|
||||
this.Types.OnUpdate += this.UpdateTypes;
|
||||
this.Formats.OnUpdate += this.UpdateFormats;
|
||||
|
||||
s_runspaceInitTracer.WriteLine("initializing types information");
|
||||
try
|
||||
{
|
||||
this.UpdateTypes();
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
s_runspaceInitTracer.WriteLine("type information initialization failed");
|
||||
MshLog.LogEngineHealthEvent(
|
||||
executionContext,
|
||||
MshLog.EVENT_ID_CONFIGURATION_FAILURE,
|
||||
e,
|
||||
Severity.Warning);
|
||||
executionContext.ReportEngineStartupError(e.Message);
|
||||
}
|
||||
|
||||
s_runspaceInitTracer.WriteLine("initializing format information");
|
||||
try
|
||||
{
|
||||
this.UpdateFormats(true);
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
s_runspaceInitTracer.WriteLine("format information initialization failed");
|
||||
MshLog.LogEngineHealthEvent(
|
||||
executionContext,
|
||||
MshLog.EVENT_ID_CONFIGURATION_FAILURE,
|
||||
e,
|
||||
Severity.Warning);
|
||||
executionContext.ReportEngineStartupError(e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore 56517
|
||||
}
|
||||
|
||||
internal void UpdateTypes()
|
||||
{
|
||||
Collection<string> independentErrors = new Collection<string>();
|
||||
Collection<int> entryIndicesToRemove = new Collection<int>();
|
||||
Collection<PSSnapInTypeAndFormatErrors> PSSnapinFiles = FormatAndTypeDataHelper.GetFormatAndTypesErrors(
|
||||
this,
|
||||
_host,
|
||||
this.Types,
|
||||
independentErrors,
|
||||
entryIndicesToRemove);
|
||||
|
||||
if (entryIndicesToRemove.Count > 0)
|
||||
{
|
||||
RemoveNeedlessEntries(RunspaceConfigurationCategory.Types, entryIndicesToRemove);
|
||||
}
|
||||
|
||||
this.TypeTable.Update(PSSnapinFiles, _authorizationManager, _host);
|
||||
FormatAndTypeDataHelper.ThrowExceptionOnError(
|
||||
"ErrorsUpdatingTypes",
|
||||
independentErrors,
|
||||
PSSnapinFiles,
|
||||
RunspaceConfigurationCategory.Types);
|
||||
}
|
||||
|
||||
internal void UpdateFormats()
|
||||
{
|
||||
UpdateFormats(false);
|
||||
}
|
||||
|
||||
private void UpdateFormats(bool preValidated)
|
||||
{
|
||||
Collection<string> independentErrors = new Collection<string>();
|
||||
Collection<int> entryIndicesToRemove = new Collection<int>();
|
||||
Collection<PSSnapInTypeAndFormatErrors> PSSnapinFiles = FormatAndTypeDataHelper.GetFormatAndTypesErrors(
|
||||
this,
|
||||
_host,
|
||||
this.Formats,
|
||||
independentErrors,
|
||||
entryIndicesToRemove);
|
||||
|
||||
if (entryIndicesToRemove.Count > 0)
|
||||
{
|
||||
RemoveNeedlessEntries(RunspaceConfigurationCategory.Formats, entryIndicesToRemove);
|
||||
}
|
||||
|
||||
this.FormatDBManager.UpdateDataBase(PSSnapinFiles, this.AuthorizationManager, _host, preValidated);
|
||||
FormatAndTypeDataHelper.ThrowExceptionOnError(
|
||||
"ErrorsUpdatingFormats",
|
||||
independentErrors,
|
||||
PSSnapinFiles,
|
||||
RunspaceConfigurationCategory.Formats);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove duplicate entries and entries with files that cannot be loaded from the Types and Formats
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
/// <param name="entryIndicesToRemove"></param>
|
||||
private void RemoveNeedlessEntries(RunspaceConfigurationCategory category, IList<int> entryIndicesToRemove)
|
||||
{
|
||||
for (int i = entryIndicesToRemove.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (category == RunspaceConfigurationCategory.Types)
|
||||
{
|
||||
this.Types.RemoveItem(entryIndicesToRemove[i]);
|
||||
}
|
||||
else if (category == RunspaceConfigurationCategory.Formats)
|
||||
{
|
||||
this.Formats.RemoveItem(entryIndicesToRemove[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
[TraceSource("RunspaceInit", "Initialization code for Runspace")]
|
||||
private static PSTraceSource s_runspaceInitTracer = PSTraceSource.GetTracer("RunspaceInit", "Initialization code for Runspace", false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enum for describing different kind information that can be configured in runspace configuration.
|
||||
/// </summary>
|
||||
///
|
||||
/// <!--
|
||||
/// This is used in RunspaceConfiguration.Update()
|
||||
/// -->
|
||||
internal enum RunspaceConfigurationCategory
|
||||
{
|
||||
/// <summary>
|
||||
/// Cmdlets
|
||||
/// </summary>
|
||||
Cmdlets,
|
||||
|
||||
/// <summary>
|
||||
/// Providers
|
||||
/// </summary>
|
||||
Providers,
|
||||
|
||||
/// <summary>
|
||||
/// Assemblies
|
||||
/// </summary>
|
||||
Assemblies,
|
||||
|
||||
/// <summary>
|
||||
/// Scripts
|
||||
/// </summary>
|
||||
Scripts,
|
||||
|
||||
/// <summary>
|
||||
/// Initialization scripts
|
||||
/// </summary>
|
||||
InitializationScripts,
|
||||
|
||||
/// <summary>
|
||||
/// Types
|
||||
/// </summary>
|
||||
Types,
|
||||
|
||||
/// <summary>
|
||||
/// Formats
|
||||
/// </summary>
|
||||
Formats,
|
||||
}
|
||||
|
||||
#if V2
|
||||
|
||||
/// <summary>
|
||||
/// Defines enum for runspace constraints
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum RunspaceConstraints
|
||||
{
|
||||
/// <summary>
|
||||
/// No constraint.
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// Allow console applications.
|
||||
/// </summary>
|
||||
AllowConsoleApplication,
|
||||
|
||||
/// <summary>
|
||||
/// Allow user interaction.
|
||||
/// </summary>
|
||||
AllowUserInteraction,
|
||||
|
||||
/// <summary>
|
||||
/// For GUI cases.
|
||||
/// </summary>
|
||||
AllowGUIDesktop
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
-194
@@ -1,194 +0,0 @@
|
||||
/********************************************************************++
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
using System.Runtime.Serialization;
|
||||
using System.Reflection;
|
||||
using System.Security.Permissions;
|
||||
|
||||
namespace System.Management.Automation.Runspaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines exception thrown when runspace configuration attribute is not defined correctly.
|
||||
/// </summary>
|
||||
/// <!--
|
||||
/// RunspaceConfigurationAttributeException is either
|
||||
///
|
||||
/// 1. no assembly attribute of type RunspaceConfigurationTypeAttribute defined
|
||||
/// 2. or multiple assembly attributes of type RunspaceConfigurationTypeAttribute defined
|
||||
///
|
||||
/// Implementation of RunspaceConfigurationAttributeException requires it to
|
||||
/// 1. Implement IContainsErrorRecord,
|
||||
/// 2. ISerializable
|
||||
/// -->
|
||||
[Serializable]
|
||||
public class RunspaceConfigurationAttributeException : SystemException, IContainsErrorRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// Initiate an instance of RunspaceConfigurationAttributeException.
|
||||
/// </summary>
|
||||
/// <param name="error">Error detail for the exception</param>
|
||||
/// <param name="assemblyName">Assembly on which runspace configuration attribute is defined or should be defined.</param>
|
||||
internal RunspaceConfigurationAttributeException(string error, string assemblyName) : base()
|
||||
{
|
||||
_error = error;
|
||||
_assemblyName = assemblyName;
|
||||
CreateErrorRecord();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initiate an instance of RunspaceConfigurationAttributeException.
|
||||
/// </summary>
|
||||
public RunspaceConfigurationAttributeException() : base()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initiate an instance of RunspaceConfigurationAttributeException.
|
||||
/// </summary>
|
||||
/// <param name="message">Error message</param>
|
||||
public RunspaceConfigurationAttributeException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initiate an instance of RunspaceConfigurationAttributeException.
|
||||
/// </summary>
|
||||
/// <param name="message">Error message</param>
|
||||
/// <param name="innerException">Inner exception</param>
|
||||
public RunspaceConfigurationAttributeException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initiate an instance of RunspaceConfigurationAttributeException.
|
||||
/// </summary>
|
||||
/// <param name="error">Error detail</param>
|
||||
/// <param name="assemblyName">Assembly on which runspace configuration attribute is defined or should be defined.</param>
|
||||
/// <param name="innerException">The inner exception of this exception</param>
|
||||
internal RunspaceConfigurationAttributeException(string error, string assemblyName, Exception innerException) : base(innerException.Message, innerException)
|
||||
{
|
||||
_error = error;
|
||||
_assemblyName = assemblyName;
|
||||
CreateErrorRecord();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the internal error record based on helpTopic.
|
||||
/// The ErrorRecord created will be stored in the _errorRecord member.
|
||||
/// </summary>
|
||||
private void CreateErrorRecord()
|
||||
{
|
||||
// if _error is empty, this exception is created using default
|
||||
// constructor. Don't create the error record since there is
|
||||
// no useful information anyway.
|
||||
if (!String.IsNullOrEmpty(_error) && !String.IsNullOrEmpty(_assemblyName))
|
||||
{
|
||||
_errorRecord = new ErrorRecord(new ParentContainsErrorRecordException(this), _error, ErrorCategory.ResourceUnavailable, null);
|
||||
_errorRecord.ErrorDetails = new ErrorDetails(typeof(RunspaceConfigurationAttributeException).GetTypeInfo().Assembly, "MiniShellErrors", _error, _assemblyName);
|
||||
}
|
||||
}
|
||||
|
||||
private ErrorRecord _errorRecord;
|
||||
|
||||
/// <summary>
|
||||
/// Gets error record embedded in this exception.
|
||||
/// </summary>
|
||||
/// <!--
|
||||
/// This property is required as part of IErrorRecordContainer
|
||||
/// interface.
|
||||
/// -->
|
||||
public ErrorRecord ErrorRecord
|
||||
{
|
||||
get
|
||||
{
|
||||
return _errorRecord;
|
||||
}
|
||||
}
|
||||
|
||||
private string _error = "";
|
||||
|
||||
/// <summary>
|
||||
/// Get localized error message.
|
||||
/// </summary>
|
||||
/// <value>error</value>
|
||||
public string Error
|
||||
{
|
||||
get
|
||||
{
|
||||
return _error;
|
||||
}
|
||||
}
|
||||
|
||||
private string _assemblyName = "";
|
||||
|
||||
/// <summary>
|
||||
/// Gets assembly name on which runspace configuration attribute is defined or should be defined.
|
||||
/// </summary>
|
||||
/// <value>error</value>
|
||||
public string AssemblyName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _assemblyName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets message for this exception.
|
||||
/// </summary>
|
||||
public override string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_errorRecord != null)
|
||||
{
|
||||
return _errorRecord.ToString();
|
||||
}
|
||||
|
||||
return base.Message;
|
||||
}
|
||||
}
|
||||
|
||||
#region Serialization
|
||||
|
||||
/// <summary>
|
||||
/// Initiate a RunspaceConfigurationAttributeException instance.
|
||||
/// </summary>
|
||||
/// <param name="info"> Serialization information </param>
|
||||
/// <param name="context"> Streaming context </param>
|
||||
protected RunspaceConfigurationAttributeException(SerializationInfo info,
|
||||
StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
_error = info.GetString("Error");
|
||||
_assemblyName = info.GetString("AssemblyName");
|
||||
|
||||
CreateErrorRecord();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get object data from serialization information.
|
||||
/// </summary>
|
||||
/// <param name="info"> Serialization information </param>
|
||||
/// <param name="context"> Streaming context </param>
|
||||
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
if (info == null)
|
||||
{
|
||||
throw PSTraceSource.NewArgumentNullException("info");
|
||||
}
|
||||
|
||||
base.GetObjectData(info, context);
|
||||
|
||||
info.AddValue("Error", _error);
|
||||
info.AddValue("AssemblyName", _assemblyName);
|
||||
}
|
||||
|
||||
#endregion Serialization
|
||||
}
|
||||
}
|
||||
|
||||
-434
@@ -1,434 +0,0 @@
|
||||
/********************************************************************++
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
#pragma warning disable 1634, 1691
|
||||
#pragma warning disable 56517
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using Dbg = System.Management.Automation.Diagnostics;
|
||||
|
||||
namespace System.Management.Automation.Runspaces
|
||||
{
|
||||
internal delegate void RunspaceConfigurationEntryUpdateEventHandler();
|
||||
|
||||
/// <summary>
|
||||
/// Define class for runspace configuration entry collection.
|
||||
/// </summary>
|
||||
/// <!--
|
||||
/// Runspace configuration entry collection is used for handling following
|
||||
/// problems for runspace configuration entries.
|
||||
///
|
||||
/// 1. synchronization. Since multiple runspaces may be sharing the same
|
||||
/// runspace configuration, it is essential all the entry collections
|
||||
/// (cmdlets, providers, assemblies, types, formats) are thread-safe.
|
||||
/// 2. prepending/appending. Data for types and formats are order
|
||||
/// sensitive. It is required for supporting prepending/appending to
|
||||
/// the list and ability to remove the prepended/appended items.
|
||||
/// 3. update. Update to the data needs to be communicated to other monad
|
||||
/// components. For example, if cmdlets/providers list is updated, it
|
||||
/// has to be communicated to engine.
|
||||
/// -->
|
||||
#if CORECLR
|
||||
internal
|
||||
#else
|
||||
public
|
||||
#endif
|
||||
sealed class RunspaceConfigurationEntryCollection<T> : IEnumerable<T> where T : RunspaceConfigurationEntry
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public RunspaceConfigurationEntryCollection()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="items"></param>
|
||||
public RunspaceConfigurationEntryCollection(IEnumerable<T> items)
|
||||
{
|
||||
if (items == null)
|
||||
{
|
||||
throw PSTraceSource.NewArgumentNullException("item");
|
||||
}
|
||||
AddBuiltInItem(items);
|
||||
}
|
||||
|
||||
private Collection<T> _data = new Collection<T>();
|
||||
private int _builtInEnd = 0; // this is the index of first after item.
|
||||
|
||||
private Collection<T> _updateList = new Collection<T>();
|
||||
internal Collection<T> UpdateList
|
||||
{
|
||||
get
|
||||
{
|
||||
return _updateList;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get items at a index position.
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
public T this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_syncObject)
|
||||
{
|
||||
return _data[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get number of items in the collection.
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_syncObject)
|
||||
{
|
||||
return _data.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset items in the collection
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
lock (_syncObject)
|
||||
{
|
||||
for (int i = _data.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (!_data[i].BuiltIn)
|
||||
{
|
||||
RecordRemove(_data[i]);
|
||||
|
||||
_data.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
_builtInEnd = _data.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove one item from the collection
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <exception cref="PSArgumentOutOfRangeException">when <paramref name="index"/> is out of range.</exception>
|
||||
public void RemoveItem(int index)
|
||||
{
|
||||
lock (_syncObject)
|
||||
{
|
||||
if (index < 0 || index >= _data.Count)
|
||||
{
|
||||
throw PSTraceSource.NewArgumentOutOfRangeException("index", index);
|
||||
}
|
||||
|
||||
RecordRemove(_data[index]);
|
||||
|
||||
_data.RemoveAt(index);
|
||||
|
||||
if (index < _builtInEnd)
|
||||
_builtInEnd--;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove multiple items in the collection.
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <exception cref="PSArgumentOutOfRangeException">when <paramref name="index"/> is out of range.</exception>
|
||||
public void RemoveItem(int index, int count)
|
||||
{
|
||||
lock (_syncObject)
|
||||
{
|
||||
if (index < 0 || index + count > _data.Count)
|
||||
{
|
||||
throw PSTraceSource.NewArgumentOutOfRangeException("index", index);
|
||||
}
|
||||
|
||||
for (int i = index + count - 1; i >= index; i--)
|
||||
{
|
||||
RecordRemove(_data[i]);
|
||||
|
||||
_data.RemoveAt(i);
|
||||
}
|
||||
|
||||
int _numBeforeBuiltInEnd = Math.Min(count, _builtInEnd - index);
|
||||
|
||||
if (_numBeforeBuiltInEnd > 0)
|
||||
_builtInEnd -= _numBeforeBuiltInEnd;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove one item from the collection
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
internal void Remove(T item)
|
||||
{
|
||||
lock (_syncObject)
|
||||
{
|
||||
int index = _data.IndexOf(item);
|
||||
|
||||
if (index < 0 || index >= _data.Count)
|
||||
{
|
||||
Dbg.Assert(false, "Index from which to remove the item is out of range.");
|
||||
throw PSTraceSource.NewArgumentOutOfRangeException("index", index);
|
||||
}
|
||||
|
||||
RecordRemove(item);
|
||||
_data.Remove(item);
|
||||
|
||||
if (index < _builtInEnd)
|
||||
_builtInEnd--;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepend an item to the collection.
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
public void Prepend(T item)
|
||||
{
|
||||
lock (_syncObject)
|
||||
{
|
||||
RecordAdd(item);
|
||||
|
||||
item._builtIn = false;
|
||||
_data.Insert(0, item);
|
||||
_builtInEnd++;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepend items into the collection
|
||||
/// </summary>
|
||||
/// <param name="items"></param>
|
||||
public void Prepend(IEnumerable<T> items)
|
||||
{
|
||||
if (items == null)
|
||||
{
|
||||
throw new ArgumentNullException("items");
|
||||
}
|
||||
|
||||
lock (_syncObject)
|
||||
{
|
||||
int i = 0;
|
||||
foreach (T t in items)
|
||||
{
|
||||
RecordAdd(t);
|
||||
|
||||
t._builtIn = false;
|
||||
_data.Insert(i++, t);
|
||||
_builtInEnd++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Append one item to the collection
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
public void Append(T item)
|
||||
{
|
||||
lock (_syncObject)
|
||||
{
|
||||
RecordAdd(item);
|
||||
|
||||
item._builtIn = false;
|
||||
_data.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Append items to the collection.
|
||||
/// </summary>
|
||||
/// <param name="items"></param>
|
||||
public void Append(IEnumerable<T> items)
|
||||
{
|
||||
if (items == null)
|
||||
{
|
||||
throw new ArgumentNullException("items");
|
||||
}
|
||||
|
||||
lock (_syncObject)
|
||||
{
|
||||
foreach (T t in items)
|
||||
{
|
||||
RecordAdd(t);
|
||||
|
||||
t._builtIn = false;
|
||||
_data.Add(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddBuiltInItem(T item)
|
||||
{
|
||||
lock (_syncObject)
|
||||
{
|
||||
item._builtIn = true;
|
||||
|
||||
RecordAdd(item);
|
||||
|
||||
_data.Insert(_builtInEnd, item);
|
||||
_builtInEnd++;
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddBuiltInItem(IEnumerable<T> items)
|
||||
{
|
||||
lock (_syncObject)
|
||||
{
|
||||
foreach (T t in items)
|
||||
{
|
||||
t._builtIn = true;
|
||||
|
||||
RecordAdd(t);
|
||||
|
||||
_data.Insert(_builtInEnd, t);
|
||||
_builtInEnd++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void RemovePSSnapIn(string PSSnapinName)
|
||||
{
|
||||
lock (_syncObject)
|
||||
{
|
||||
for (int i = _data.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (_data[i].PSSnapIn != null)
|
||||
{
|
||||
if (_data[i].PSSnapIn.Name.Equals(PSSnapinName, StringComparison.Ordinal))
|
||||
{
|
||||
RecordRemove(_data[i]);
|
||||
|
||||
_data.RemoveAt(i);
|
||||
|
||||
if (i < _builtInEnd)
|
||||
_builtInEnd--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get enumerator for this collection.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <!--
|
||||
/// Enumerator work is not thread safe by default. Any code trying
|
||||
/// to do enumeration on this collection should lock it first.
|
||||
///
|
||||
/// Need to document this.
|
||||
/// -->
|
||||
IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return _data.GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get enumerator for this collection.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <!--
|
||||
/// Enumerator work is not thread safe by default. Any code trying
|
||||
/// to do enumeration on this collection should lock it first.
|
||||
///
|
||||
/// Need to document this.
|
||||
/// -->
|
||||
IEnumerator<T> System.Collections.Generic.IEnumerable<T>.GetEnumerator()
|
||||
{
|
||||
return _data.GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update others about the collection change.
|
||||
/// </summary>
|
||||
public void Update()
|
||||
{
|
||||
Update(false);
|
||||
}
|
||||
|
||||
internal void Update(bool force)
|
||||
{
|
||||
lock (_syncObject)
|
||||
{
|
||||
if (OnUpdate != null && (force || _updateList.Count > 0))
|
||||
{
|
||||
OnUpdate();
|
||||
|
||||
// Here we need to clear the Action for each item
|
||||
// since _updateList is sharing data with _data.
|
||||
foreach (T t in _updateList)
|
||||
{
|
||||
t._action = UpdateAction.None;
|
||||
}
|
||||
|
||||
_updateList.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RecordRemove(T t)
|
||||
{
|
||||
// if this item was added recently, simply remove the add action.
|
||||
if (t.Action == UpdateAction.Add)
|
||||
{
|
||||
t._action = UpdateAction.None;
|
||||
_updateList.Remove(t);
|
||||
}
|
||||
else
|
||||
{
|
||||
t._action = UpdateAction.Remove;
|
||||
_updateList.Add(t);
|
||||
}
|
||||
}
|
||||
|
||||
private void RecordAdd(T t)
|
||||
{
|
||||
// if this item was removed recently, simply remove the add action.
|
||||
if (t.Action == UpdateAction.Remove)
|
||||
{
|
||||
t._action = UpdateAction.None;
|
||||
_updateList.Remove(t);
|
||||
}
|
||||
else
|
||||
{
|
||||
t._action = UpdateAction.Add;
|
||||
_updateList.Add(t);
|
||||
}
|
||||
}
|
||||
|
||||
//object to use for locking
|
||||
private object _syncObject = new object();
|
||||
|
||||
/// <summary>
|
||||
/// OnUpdate handler should lock the object itself.
|
||||
/// </summary>
|
||||
internal event RunspaceConfigurationEntryUpdateEventHandler OnUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore 56517
|
||||
@@ -1,29 +0,0 @@
|
||||
/********************************************************************++
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
namespace System.Management.Automation.Runspaces
|
||||
{
|
||||
/// <summary>
|
||||
/// RunspaceConfigurationHelper define some constants to be used by
|
||||
/// both Minishell api and makekit.
|
||||
///
|
||||
/// Be very careful when trying to change values for strings below since
|
||||
/// it will be used by makekit process also.
|
||||
///
|
||||
/// This file will be built with both monad engine and makekit.
|
||||
/// </summary>
|
||||
internal static class RunspaceConfigurationHelper
|
||||
{
|
||||
internal const string IntrinsicTypeResourceName = "intrinsicTypes";
|
||||
internal const string BuiltInTypeResourceName = "builtInTypes";
|
||||
internal const string IntrinsicFormatResourceName = "intrinsicFormats";
|
||||
internal const string BuiltInFormatResourceName = "builtInFormats";
|
||||
internal const string ScriptResourceName = "script";
|
||||
internal const string ProfileResourceName = "initialization";
|
||||
internal const string HelpResourceName = "help";
|
||||
internal const string ShellHelpResourceKey = "ShellHelp";
|
||||
internal const string ShellBannerResourceKey = "ShellBanner";
|
||||
internal const string ResourceListKey = "__resourceList__";
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/********************************************************************++
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
namespace System.Management.Automation.Runspaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Define the class for runspace configuration type attribute.
|
||||
/// </summary>
|
||||
/// <!--
|
||||
/// This is an assembly attribute for the mini-shell assembly to tell
|
||||
/// the type name for MiniShellConfiguration derived class.
|
||||
/// -->
|
||||
[AttributeUsage(AttributeTargets.Assembly)]
|
||||
internal sealed class RunspaceConfigurationTypeAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initiate an instance of RunspaceConfigurationTypeAttribute.
|
||||
/// </summary>
|
||||
/// <param name="runspaceConfigurationType">Runspace configuration type</param>
|
||||
public RunspaceConfigurationTypeAttribute(string runspaceConfigurationType)
|
||||
{
|
||||
RunspaceConfigurationType = runspaceConfigurationType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get runspace configuration type
|
||||
/// </summary>
|
||||
public string RunspaceConfigurationType { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,181 +0,0 @@
|
||||
/********************************************************************++
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
using System.Runtime.Serialization;
|
||||
using System.Reflection;
|
||||
using System.Security.Permissions;
|
||||
|
||||
namespace System.Management.Automation.Runspaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Define class for runspace configuration type.
|
||||
/// </summary>
|
||||
/// <!--
|
||||
/// RunspaceConfigurationTypeException is the exception to be thrown when there is no
|
||||
/// help found for a topic.
|
||||
///
|
||||
/// Implementation of RunspaceConfigurationTypeException requires it to
|
||||
/// 1. Implement IContainsErrorRecord,
|
||||
/// 2. ISerializable
|
||||
/// -->
|
||||
[Serializable]
|
||||
internal class RunspaceConfigurationTypeException : SystemException, IContainsErrorRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// Initiate an instance for RunspaceConfigurationTypeException
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">Name of the assembly where <paramref name="typeName"/> is defined.</param>
|
||||
/// <param name="typeName">Runspace configuration type</param>
|
||||
internal RunspaceConfigurationTypeException(string assemblyName, string typeName) : base()
|
||||
{
|
||||
_assemblyName = assemblyName;
|
||||
_typeName = typeName;
|
||||
CreateErrorRecord();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initiate an instance for RunspaceConfigurationTypeException
|
||||
/// </summary>
|
||||
public RunspaceConfigurationTypeException() : base()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initiate an instance for RunspaceConfigurationTypeException
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">Name of the assembly where <paramref name="typeName"/> is defined.</param>
|
||||
/// <param name="typeName">Runspace configuration type defined in <paramref name="assemblyName"/></param>
|
||||
/// <param name="innerException">Inner exception of this exception</param>
|
||||
internal RunspaceConfigurationTypeException(string assemblyName, string typeName, Exception innerException) : base(innerException.Message, innerException)
|
||||
{
|
||||
_assemblyName = assemblyName;
|
||||
_typeName = typeName;
|
||||
CreateErrorRecord();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initiate an instance for RunspaceConfigurationTypeException
|
||||
/// </summary>
|
||||
/// <param name="message">Error message</param>
|
||||
public RunspaceConfigurationTypeException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initiate an instance for RunspaceConfigurationTypeException
|
||||
/// </summary>
|
||||
/// <param name="message">Error message</param>
|
||||
/// <param name="innerException">Inner exception of this exception</param>
|
||||
public RunspaceConfigurationTypeException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the internal error record based on assembly name and type.
|
||||
/// The ErrorRecord created will be stored in the _errorRecord member.
|
||||
/// </summary>
|
||||
private void CreateErrorRecord()
|
||||
{
|
||||
if (!String.IsNullOrEmpty(_assemblyName) && !String.IsNullOrEmpty(_typeName))
|
||||
{
|
||||
_errorRecord = new ErrorRecord(new ParentContainsErrorRecordException(this), "UndefinedRunspaceConfigurationType", ErrorCategory.ResourceUnavailable, null);
|
||||
_errorRecord.ErrorDetails = new ErrorDetails(typeof(RunspaceConfigurationTypeException).GetTypeInfo().Assembly, "MiniShellErrors", "UndefinedRunspaceConfigurationType", _assemblyName, _typeName);
|
||||
}
|
||||
}
|
||||
|
||||
private ErrorRecord _errorRecord;
|
||||
|
||||
/// <summary>
|
||||
/// Get the error record embedded in this exception.
|
||||
/// </summary>
|
||||
public ErrorRecord ErrorRecord
|
||||
{
|
||||
get
|
||||
{
|
||||
return _errorRecord;
|
||||
}
|
||||
}
|
||||
|
||||
private string _assemblyName = "";
|
||||
|
||||
/// <summary>
|
||||
/// Get name of the assembly where runspace configuration type is defined.
|
||||
/// </summary>
|
||||
public string AssemblyName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _assemblyName;
|
||||
}
|
||||
}
|
||||
|
||||
private string _typeName = "";
|
||||
|
||||
/// <summary>
|
||||
/// Get the runspace configuration type.
|
||||
/// </summary>
|
||||
public string TypeName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _typeName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get message for this exception.
|
||||
/// </summary>
|
||||
public override string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_errorRecord != null)
|
||||
{
|
||||
return _errorRecord.ToString();
|
||||
}
|
||||
|
||||
return base.Message;
|
||||
}
|
||||
}
|
||||
|
||||
#region Serialization
|
||||
|
||||
/// <summary>
|
||||
/// Initiate a RunspaceConfigurationAttributeException instance.
|
||||
/// </summary>
|
||||
/// <param name="info"> Serialization information </param>
|
||||
/// <param name="context"> Streaming context </param>
|
||||
protected RunspaceConfigurationTypeException(SerializationInfo info,
|
||||
StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
_typeName = info.GetString("TypeName");
|
||||
_assemblyName = info.GetString("AssemblyName");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get object data from serialization information.
|
||||
/// </summary>
|
||||
/// <param name="info"> Serialization information </param>
|
||||
/// <param name="context"> Streaming context </param>
|
||||
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
if (info == null)
|
||||
{
|
||||
throw PSTraceSource.NewArgumentNullException("info");
|
||||
}
|
||||
|
||||
base.GetObjectData(info, context);
|
||||
|
||||
info.AddValue("TypeName", _typeName);
|
||||
info.AddValue("AssemblyName", _assemblyName);
|
||||
}
|
||||
|
||||
#endregion Serialization
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,18 +117,6 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="UndefinedRunspaceConfigurationType" xml:space="preserve">
|
||||
<value>The RunspaceConfiguration-derived type {1} is not defined in assembly {0}.</value>
|
||||
</data>
|
||||
<data name="RunspaceConfigurationAttributeNotExist" xml:space="preserve">
|
||||
<value>Cannot create the RunspaceConfiguration object because an assembly attribute of type RunspaceConfigurationType is not defined in assembly {0}. </value>
|
||||
</data>
|
||||
<data name="RunspaceConfigurationAttributeDuplicate" xml:space="preserve">
|
||||
<value>Cannot create the RunspaceConfiguration object because there is more than one assembly attribute of the type RunspaceConfigurationType defined in the assembly {0}.</value>
|
||||
</data>
|
||||
<data name="InvalidEntryAssembly" xml:space="preserve">
|
||||
<value>Cannot reflect on the entry assembly and determine the value of the RunspaceConfigurationType attribute. </value>
|
||||
</data>
|
||||
<data name="UpdateNotSupportedForConfigurationCategory" xml:space="preserve">
|
||||
<value>The update is not supported for the runspace configuration category {0}. </value>
|
||||
</data>
|
||||
|
||||
@@ -1,602 +0,0 @@
|
||||
/********************************************************************++
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Management.Automation;
|
||||
using System.Management.Automation.Runspaces;
|
||||
using System.Management.Automation.Internal;
|
||||
using Dbg = System.Management.Automation.Diagnostics;
|
||||
|
||||
#pragma warning disable 1634, 1691 // Stops compiler from warning about unknown warnings
|
||||
|
||||
namespace Microsoft.PowerShell.Commands
|
||||
{
|
||||
#region ConsoleCmdletsBase
|
||||
/// <summary>
|
||||
/// Base class for all the Console related cmdlets.
|
||||
/// </summary>
|
||||
public abstract class ConsoleCmdletsBase : PSCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// Runspace configuration for the current engine
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Console cmdlets need <see cref="RunspaceConfigForSingleShell"/> object to work with.
|
||||
/// </remarks>
|
||||
internal RunspaceConfigForSingleShell Runspace
|
||||
{
|
||||
get
|
||||
{
|
||||
RunspaceConfigForSingleShell runSpace = Context.RunspaceConfiguration as RunspaceConfigForSingleShell;
|
||||
return runSpace;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// InitialSessionState for the current engine
|
||||
/// </summary>
|
||||
internal InitialSessionState InitialSessionState
|
||||
{
|
||||
get
|
||||
{
|
||||
return Context.InitialSessionState;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws a terminating error.
|
||||
/// </summary>
|
||||
/// <param name="targetObject">Object which caused this exception.</param>
|
||||
/// <param name="errorId">ErrorId for this error.</param>
|
||||
/// <param name="innerException">Complete exception object.</param>
|
||||
/// <param name="category">ErrorCategory for this exception.</param>
|
||||
internal void ThrowError(
|
||||
Object targetObject,
|
||||
string errorId,
|
||||
Exception innerException,
|
||||
ErrorCategory category)
|
||||
{
|
||||
ThrowTerminatingError(new ErrorRecord(innerException, errorId, category, targetObject));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region export-console
|
||||
|
||||
/// <summary>
|
||||
/// Class that implements export-console cmdlet.
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsData.Export, "Console", SupportsShouldProcess = true, HelpUri = "https://go.microsoft.com/fwlink/?LinkID=113298")]
|
||||
public sealed class ExportConsoleCommand : ConsoleCmdletsBase
|
||||
{
|
||||
#region Parameters
|
||||
|
||||
/// <summary>
|
||||
/// Property that gets/sets console file name.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If a parameter is not supplied then the file represented by $console
|
||||
/// will be used for saving.
|
||||
/// </remarks>
|
||||
[Parameter(Position = 0, Mandatory = false, ValueFromPipeline = true,
|
||||
ValueFromPipelineByPropertyName = true)]
|
||||
[Alias("PSPath")]
|
||||
public string Path
|
||||
{
|
||||
get
|
||||
{
|
||||
return _fileName;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_fileName = value;
|
||||
}
|
||||
}
|
||||
private string _fileName;
|
||||
|
||||
/// <summary>
|
||||
/// Property that sets force parameter. This will reset the read-only
|
||||
/// attribute on an existing file before deleting it.
|
||||
/// </summary>
|
||||
[Parameter()]
|
||||
public SwitchParameter Force
|
||||
{
|
||||
get
|
||||
{
|
||||
return _force;
|
||||
}
|
||||
set
|
||||
{
|
||||
_force = value;
|
||||
}
|
||||
}
|
||||
private bool _force;
|
||||
|
||||
/// <summary>
|
||||
/// Property that prevents file overwrite.
|
||||
/// </summary>
|
||||
[Parameter()]
|
||||
[Alias("NoOverwrite")]
|
||||
public SwitchParameter NoClobber
|
||||
{
|
||||
get
|
||||
{
|
||||
return _noclobber;
|
||||
}
|
||||
set
|
||||
{
|
||||
_noclobber = value;
|
||||
}
|
||||
}
|
||||
private bool _noclobber;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides
|
||||
|
||||
/// <summary>
|
||||
/// Saves the current console info into a file.
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
// Get filename..
|
||||
string file = GetFileName();
|
||||
|
||||
// if file is null or empty..prompt the user for filename
|
||||
if (string.IsNullOrEmpty(file))
|
||||
{
|
||||
file = PromptUserForFile();
|
||||
}
|
||||
|
||||
// if file is still empty..write error and back out..
|
||||
if (string.IsNullOrEmpty(file))
|
||||
{
|
||||
PSArgumentException ae = PSTraceSource.NewArgumentException("file", ConsoleInfoErrorStrings.FileNameNotResolved);
|
||||
ThrowError(file, "FileNameNotResolved", ae, ErrorCategory.InvalidArgument);
|
||||
}
|
||||
|
||||
if (WildcardPattern.ContainsWildcardCharacters(file))
|
||||
{
|
||||
ThrowError(file, "WildCardNotSupported",
|
||||
PSTraceSource.NewInvalidOperationException(ConsoleInfoErrorStrings.ConsoleFileWildCardsNotSupported,
|
||||
file), ErrorCategory.InvalidOperation);
|
||||
}
|
||||
|
||||
// Ofcourse, you cant write to a file from HKLM: etc..
|
||||
string resolvedPath = ResolveProviderAndPath(file);
|
||||
|
||||
// If resolvedPath is empty just return..
|
||||
if (string.IsNullOrEmpty(resolvedPath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check whether the file ends with valid extension
|
||||
if (!resolvedPath.EndsWith(StringLiterals.PowerShellConsoleFileExtension,
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// file does not end with proper extension..create one..
|
||||
resolvedPath = resolvedPath + StringLiterals.PowerShellConsoleFileExtension;
|
||||
}
|
||||
|
||||
if (!ShouldProcess(this.Path)) // should this be resolvedPath?
|
||||
return;
|
||||
|
||||
//check if destination file exists.
|
||||
if (File.Exists(resolvedPath))
|
||||
{
|
||||
if (NoClobber)
|
||||
{
|
||||
string message = StringUtil.Format(
|
||||
ConsoleInfoErrorStrings.FileExistsNoClobber,
|
||||
resolvedPath,
|
||||
"NoClobber"); // prevents localization
|
||||
Exception uae = new UnauthorizedAccessException(message);
|
||||
ErrorRecord errorRecord = new ErrorRecord(
|
||||
uae, "NoClobber", ErrorCategory.ResourceExists, resolvedPath);
|
||||
// NOTE: this call will throw
|
||||
ThrowTerminatingError(errorRecord);
|
||||
}
|
||||
// Check if the file is read-only
|
||||
System.IO.FileAttributes attrib = System.IO.File.GetAttributes(resolvedPath);
|
||||
if ((attrib & System.IO.FileAttributes.ReadOnly) == System.IO.FileAttributes.ReadOnly)
|
||||
{
|
||||
if (Force)
|
||||
{
|
||||
RemoveFileThrowIfError(resolvedPath);
|
||||
// Note, we do not attempt to set read-only on the new file
|
||||
}
|
||||
else
|
||||
{
|
||||
ThrowError(file, "ConsoleFileReadOnly",
|
||||
PSTraceSource.NewArgumentException(file, ConsoleInfoErrorStrings.ConsoleFileReadOnly, resolvedPath),
|
||||
ErrorCategory.InvalidArgument);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (this.Runspace != null)
|
||||
{
|
||||
this.Runspace.SaveAsConsoleFile(resolvedPath);
|
||||
}
|
||||
else if (InitialSessionState != null)
|
||||
{
|
||||
this.InitialSessionState.SaveAsConsoleFile(resolvedPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
Dbg.Assert(false, "Both RunspaceConfiguration and InitialSessionState should not be null");
|
||||
throw PSTraceSource.NewInvalidOperationException(ConsoleInfoErrorStrings.CmdletNotAvailable);
|
||||
}
|
||||
}
|
||||
catch (PSArgumentException mae)
|
||||
{
|
||||
ThrowError(resolvedPath,
|
||||
"PathNotAbsolute", mae, ErrorCategory.InvalidArgument);
|
||||
}
|
||||
catch (PSArgumentNullException mane)
|
||||
{
|
||||
ThrowError(resolvedPath,
|
||||
"PathNull", mane, ErrorCategory.InvalidArgument);
|
||||
}
|
||||
catch (ArgumentException ae)
|
||||
{
|
||||
ThrowError(resolvedPath,
|
||||
"InvalidCharactersInPath", ae, ErrorCategory.InvalidArgument);
|
||||
}
|
||||
|
||||
// looks like saving succeeded.
|
||||
// Now try changing $console
|
||||
Exception e = null;
|
||||
try
|
||||
{
|
||||
//Update $Console variable
|
||||
Context.EngineSessionState.SetConsoleVariable();
|
||||
}
|
||||
catch (ArgumentNullException ane)
|
||||
{
|
||||
e = ane;
|
||||
}
|
||||
catch (ArgumentOutOfRangeException aor)
|
||||
{
|
||||
e = aor;
|
||||
}
|
||||
catch (ArgumentException ae)
|
||||
{
|
||||
e = ae;
|
||||
}
|
||||
catch (SessionStateUnauthorizedAccessException sue)
|
||||
{
|
||||
e = sue;
|
||||
}
|
||||
catch (ProviderNotFoundException pnf)
|
||||
{
|
||||
e = pnf;
|
||||
}
|
||||
catch (System.Management.Automation.DriveNotFoundException dnfe)
|
||||
{
|
||||
e = dnfe;
|
||||
}
|
||||
catch (NotSupportedException ne)
|
||||
{
|
||||
e = ne;
|
||||
}
|
||||
catch (ProviderInvocationException pin)
|
||||
{
|
||||
e = pin;
|
||||
}
|
||||
|
||||
if (e != null)
|
||||
{
|
||||
throw PSTraceSource.NewInvalidOperationException(e,
|
||||
ConsoleInfoErrorStrings.ConsoleVariableCannotBeSet, resolvedPath);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Removes file specified by destination
|
||||
/// </summary>
|
||||
/// <param name="destination">Absolute path of the file to be removed.</param>
|
||||
private void RemoveFileThrowIfError(string destination)
|
||||
{
|
||||
Diagnostics.Assert(System.IO.Path.IsPathRooted(destination),
|
||||
"RemoveFile expects an absolute path");
|
||||
|
||||
System.IO.FileInfo destfile = new System.IO.FileInfo(destination);
|
||||
if (destfile != null)
|
||||
{
|
||||
Exception e = null;
|
||||
try
|
||||
{
|
||||
//Make sure the file is not read only
|
||||
destfile.Attributes = destfile.Attributes & ~(FileAttributes.ReadOnly | FileAttributes.Hidden);
|
||||
destfile.Delete();
|
||||
}
|
||||
catch (FileNotFoundException fnf)
|
||||
{
|
||||
e = fnf;
|
||||
}
|
||||
catch (DirectoryNotFoundException dnf)
|
||||
{
|
||||
e = dnf;
|
||||
}
|
||||
catch (UnauthorizedAccessException uac)
|
||||
{
|
||||
e = uac;
|
||||
}
|
||||
catch (System.Security.SecurityException se)
|
||||
{
|
||||
e = se;
|
||||
}
|
||||
catch (ArgumentNullException ane)
|
||||
{
|
||||
e = ane;
|
||||
}
|
||||
catch (ArgumentException ae)
|
||||
{
|
||||
e = ae;
|
||||
}
|
||||
catch (PathTooLongException pe)
|
||||
{
|
||||
e = pe;
|
||||
}
|
||||
catch (NotSupportedException ns)
|
||||
{
|
||||
e = ns;
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
e = ioe;
|
||||
}
|
||||
|
||||
if (e != null)
|
||||
{
|
||||
throw PSTraceSource.NewInvalidOperationException(e,
|
||||
ConsoleInfoErrorStrings.ExportConsoleCannotDeleteFile,
|
||||
destfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the specified path and verifies the path belongs to
|
||||
/// FileSystemProvider.
|
||||
/// </summary>
|
||||
/// <param name="path">Path to resolve</param>
|
||||
/// <returns>A fully qualified string representing filename.</returns>
|
||||
private string ResolveProviderAndPath(string path)
|
||||
{
|
||||
// Construct cmdletprovidercontext
|
||||
CmdletProviderContext cmdContext = new CmdletProviderContext(this);
|
||||
// First resolve path
|
||||
PathInfo resolvedPath = ResolvePath(path, true, cmdContext);
|
||||
|
||||
// Check whether this is FileSystemProvider..
|
||||
if (resolvedPath != null)
|
||||
{
|
||||
if (resolvedPath.Provider.ImplementingType == typeof(FileSystemProvider))
|
||||
{
|
||||
return resolvedPath.Path;
|
||||
}
|
||||
|
||||
throw PSTraceSource.NewInvalidOperationException(ConsoleInfoErrorStrings.ProviderNotSupported, resolvedPath.Provider.Name);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the specified path to PathInfo objects
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="pathToResolve">
|
||||
/// The path to be resolved. Each path may contain glob characters.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="allowNonexistingPaths">
|
||||
/// If true, resolves the path even if it doesn't exist.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="currentCommandContext">
|
||||
/// The context under which the command is running.
|
||||
/// </param>
|
||||
///
|
||||
/// <returns>
|
||||
/// A string representing the resolved path.
|
||||
/// </returns>
|
||||
///
|
||||
private PathInfo ResolvePath(
|
||||
string pathToResolve,
|
||||
bool allowNonexistingPaths,
|
||||
CmdletProviderContext currentCommandContext)
|
||||
{
|
||||
Collection<PathInfo> results = new Collection<PathInfo>();
|
||||
|
||||
try
|
||||
{
|
||||
// First resolve path
|
||||
Collection<PathInfo> pathInfos =
|
||||
SessionState.Path.GetResolvedPSPathFromPSPath(
|
||||
pathToResolve,
|
||||
currentCommandContext);
|
||||
|
||||
foreach (PathInfo pathInfo in pathInfos)
|
||||
{
|
||||
results.Add(pathInfo);
|
||||
}
|
||||
}
|
||||
catch (PSNotSupportedException notSupported)
|
||||
{
|
||||
WriteError(
|
||||
new ErrorRecord(
|
||||
notSupported.ErrorRecord,
|
||||
notSupported));
|
||||
}
|
||||
catch (System.Management.Automation.DriveNotFoundException driveNotFound)
|
||||
{
|
||||
WriteError(
|
||||
new ErrorRecord(
|
||||
driveNotFound.ErrorRecord,
|
||||
driveNotFound));
|
||||
}
|
||||
catch (ProviderNotFoundException providerNotFound)
|
||||
{
|
||||
WriteError(
|
||||
new ErrorRecord(
|
||||
providerNotFound.ErrorRecord,
|
||||
providerNotFound));
|
||||
}
|
||||
catch (ItemNotFoundException pathNotFound)
|
||||
{
|
||||
if (allowNonexistingPaths)
|
||||
{
|
||||
ProviderInfo provider = null;
|
||||
System.Management.Automation.PSDriveInfo drive = null;
|
||||
string unresolvedPath =
|
||||
SessionState.Path.GetUnresolvedProviderPathFromPSPath(
|
||||
pathToResolve,
|
||||
currentCommandContext,
|
||||
out provider,
|
||||
out drive);
|
||||
|
||||
PathInfo pathInfo =
|
||||
new PathInfo(
|
||||
drive,
|
||||
provider,
|
||||
unresolvedPath,
|
||||
SessionState);
|
||||
results.Add(pathInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(
|
||||
new ErrorRecord(
|
||||
pathNotFound.ErrorRecord,
|
||||
pathNotFound));
|
||||
}
|
||||
}
|
||||
|
||||
if (results.Count == 1)
|
||||
{
|
||||
return results[0];
|
||||
}
|
||||
else if (results.Count > 1)
|
||||
{
|
||||
Exception e = PSTraceSource.NewNotSupportedException();
|
||||
WriteError(
|
||||
new ErrorRecord(e,
|
||||
"NotSupported",
|
||||
ErrorCategory.NotImplemented,
|
||||
results));
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
} // ResolvePath
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filename for the current operation. If Name parameter is empty
|
||||
/// checks $console. If $console is not present, prompts user?
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string representing filename.
|
||||
/// If filename cannot be deduced returns null.
|
||||
/// </returns>
|
||||
/// <exception cref="PSArgumentException">
|
||||
/// 1. $console points to an PSObject that cannot be converted to string.
|
||||
/// </exception>
|
||||
private string GetFileName()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_fileName))
|
||||
{
|
||||
// if user specified input..just return
|
||||
return _fileName;
|
||||
}
|
||||
// no input is specified..
|
||||
// check whether $console is set
|
||||
PSVariable consoleVariable = Context.SessionState.PSVariable.Get(SpecialVariables.ConsoleFileName);
|
||||
if (consoleVariable == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
string consoleValue = consoleVariable.Value as string;
|
||||
|
||||
if (consoleValue == null)
|
||||
{
|
||||
// $console is not in string format
|
||||
// Check whether it is in PSObject format
|
||||
PSObject consolePSObject = consoleVariable.Value as PSObject;
|
||||
|
||||
if ((consolePSObject != null) && ((consolePSObject.BaseObject as string) != null))
|
||||
{
|
||||
consoleValue = consolePSObject.BaseObject as string;
|
||||
}
|
||||
}
|
||||
|
||||
if (consoleValue != null)
|
||||
{
|
||||
// ConsoleFileName variable is found..
|
||||
return consoleValue;
|
||||
}
|
||||
|
||||
throw PSTraceSource.NewArgumentException("fileName", ConsoleInfoErrorStrings.ConsoleCannotBeConvertedToString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prompt user for filename.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// User input in string format.
|
||||
/// If user chooses not to export, an empty string is returned.
|
||||
/// </returns>
|
||||
/// <remarks>No exception is thrown</remarks>
|
||||
private string PromptUserForFile()
|
||||
{
|
||||
// ask user what to do..
|
||||
if (ShouldContinue(
|
||||
ConsoleInfoErrorStrings.PromptForExportConsole,
|
||||
null))
|
||||
{
|
||||
string caption = StringUtil.Format(ConsoleInfoErrorStrings.FileNameCaptionForExportConsole, "export-console");
|
||||
string message = ConsoleInfoErrorStrings.FileNamePromptMessage;
|
||||
|
||||
// Construct a field description object of required parameters
|
||||
Collection<System.Management.Automation.Host.FieldDescription> desc = new Collection<System.Management.Automation.Host.FieldDescription>();
|
||||
desc.Add(new System.Management.Automation.Host.FieldDescription("Name"));
|
||||
|
||||
// get user input from the host
|
||||
System.Collections.Generic.Dictionary<string, PSObject> returnValue =
|
||||
this.PSHostInternal.UI.Prompt(caption, message, desc);
|
||||
|
||||
if ((returnValue != null) && (returnValue["Name"] != null))
|
||||
{
|
||||
return (returnValue["Name"].BaseObject as string);
|
||||
}
|
||||
|
||||
// We dont have any input..
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
// If user chooses not to export, return empty string.
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -1,850 +0,0 @@
|
||||
/********************************************************************++
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Management.Automation;
|
||||
using System.Management.Automation.Runspaces;
|
||||
|
||||
#pragma warning disable 1634, 1691 // Stops compiler from warning about unknown warnings
|
||||
|
||||
namespace Microsoft.PowerShell.Commands
|
||||
{
|
||||
#region PSSnapInCommandBase
|
||||
/// <summary>
|
||||
/// Base class for all the pssnapin related cmdlets.
|
||||
/// </summary>
|
||||
public abstract class PSSnapInCommandBase : PSCmdlet, IDisposable
|
||||
{
|
||||
#region IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// Set to true when object is disposed
|
||||
/// </summary>
|
||||
///
|
||||
private bool _disposed;
|
||||
|
||||
/// <summary>
|
||||
/// Dispose method unloads the app domain and the
|
||||
/// resource reader if it was created.
|
||||
/// </summary>
|
||||
///
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed == false)
|
||||
{
|
||||
if (_resourceReader != null)
|
||||
{
|
||||
_resourceReader.Dispose();
|
||||
_resourceReader = null;
|
||||
}
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
#endregion IDisposable Members
|
||||
|
||||
#region Cmdlet Methods
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the resource reader.
|
||||
/// </summary>
|
||||
///
|
||||
protected override void EndProcessing()
|
||||
{
|
||||
if (_resourceReader != null)
|
||||
{
|
||||
_resourceReader.Dispose();
|
||||
_resourceReader = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion CmdletMethods
|
||||
|
||||
#region Internal Methods
|
||||
|
||||
/// <summary>
|
||||
/// Runspace configuration for the current engine
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// PSSnapIn cmdlets need <see cref="RunspaceConfigForSingleShell"/> object to work with.
|
||||
/// </remarks>
|
||||
internal RunspaceConfigForSingleShell Runspace
|
||||
{
|
||||
get
|
||||
{
|
||||
RunspaceConfigForSingleShell runSpace = Context.RunspaceConfiguration as RunspaceConfigForSingleShell;
|
||||
|
||||
if (runSpace == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return runSpace;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a non-terminating error onto the pipeline.
|
||||
/// </summary>
|
||||
/// <param name="targetObject">Object which caused this exception.</param>
|
||||
/// <param name="errorId">ErrorId for this error.</param>
|
||||
/// <param name="innerException">Complete exception object.</param>
|
||||
/// <param name="category">ErrorCategory for this exception.</param>
|
||||
internal void WriteNonTerminatingError(
|
||||
Object targetObject,
|
||||
string errorId,
|
||||
Exception innerException,
|
||||
ErrorCategory category)
|
||||
{
|
||||
WriteError(new ErrorRecord(innerException, errorId, category, targetObject));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Searches the input list for the pattern supplied.
|
||||
/// </summary>
|
||||
/// <param name="searchList">Input list</param>
|
||||
/// <param name="pattern">pattern with wildcards</param>
|
||||
/// <returns>
|
||||
/// A collection of string objects (representing PSSnapIn name)
|
||||
/// that match the pattern.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// Please note that this method will use WildcardPattern class.
|
||||
/// So it wont support all the 'regex' patterns
|
||||
/// </remarks>
|
||||
internal Collection<string>
|
||||
SearchListForPattern(Collection<PSSnapInInfo> searchList,
|
||||
string pattern)
|
||||
{
|
||||
Collection<string> listToReturn = new Collection<string>();
|
||||
|
||||
if (null == searchList)
|
||||
{
|
||||
// return an empty list
|
||||
return listToReturn;
|
||||
}
|
||||
|
||||
WildcardPattern matcher = WildcardPattern.Get(pattern, WildcardOptions.IgnoreCase);
|
||||
// We are doing WildCard search
|
||||
foreach (PSSnapInInfo psSnapIn in searchList)
|
||||
{
|
||||
if (matcher.IsMatch(psSnapIn.Name))
|
||||
{
|
||||
listToReturn.Add(psSnapIn.Name);
|
||||
}
|
||||
}
|
||||
|
||||
// the returned list might contain 0 objects
|
||||
return listToReturn;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See if the snapin is already loaded..returns load snapin info if true, null otherwise.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal static PSSnapInInfo IsSnapInLoaded(Collection<PSSnapInInfo> loadedSnapins, PSSnapInInfo psSnapInInfo)
|
||||
{
|
||||
if (null == loadedSnapins)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (PSSnapInInfo loadedPSSnapInInfo in loadedSnapins)
|
||||
{
|
||||
// See if the assembly-qualified names match and return the existing PSSnapInInfo
|
||||
// if they do.
|
||||
string loadedSnapInAssemblyName = loadedPSSnapInInfo.AssemblyName;
|
||||
if (string.Equals(loadedPSSnapInInfo.Name, psSnapInInfo.Name, StringComparison.OrdinalIgnoreCase) &&
|
||||
!string.IsNullOrEmpty(loadedSnapInAssemblyName)
|
||||
&& string.Equals(loadedSnapInAssemblyName, psSnapInInfo.AssemblyName, System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return loadedPSSnapInInfo;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Routine to get the list of loaded snapins...
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected internal Collection<PSSnapInInfo> GetSnapIns(string pattern)
|
||||
{
|
||||
// If RunspaceConfiguration is not null, then return the list that it has
|
||||
if (Runspace != null)
|
||||
{
|
||||
if (pattern != null)
|
||||
return Runspace.ConsoleInfo.GetPSSnapIn(pattern, _shouldGetAll);
|
||||
else
|
||||
return Runspace.ConsoleInfo.PSSnapIns;
|
||||
}
|
||||
|
||||
WildcardPattern matcher = null;
|
||||
if (!String.IsNullOrEmpty(pattern))
|
||||
{
|
||||
bool doWildCardSearch = WildcardPattern.ContainsWildcardCharacters(pattern);
|
||||
|
||||
if (!doWildCardSearch)
|
||||
{
|
||||
// Verify PSSnapInID..
|
||||
// This will throw if it not a valid name
|
||||
PSSnapInInfo.VerifyPSSnapInFormatThrowIfError(pattern);
|
||||
}
|
||||
matcher = WildcardPattern.Get(pattern, WildcardOptions.IgnoreCase);
|
||||
}
|
||||
|
||||
Collection<PSSnapInInfo> snapins = new Collection<PSSnapInInfo>();
|
||||
if (_shouldGetAll)
|
||||
{
|
||||
foreach (PSSnapInInfo snapinKey in PSSnapInReader.ReadAll())
|
||||
{
|
||||
if (matcher == null || matcher.IsMatch(snapinKey.Name))
|
||||
snapins.Add(snapinKey);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, just scan through the list of cmdlets and rebuild the table.
|
||||
List<CmdletInfo> cmdlets = InvokeCommand.GetCmdlets();
|
||||
Dictionary<PSSnapInInfo, bool> snapinTable = new Dictionary<PSSnapInInfo, bool>();
|
||||
foreach (CmdletInfo cmdlet in cmdlets)
|
||||
{
|
||||
PSSnapInInfo snapin = cmdlet.PSSnapIn;
|
||||
if (snapin != null && !snapinTable.ContainsKey(snapin))
|
||||
snapinTable.Add(snapin, true);
|
||||
}
|
||||
|
||||
foreach (PSSnapInInfo snapinKey in snapinTable.Keys)
|
||||
{
|
||||
if (matcher == null || matcher.IsMatch(snapinKey.Name))
|
||||
snapins.Add(snapinKey);
|
||||
}
|
||||
}
|
||||
return snapins;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use to indicate if all registered snapins should be listed by GetSnapins...
|
||||
/// </summary>
|
||||
protected internal bool ShouldGetAll
|
||||
{
|
||||
get { return _shouldGetAll; }
|
||||
set { _shouldGetAll = value; }
|
||||
}
|
||||
private bool _shouldGetAll;
|
||||
|
||||
/// <summary>
|
||||
/// A single instance of the resource indirect reader. This is used to load the
|
||||
/// managed resource assemblies in a different app-domain so that they can be unloaded.
|
||||
/// For perf reasons we only want to create one instance for the duration of the command
|
||||
/// and be sure it gets disposed when the command completes.
|
||||
/// </summary>
|
||||
///
|
||||
internal RegistryStringResourceIndirect ResourceReader
|
||||
{
|
||||
get {
|
||||
return _resourceReader ?? (_resourceReader = RegistryStringResourceIndirect.GetResourceIndirectReader());
|
||||
}
|
||||
}
|
||||
private RegistryStringResourceIndirect _resourceReader;
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Add-PSSnapIn
|
||||
|
||||
/// <summary>
|
||||
/// Class that implements add-pssnapin cmdlet.
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Add, "PSSnapin", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=113281")]
|
||||
[OutputType(typeof(PSSnapInInfo))]
|
||||
public sealed class AddPSSnapinCommand : PSSnapInCommandBase
|
||||
{
|
||||
#region Parameters
|
||||
|
||||
/// <summary>
|
||||
/// Property that gets/sets PSSnapIn Ids for the cmdlet.
|
||||
/// </summary>
|
||||
/// <value>An array of strings representing PSSnapIn ids.</value>
|
||||
[Parameter(
|
||||
Position = 0,
|
||||
Mandatory = true,
|
||||
ValueFromPipelineByPropertyName = true)]
|
||||
public string[] Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _pssnapins;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_pssnapins = value;
|
||||
}
|
||||
}
|
||||
private string[] _pssnapins;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Passthru flag for the operation.
|
||||
/// If true, the PSSnapInInfo object is passed down the
|
||||
/// output pipeline.
|
||||
/// </summary>
|
||||
[Parameter()]
|
||||
public SwitchParameter PassThru
|
||||
{
|
||||
get
|
||||
{
|
||||
return _passThru;
|
||||
}
|
||||
set
|
||||
{
|
||||
_passThru = value;
|
||||
}
|
||||
}
|
||||
private bool _passThru;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides
|
||||
|
||||
/// <summary>
|
||||
/// Adds pssnapins to console file and loads the pssnapin dlls into
|
||||
/// the current monad runtime.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The new pssnapin information is not stored in the console file until
|
||||
/// the file is saved.
|
||||
/// </remarks>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
// Cache for the information stored in the registry
|
||||
// update the cache the first time a wildcard is found..
|
||||
Collection<PSSnapInInfo> listToSearch = null;
|
||||
|
||||
foreach (string pattern in _pssnapins)
|
||||
{
|
||||
Exception exception = null;
|
||||
Collection<string> listToAdd = new Collection<string>();
|
||||
|
||||
try
|
||||
{
|
||||
// check whether there are any wildcard characters
|
||||
bool doWildCardSearch = WildcardPattern.ContainsWildcardCharacters(pattern);
|
||||
if (doWildCardSearch)
|
||||
{
|
||||
// wildcard found in the pattern
|
||||
// Get all the possible candidates for current monad version
|
||||
if (listToSearch == null)
|
||||
{
|
||||
// cache snapin registry information...
|
||||
|
||||
// For 3.0 PowerShell, we still use "1" as the registry version key for
|
||||
// Snapin and Custom shell lookup/discovery.
|
||||
// For 3.0 PowerShell, we use "3" as the registry version key only for Engine
|
||||
// related data like ApplicationBase etc.
|
||||
listToSearch = PSSnapInReader.ReadAll(PSVersionInfo.RegistryVersion1Key);
|
||||
}
|
||||
|
||||
listToAdd = SearchListForPattern(listToSearch, pattern);
|
||||
|
||||
// listToAdd wont be null..
|
||||
Diagnostics.Assert(listToAdd != null, "Pattern matching returned null");
|
||||
if (listToAdd.Count == 0)
|
||||
{
|
||||
if (_passThru)
|
||||
{
|
||||
// passThru is specified and we have nothing to add...
|
||||
WriteNonTerminatingError(pattern, "NoPSSnapInsFound",
|
||||
PSTraceSource.NewArgumentException(pattern,
|
||||
MshSnapInCmdletResources.NoPSSnapInsFound, pattern),
|
||||
ErrorCategory.InvalidArgument);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
listToAdd.Add(pattern);
|
||||
}
|
||||
|
||||
// now add all the snapins for this pattern...
|
||||
AddPSSnapIns(listToAdd);
|
||||
}
|
||||
catch (PSArgumentException ae)
|
||||
{
|
||||
exception = ae;
|
||||
}
|
||||
catch (System.Security.SecurityException se)
|
||||
{
|
||||
exception = se;
|
||||
}
|
||||
|
||||
if (exception != null)
|
||||
{
|
||||
WriteNonTerminatingError(pattern,
|
||||
"AddPSSnapInRead",
|
||||
exception,
|
||||
ErrorCategory.InvalidArgument);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Adds one or more snapins
|
||||
/// </summary>
|
||||
/// <param name="snapInList">List of snapin IDs</param>
|
||||
/// <remarks>
|
||||
/// This is a helper method and should not throw any
|
||||
/// exceptions. All exceptions are caught and displayed
|
||||
/// to the user using write* methods
|
||||
/// </remarks>
|
||||
private void AddPSSnapIns(Collection<string> snapInList)
|
||||
{
|
||||
if (snapInList == null)
|
||||
{
|
||||
// nothing to add
|
||||
return;
|
||||
}
|
||||
|
||||
//BUGBUG TODO - brucepay - this is a workaround for not being able to dynamically update
|
||||
// the set of cmdlets in a runspace if there is no RunspaceConfiguration object.
|
||||
// This is a temporary fix to unblock remoting tests and need to be corrected/completed
|
||||
// before we can ship...
|
||||
|
||||
// If there is no RunspaceConfig object, then
|
||||
// use an InitialSessionState object to gather and
|
||||
// bind the cmdlets from the snapins...
|
||||
if (Context.RunspaceConfiguration == null)
|
||||
{
|
||||
Collection<PSSnapInInfo> loadedSnapins = base.GetSnapIns(null);
|
||||
InitialSessionState iss = InitialSessionState.Create();
|
||||
bool isAtleastOneSnapinLoaded = false;
|
||||
foreach (string snapIn in snapInList)
|
||||
{
|
||||
if (InitialSessionState.IsEngineModule(snapIn))
|
||||
{
|
||||
WriteNonTerminatingError(snapIn, "LoadSystemSnapinAsModule",
|
||||
PSTraceSource.NewArgumentException(snapIn,
|
||||
MshSnapInCmdletResources.LoadSystemSnapinAsModule, snapIn),
|
||||
ErrorCategory.InvalidArgument);
|
||||
}
|
||||
else
|
||||
{
|
||||
PSSnapInException warning;
|
||||
try
|
||||
{
|
||||
// Read snapin data
|
||||
PSSnapInInfo newPSSnapIn = PSSnapInReader.Read(Utils.GetCurrentMajorVersion(), snapIn);
|
||||
PSSnapInInfo psSnapInInfo = IsSnapInLoaded(loadedSnapins, newPSSnapIn);
|
||||
|
||||
// that means snapin is not already loaded ..so load the snapin
|
||||
// now.
|
||||
if (null == psSnapInInfo)
|
||||
{
|
||||
psSnapInInfo = iss.ImportPSSnapIn(snapIn, out warning);
|
||||
isAtleastOneSnapinLoaded = true;
|
||||
Context.InitialSessionState.ImportedSnapins.Add(psSnapInInfo.Name, psSnapInInfo);
|
||||
}
|
||||
// Write psSnapInInfo object only if passthru is specified.
|
||||
if (_passThru)
|
||||
{
|
||||
// Load the pssnapin info properties that are localizable and redirected in the registry
|
||||
psSnapInInfo.LoadIndirectResources(ResourceReader);
|
||||
WriteObject(psSnapInInfo);
|
||||
}
|
||||
}
|
||||
|
||||
catch (PSSnapInException pse)
|
||||
{
|
||||
WriteNonTerminatingError(snapIn, "AddPSSnapInRead", pse, ErrorCategory.InvalidData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isAtleastOneSnapinLoaded)
|
||||
{
|
||||
// Now update the session state with the new stuff...
|
||||
iss.Bind(Context, /*updateOnly*/ true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string psSnapIn in snapInList)
|
||||
{
|
||||
Exception exception = null;
|
||||
|
||||
try
|
||||
{
|
||||
PSSnapInException warning = null;
|
||||
|
||||
PSSnapInInfo psSnapInInfo = this.Runspace.AddPSSnapIn(psSnapIn, out warning);
|
||||
|
||||
if (warning != null)
|
||||
{
|
||||
WriteNonTerminatingError(psSnapIn, "AddPSSnapInRead", warning, ErrorCategory.InvalidData);
|
||||
}
|
||||
|
||||
// Write psSnapInInfo object only if passthru is specified.
|
||||
if (_passThru)
|
||||
{
|
||||
// Load the pssnapin info properties that are localizable and redirected in the registry
|
||||
psSnapInInfo.LoadIndirectResources(ResourceReader);
|
||||
WriteObject(psSnapInInfo);
|
||||
}
|
||||
}
|
||||
catch (PSArgumentException ae)
|
||||
{
|
||||
exception = ae;
|
||||
}
|
||||
catch (PSSnapInException sle)
|
||||
{
|
||||
exception = sle;
|
||||
}
|
||||
catch (System.Security.SecurityException se)
|
||||
{
|
||||
exception = se;
|
||||
}
|
||||
|
||||
if (exception != null)
|
||||
{
|
||||
WriteNonTerminatingError(psSnapIn,
|
||||
"AddPSSnapInRead",
|
||||
exception,
|
||||
ErrorCategory.InvalidArgument);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Remove-PSSnapIn
|
||||
|
||||
/// <summary>
|
||||
/// Class that implements remove-pssnapin cmdlet.
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Remove, "PSSnapin", SupportsShouldProcess = true, HelpUri = "https://go.microsoft.com/fwlink/?LinkID=113378")]
|
||||
[OutputType(typeof(PSSnapInInfo))]
|
||||
public sealed class RemovePSSnapinCommand : PSSnapInCommandBase
|
||||
{
|
||||
#region Parameters
|
||||
|
||||
/// <summary>
|
||||
/// Property that gets/sets PSSnapIn Ids for the cmdlet.
|
||||
/// </summary>
|
||||
/// <value>An array of strings representing PSSnapIn ids.</value>
|
||||
[Parameter(
|
||||
Position = 0,
|
||||
Mandatory = true,
|
||||
ValueFromPipelineByPropertyName = true)]
|
||||
public string[] Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _pssnapins;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_pssnapins = value;
|
||||
}
|
||||
}
|
||||
private string[] _pssnapins;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Passthru flag for the operation.
|
||||
/// If true, the PSSnapInInfo object is also passed
|
||||
/// down the output pipeline.
|
||||
/// </summary>
|
||||
[Parameter()]
|
||||
public SwitchParameter PassThru
|
||||
{
|
||||
get
|
||||
{
|
||||
return _passThru;
|
||||
}
|
||||
set
|
||||
{
|
||||
_passThru = value;
|
||||
}
|
||||
}
|
||||
private bool _passThru;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides
|
||||
|
||||
/// <summary>
|
||||
/// Removes pssnapins from the current console file.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The pssnapin is not unloaded from the current engine. So all the cmdlets that are
|
||||
/// represented by this pssnapin will continue to work.
|
||||
/// </remarks>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
foreach (string psSnapIn in _pssnapins)
|
||||
{
|
||||
Collection<PSSnapInInfo> snapIns = GetSnapIns(psSnapIn);
|
||||
|
||||
// snapIns won't be null..
|
||||
Diagnostics.Assert(snapIns != null, "GetSnapIns() returned null");
|
||||
if (snapIns.Count == 0)
|
||||
{
|
||||
WriteNonTerminatingError(psSnapIn, "NoPSSnapInsFound",
|
||||
PSTraceSource.NewArgumentException(psSnapIn,
|
||||
MshSnapInCmdletResources.NoPSSnapInsFound, psSnapIn),
|
||||
ErrorCategory.InvalidArgument);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (PSSnapInInfo snapIn in snapIns)
|
||||
{
|
||||
// confirm the operation first
|
||||
// this is always false if WhatIf is set
|
||||
if (ShouldProcess(snapIn.Name))
|
||||
{
|
||||
Exception exception = null;
|
||||
|
||||
if (this.Runspace == null && this.Context.InitialSessionState != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Check if this snapin can be removed
|
||||
|
||||
// Monad has specific restrictions on the mshsnapinid like
|
||||
// mshsnapinid should be A-Za-z0-9.-_ etc.
|
||||
PSSnapInInfo.VerifyPSSnapInFormatThrowIfError(snapIn.Name);
|
||||
|
||||
if (MshConsoleInfo.IsDefaultPSSnapIn(snapIn.Name, this.Context.InitialSessionState.defaultSnapins))
|
||||
{
|
||||
throw PSTraceSource.NewArgumentException(snapIn.Name, ConsoleInfoErrorStrings.CannotRemoveDefault, snapIn.Name);
|
||||
}
|
||||
|
||||
// Handle the initial session state case...
|
||||
InitialSessionState iss = InitialSessionState.Create();
|
||||
PSSnapInException warning;
|
||||
|
||||
// Get the snapin information...
|
||||
iss.ImportPSSnapIn(snapIn, out warning);
|
||||
iss.Unbind(Context);
|
||||
Context.InitialSessionState.ImportedSnapins.Remove(snapIn.Name);
|
||||
}
|
||||
catch (PSArgumentException ae)
|
||||
{
|
||||
exception = ae;
|
||||
}
|
||||
|
||||
if (exception != null)
|
||||
{
|
||||
WriteNonTerminatingError(psSnapIn, "RemovePSSnapIn", exception, ErrorCategory.InvalidArgument);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
PSSnapInException warning = null;
|
||||
|
||||
PSSnapInInfo psSnapInInfo = this.Runspace.RemovePSSnapIn(snapIn.Name, out warning);
|
||||
|
||||
if (warning != null)
|
||||
{
|
||||
WriteNonTerminatingError(snapIn.Name, "RemovePSSnapInRead", warning, ErrorCategory.InvalidData);
|
||||
}
|
||||
|
||||
if (_passThru)
|
||||
{
|
||||
// Load the pssnapin info properties that are localizable and redirected in the registry
|
||||
psSnapInInfo.LoadIndirectResources(ResourceReader);
|
||||
WriteObject(psSnapInInfo);
|
||||
}
|
||||
}
|
||||
catch (PSArgumentException ae)
|
||||
{
|
||||
exception = ae;
|
||||
}
|
||||
|
||||
if (exception != null)
|
||||
{
|
||||
WriteNonTerminatingError(psSnapIn, "RemovePSSnapIn", exception, ErrorCategory.InvalidArgument);
|
||||
}
|
||||
}
|
||||
} // ShouldContinue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get-PSSnapIn
|
||||
|
||||
/// <summary>
|
||||
/// Class that implements get-pssnapin cmdlet.
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "PSSnapin", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=113330")]
|
||||
[OutputType(typeof(PSSnapInInfo))]
|
||||
public sealed class GetPSSnapinCommand : PSSnapInCommandBase
|
||||
{
|
||||
#region Parameters
|
||||
|
||||
/// <summary>
|
||||
/// Name(s) of PSSnapIn(s).
|
||||
/// </summary>
|
||||
[Parameter(Position = 0, Mandatory = false)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
public string[] Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _pssnapins;
|
||||
}
|
||||
set
|
||||
{
|
||||
_pssnapins = value;
|
||||
}
|
||||
}
|
||||
private string[] _pssnapins;
|
||||
|
||||
/// <summary>
|
||||
/// Property that determines whether to get all pssnapins that are currently
|
||||
/// registered ( in registry ).
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A boolean that determines whether to get all pssnapins that are currently
|
||||
/// registered ( in registry ).
|
||||
/// </value>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Registered
|
||||
{
|
||||
get
|
||||
{
|
||||
return ShouldGetAll;
|
||||
}
|
||||
set
|
||||
{
|
||||
ShouldGetAll = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides
|
||||
|
||||
/// <summary>
|
||||
/// Constructs PSSnapInfo objects as requested by the user and writes them to the
|
||||
/// output buffer.
|
||||
/// </summary>
|
||||
protected override void BeginProcessing()
|
||||
{
|
||||
if (_pssnapins != null)
|
||||
{
|
||||
foreach (string psSnapIn in _pssnapins)
|
||||
{
|
||||
Exception exception = null;
|
||||
|
||||
try
|
||||
{
|
||||
Collection<PSSnapInInfo> psSnapInInfoList = GetSnapIns(psSnapIn);
|
||||
|
||||
// psSnapInInfoList wont be null..
|
||||
Diagnostics.Assert(psSnapInInfoList != null, "ConsoleInfo.GetPSSnapIn returned null");
|
||||
if (psSnapInInfoList.Count == 0)
|
||||
{
|
||||
WriteNonTerminatingError(psSnapIn, "NoPSSnapInsFound",
|
||||
PSTraceSource.NewArgumentException(psSnapIn,
|
||||
MshSnapInCmdletResources.NoPSSnapInsFound, psSnapIn),
|
||||
ErrorCategory.InvalidArgument);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (PSSnapInInfo pssnapinInfo in psSnapInInfoList)
|
||||
{
|
||||
// Load the pssnapin info properties that are localizable and redirected in the registry
|
||||
pssnapinInfo.LoadIndirectResources(ResourceReader);
|
||||
WriteObject(pssnapinInfo);
|
||||
}
|
||||
}
|
||||
catch (System.Security.SecurityException se)
|
||||
{
|
||||
exception = se;
|
||||
}
|
||||
catch (PSArgumentException ae)
|
||||
{
|
||||
exception = ae;
|
||||
}
|
||||
|
||||
if (exception != null)
|
||||
{
|
||||
WriteNonTerminatingError(psSnapIn, "GetPSSnapInRead", exception, ErrorCategory.InvalidArgument);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ShouldGetAll)
|
||||
{
|
||||
Exception exception = null;
|
||||
|
||||
try
|
||||
{
|
||||
Collection<PSSnapInInfo> psSnapInInfoList = PSSnapInReader.ReadAll();
|
||||
foreach (PSSnapInInfo pssnapinInfo in psSnapInInfoList)
|
||||
{
|
||||
// Load the pssnapin info properties that are localizable and redirected in the registry
|
||||
pssnapinInfo.LoadIndirectResources(ResourceReader);
|
||||
WriteObject(pssnapinInfo);
|
||||
}
|
||||
}
|
||||
catch (System.Security.SecurityException se)
|
||||
{
|
||||
exception = se;
|
||||
}
|
||||
catch (PSArgumentException ae)
|
||||
{
|
||||
exception = ae;
|
||||
}
|
||||
|
||||
if (exception != null)
|
||||
{
|
||||
WriteNonTerminatingError(this, "GetPSSnapInRead", exception, ErrorCategory.InvalidArgument);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// this should never throw..
|
||||
Collection<PSSnapInInfo> psSnapInInfoList = GetSnapIns(null);
|
||||
foreach (PSSnapInInfo pssnapinInfo in psSnapInInfoList)
|
||||
{
|
||||
// Load the pssnapin info properties that are localizable and redirected in the registry
|
||||
pssnapinInfo.LoadIndirectResources(ResourceReader);
|
||||
WriteObject(pssnapinInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -1,959 +0,0 @@
|
||||
/********************************************************************++
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Text;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace System.Management.Automation.Runspaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Class that understands Monad Console File Format. The format for the console
|
||||
/// file is applied/read by this class only.
|
||||
///
|
||||
/// Functionality:
|
||||
/// 1. Schema version verification check.
|
||||
/// 2. Data values for the content represented by Console file. Later this data
|
||||
/// is used by other components ( MshConsoleInfo ) to construct Monad Types ( like
|
||||
/// PSSnapInInfo ).
|
||||
/// 3. Owns responsibility to read/write Files.
|
||||
///
|
||||
/// Risk:
|
||||
/// File Acces related security issues.
|
||||
///
|
||||
/// Requires:
|
||||
/// Might require Permissions to read/write into files.
|
||||
/// </summary>
|
||||
/// <!--
|
||||
/// Monad Console File is in the following format:
|
||||
/// <?xml version="1.0"?>
|
||||
/// <PSConsoleFile ConsoleSchemaVersion=1.0>
|
||||
///<PSVersion>1</PSVersion>
|
||||
///<PSSnapIns>
|
||||
/// <PSSnapIn Name=ExchangeMshSnapin />
|
||||
/// <PSSnapIn Name=MOMMshSnapin />
|
||||
///</PSSnapIns>
|
||||
///</PSConsoleFile>
|
||||
/// -->
|
||||
internal class PSConsoleFileElement
|
||||
{
|
||||
#region Console format (xml) tags
|
||||
// Create constants for each of the xml tags
|
||||
private const string MSHCONSOLEFILE = "PSConsoleFile";
|
||||
private const string CSCHEMAVERSION = "ConsoleSchemaVersion";
|
||||
private const string CSCHEMAVERSIONNUMBER = "1.0";
|
||||
private const string PSVERSION = "PSVersion";
|
||||
private const string SNAPINS = "PSSnapIns";
|
||||
private const string SNAPIN = "PSSnapIn";
|
||||
private const string SNAPINNAME = "Name";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Data
|
||||
|
||||
/// <summary>
|
||||
/// MonadVersion from the console file
|
||||
/// </summary>
|
||||
internal string MonadVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// List of MshSnapin IDs from the console file
|
||||
/// </summary>
|
||||
internal Collection<string> PSSnapIns { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
private PSConsoleFileElement(string version)
|
||||
{
|
||||
MonadVersion = version;
|
||||
// Dont make collections null...
|
||||
// making them null, wont be good for foreach statements
|
||||
PSSnapIns = new Collection<string>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region tracer
|
||||
|
||||
private static readonly PSTraceSource s_mshsnapinTracer = PSTraceSource.GetTracer("MshSnapinLoadUnload", "Loading and unloading mshsnapins", false);
|
||||
#endregion
|
||||
|
||||
#region Static Methods
|
||||
|
||||
/// <summary>
|
||||
/// Writes MshConsoleInfo object in Monad Console format into the file specified by the <paramref name="path"/>.
|
||||
/// </summary>
|
||||
/// <param name="path">The absolute path of the file into which the content is saved.</param>
|
||||
/// <param name="version">The version of PowerShell.</param>
|
||||
/// <param name="snapins">The external snapins that are loaded in the console</param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// The path value is null.
|
||||
/// </exception>
|
||||
/// <!--
|
||||
/// Caller should not pass a null value for path.
|
||||
/// -->
|
||||
internal static void WriteToFile(string path, Version version, IEnumerable<PSSnapInInfo> snapins)
|
||||
{
|
||||
Diagnostics.Assert(path != null, "Filename should not be null");
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Saving console info to file {0}.", path);
|
||||
|
||||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
settings.Indent = true;
|
||||
settings.Encoding = Encoding.UTF8;
|
||||
|
||||
using (Stream stream = new FileStream(path, FileMode.OpenOrCreate))
|
||||
{
|
||||
// Generate xml for the consoleinfo object.
|
||||
using (XmlWriter writer = XmlWriter.Create(stream, settings))
|
||||
{
|
||||
writer.WriteStartDocument();
|
||||
writer.WriteStartElement(MSHCONSOLEFILE);
|
||||
writer.WriteAttributeString(CSCHEMAVERSION, CSCHEMAVERSIONNUMBER);
|
||||
|
||||
writer.WriteStartElement(PSVERSION);
|
||||
writer.WriteString(version.ToString());
|
||||
writer.WriteEndElement(); // MonadVersion
|
||||
|
||||
writer.WriteStartElement(SNAPINS);
|
||||
foreach (PSSnapInInfo mshSnapIn in snapins)
|
||||
{
|
||||
writer.WriteStartElement(SNAPIN);
|
||||
writer.WriteAttributeString(SNAPINNAME, mshSnapIn.Name);
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
writer.WriteEndElement(); // MshSnapins
|
||||
|
||||
writer.WriteEndElement(); // Monad_ConsoleFile
|
||||
writer.WriteEndDocument();
|
||||
}
|
||||
}
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Saving console info succeeded.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a Monad Console file specified by <paramref name="path"/> and constructs
|
||||
/// a PSConsoleFileElement.
|
||||
/// </summary>
|
||||
/// <param name="path">The absolute path of the file to read from.</param>
|
||||
/// <returns>A MShConsoleFileElement object that represents content of the console file.</returns>
|
||||
/// <remarks>The return object wont be null.</remarks>
|
||||
/// <exception cref="XmlException">
|
||||
/// There is a load or parser error in the XML.
|
||||
/// </exception>
|
||||
/// <!--
|
||||
/// Caller should not pass a null value for path.
|
||||
/// -->
|
||||
internal static PSConsoleFileElement CreateFromFile(string path)
|
||||
{
|
||||
Diagnostics.Assert(path != null, "Filename should not be null");
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Loading console info from file {0}.", path);
|
||||
|
||||
XmlDocument doc = InternalDeserializer.LoadUnsafeXmlDocument(
|
||||
new FileInfo(path),
|
||||
false, /* ignore whitespace, comments, etc. */
|
||||
null); /* default maxCharactersInDocument */
|
||||
|
||||
// Validate content
|
||||
if (doc[MSHCONSOLEFILE] == null)
|
||||
{
|
||||
s_mshsnapinTracer.TraceError("Console file {0} doesn't contain tag {1}.", path, MSHCONSOLEFILE);
|
||||
|
||||
throw new XmlException(
|
||||
StringUtil.Format(ConsoleInfoErrorStrings.MonadConsoleNotFound, path));
|
||||
}
|
||||
|
||||
if ((doc[MSHCONSOLEFILE][PSVERSION] == null) ||
|
||||
(string.IsNullOrEmpty(doc[MSHCONSOLEFILE][PSVERSION].InnerText)))
|
||||
{
|
||||
s_mshsnapinTracer.TraceError("Console file {0} doesn't contain tag {1}.", path, PSVERSION);
|
||||
|
||||
throw new XmlException(
|
||||
StringUtil.Format(ConsoleInfoErrorStrings.MonadVersionNotFound, path));
|
||||
}
|
||||
|
||||
// This will never be null..
|
||||
XmlElement xmlElement = (XmlElement)doc[MSHCONSOLEFILE];
|
||||
|
||||
if (xmlElement.HasAttribute(CSCHEMAVERSION))
|
||||
{
|
||||
if (!xmlElement.GetAttribute(CSCHEMAVERSION).Equals(CSCHEMAVERSIONNUMBER, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
string resourceTemplate =
|
||||
StringUtil.Format(ConsoleInfoErrorStrings.BadConsoleVersion, path);
|
||||
string message = string.Format(CultureInfo.CurrentCulture,
|
||||
resourceTemplate, CSCHEMAVERSIONNUMBER);
|
||||
|
||||
s_mshsnapinTracer.TraceError(message);
|
||||
|
||||
throw new XmlException(message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s_mshsnapinTracer.TraceError("Console file {0} doesn't contain tag schema version.", path);
|
||||
|
||||
throw new XmlException(
|
||||
StringUtil.Format(ConsoleInfoErrorStrings.BadConsoleVersion, path));
|
||||
}
|
||||
|
||||
//process MonadVersion
|
||||
//This will never be null..
|
||||
xmlElement = (XmlElement)doc[MSHCONSOLEFILE][PSVERSION];
|
||||
|
||||
// Construct PSConsoleFileElement as we seem to have valid data
|
||||
PSConsoleFileElement consoleFileElement = new PSConsoleFileElement(xmlElement.InnerText.Trim());
|
||||
|
||||
bool isPSSnapInsProcessed = false;
|
||||
bool isPSVersionProcessed = false;
|
||||
|
||||
for (XmlNode mshSnapInsNode = doc["PSConsoleFile"].FirstChild; mshSnapInsNode != null; mshSnapInsNode = mshSnapInsNode.NextSibling)
|
||||
{
|
||||
if (mshSnapInsNode.NodeType == XmlNodeType.Comment)
|
||||
{
|
||||
// support comments inside a PSConsoleFile Element
|
||||
continue;
|
||||
}
|
||||
|
||||
//populate mshsnapin information
|
||||
xmlElement = mshSnapInsNode as XmlElement;
|
||||
|
||||
if (null == xmlElement)
|
||||
{
|
||||
throw new XmlException(ConsoleInfoErrorStrings.BadXMLFormat);
|
||||
}
|
||||
|
||||
if (xmlElement.Name == PSVERSION)
|
||||
{
|
||||
if (isPSVersionProcessed)
|
||||
{
|
||||
s_mshsnapinTracer.TraceError("Console file {0} contains more than one msh versions", path);
|
||||
|
||||
throw new XmlException(StringUtil.Format(ConsoleInfoErrorStrings.MultipleMshSnapinsElementNotSupported, PSVERSION));
|
||||
}
|
||||
|
||||
isPSVersionProcessed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (xmlElement.Name != SNAPINS)
|
||||
{
|
||||
s_mshsnapinTracer.TraceError("Tag {0} is not supported in console file", xmlElement.Name);
|
||||
|
||||
throw new XmlException(StringUtil.Format(ConsoleInfoErrorStrings.BadXMLElementFound, xmlElement.Name, MSHCONSOLEFILE, PSVERSION, SNAPINS));
|
||||
}
|
||||
|
||||
// PSSnapIns element is already processed. We dont support multiple
|
||||
// PSSnapIns elements
|
||||
if (isPSSnapInsProcessed)
|
||||
{
|
||||
s_mshsnapinTracer.TraceError("Console file {0} contains more than one mshsnapin lists", path);
|
||||
|
||||
throw new XmlException(StringUtil.Format(ConsoleInfoErrorStrings.MultipleMshSnapinsElementNotSupported, SNAPINS));
|
||||
}
|
||||
|
||||
// We are about to process mshsnapins element..so we should not
|
||||
// process some more mshsnapins elements..this boolean keeps track
|
||||
// of this.
|
||||
isPSSnapInsProcessed = true;
|
||||
|
||||
// decode all the child nodes of <PSSnapIns> node...
|
||||
for (XmlNode mshSnapInNode = xmlElement.FirstChild; mshSnapInNode != null; mshSnapInNode = mshSnapInNode.NextSibling)
|
||||
{
|
||||
XmlElement mshSnapInElement = mshSnapInNode as XmlElement;
|
||||
|
||||
if ((null == mshSnapInElement) || (mshSnapInElement.Name != SNAPIN))
|
||||
{
|
||||
throw new XmlException(
|
||||
StringUtil.Format(ConsoleInfoErrorStrings.PSSnapInNotFound, mshSnapInNode.Name));
|
||||
}
|
||||
|
||||
string id = mshSnapInElement.GetAttribute(SNAPINNAME);
|
||||
|
||||
if (string.IsNullOrEmpty(id))
|
||||
{
|
||||
throw new XmlException(ConsoleInfoErrorStrings.IDNotFound);
|
||||
}
|
||||
|
||||
consoleFileElement.PSSnapIns.Add(id);
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Found in mshsnapin {0} in console file {1}", id, path);
|
||||
}
|
||||
}
|
||||
|
||||
return consoleFileElement;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class that manages(reads/writes) Monad Console files and constructs objects
|
||||
/// that represent data in the console files.
|
||||
///
|
||||
/// Functionality:
|
||||
/// 1. Access point to the console files for Runspace and cmdlets
|
||||
/// 2. Depends on PSConsoleFileElement for reading/writing files
|
||||
/// </summary>
|
||||
/// <!--
|
||||
/// This object references PSSnapInInfo and PSSnapInReader classes and constructs
|
||||
/// PSSnapInfo objects that represent data in the console file. Runspace
|
||||
/// Configuration and Cmdlets (add-pssnapin,remove-pssnapin etc ) are expected
|
||||
/// to use this object.
|
||||
/// -->
|
||||
internal class MshConsoleInfo
|
||||
{
|
||||
#region Private Data
|
||||
|
||||
// Monad Version that this console file depends on.
|
||||
// MshSnapins that are not shipped with monad.
|
||||
private readonly Collection<PSSnapInInfo> _externalPSSnapIns;
|
||||
// Monad specific mshsnapins
|
||||
private Collection<PSSnapInInfo> _defaultPSSnapIns;
|
||||
// An internal representation that tells whether a console file is modified.
|
||||
// A string that stores fileName of the current consoleinfo object
|
||||
|
||||
#endregion
|
||||
|
||||
#region Class specific data
|
||||
|
||||
private static readonly PSTraceSource s_mshsnapinTracer = PSTraceSource.GetTracer("MshSnapinLoadUnload", "Loading and unloading mshsnapins", false);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Monad Version that the console file depends on.
|
||||
/// </summary>
|
||||
internal Version PSVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the major version of current console.
|
||||
/// </summary>
|
||||
internal string MajorVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
Diagnostics.Assert(PSVersion != null,
|
||||
"PSVersion is null");
|
||||
|
||||
return PSVersion.Major.ToString(System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of mshsnapins that are available. This includes both the monad
|
||||
/// default mshsnapins as well as external mshsnapins as represented by the
|
||||
/// console file.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The list returned is an ordered-list with default mshsnapins at the
|
||||
/// start followed by external mshsnapins in the order represented by the
|
||||
/// console file.
|
||||
/// </remarks>
|
||||
internal Collection<PSSnapInInfo> PSSnapIns
|
||||
{
|
||||
get
|
||||
{
|
||||
return MergeDefaultExternalMshSnapins();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of external mshsnapins, as represented by the console file and cmdlets
|
||||
/// add-pssnapin,remove-pssnapin, that are available.
|
||||
/// </summary>
|
||||
internal Collection<PSSnapInInfo> ExternalPSSnapIns
|
||||
{
|
||||
get
|
||||
{
|
||||
// externalPSSnapIns is never null
|
||||
Diagnostics.Assert(_externalPSSnapIns != null, "externalPSSnapIns is null");
|
||||
|
||||
return _externalPSSnapIns;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A boolean which tells whether the console file is modified after it is read
|
||||
/// or created.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Modification refers to addition/deletion operations of the external mshsnapins.
|
||||
/// </remarks>
|
||||
internal bool IsDirty { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A string representing the console file name of the current MshConsoleInfo object.
|
||||
/// If the filename is relative path, an absolute path will be constructed using
|
||||
/// Path.GetFullPath()
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Once a MshConsoleInfo object is constructed, a user may update the object by
|
||||
/// adding,removing mshsnapins. These operations directly effect the state of the
|
||||
/// MshConsoleInfo object but not update the console file.
|
||||
/// </remarks>
|
||||
internal string Filename { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Construct a MshConsoleInfo object for the Monad version specified.
|
||||
/// </summary>
|
||||
/// <param name="version">Monad Version.</param>
|
||||
private MshConsoleInfo(Version version)
|
||||
{
|
||||
PSVersion = version;
|
||||
IsDirty = false;
|
||||
Filename = null;
|
||||
|
||||
// Initialize list of mshsnapins..
|
||||
_defaultPSSnapIns = new Collection<PSSnapInInfo>();
|
||||
_externalPSSnapIns = new Collection<PSSnapInInfo>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Staic Methods
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="System.Management.Automation.Runspaces.MshConsoleInfo"/> object for the
|
||||
/// current Monad version which is already started.
|
||||
/// </summary>
|
||||
/// <exception cref="PSSnapInException">
|
||||
/// One or more default mshsnapins cannot be loaded because the
|
||||
/// registry is not populated correctly.
|
||||
/// </exception>
|
||||
internal static MshConsoleInfo CreateDefaultConfiguration()
|
||||
{
|
||||
// Steps:
|
||||
// 1. Get the current Monad Version
|
||||
// 2. Create MshConsoleInfo object.
|
||||
// 3. Read default mshsnapins.
|
||||
|
||||
MshConsoleInfo consoleInfo = new MshConsoleInfo(PSVersionInfo.PSVersion);
|
||||
try
|
||||
{
|
||||
consoleInfo._defaultPSSnapIns = PSSnapInReader.ReadEnginePSSnapIns();
|
||||
}
|
||||
catch (PSArgumentException ae)
|
||||
{
|
||||
string message = ConsoleInfoErrorStrings.CannotLoadDefaults;
|
||||
// If we were unable to load default mshsnapins throw PSSnapInException
|
||||
|
||||
s_mshsnapinTracer.TraceError(message);
|
||||
|
||||
throw new PSSnapInException(message, ae);
|
||||
}
|
||||
catch (System.Security.SecurityException se)
|
||||
{
|
||||
string message = ConsoleInfoErrorStrings.CannotLoadDefaults;
|
||||
// If we were unable to load default mshsnapins throw PSSnapInException
|
||||
|
||||
s_mshsnapinTracer.TraceError(message);
|
||||
|
||||
throw new PSSnapInException(message, se);
|
||||
}
|
||||
|
||||
return consoleInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="System.Management.Automation.Runspaces.MshConsoleInfo"/> object from a
|
||||
/// Monad console file.
|
||||
/// </summary>
|
||||
/// <param name="fileName">
|
||||
/// Monad console file name. If the filename is not absolute path. Then absolute path is
|
||||
/// constructed by using Path.GetFullPath() API.
|
||||
/// </param>
|
||||
/// <param name="cle">
|
||||
/// PSConsoleLoadException occurred while loading this console file. This object
|
||||
/// also contains specific PSSnapInExceptions that occurred while loading.
|
||||
/// </param>
|
||||
/// <exception cref="PSSnapInException">
|
||||
/// One or more default mshsnapins cannot be loaded because the
|
||||
/// registry is not populated correctly.
|
||||
/// </exception>
|
||||
/// <exception cref="PSArgumentNullException">
|
||||
/// fileName is null.
|
||||
/// </exception>
|
||||
/// <exception cref="PSArgumentException">
|
||||
/// 1. fileName does not specify proper file extension.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// fileName contains one or more of the invalid characters defined in System.IO.Path.InvalidPathChars.
|
||||
/// </exception>
|
||||
/// <exception cref="XmlException">
|
||||
/// Unable to load/parse the file specified by fileName.
|
||||
/// </exception>
|
||||
internal static MshConsoleInfo CreateFromConsoleFile(string fileName, out PSConsoleLoadException cle)
|
||||
{
|
||||
s_mshsnapinTracer.WriteLine("Creating console info from file {0}", fileName);
|
||||
|
||||
// Construct default mshsnapins
|
||||
MshConsoleInfo consoleInfo = CreateDefaultConfiguration();
|
||||
|
||||
// Check whether the filename specified is an absolute path.
|
||||
string absolutePath = Path.GetFullPath(fileName);
|
||||
consoleInfo.Filename = absolutePath;
|
||||
|
||||
// Construct externalPSSnapIns by loading file.
|
||||
consoleInfo.Load(absolutePath, out cle);
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Console info created successfully");
|
||||
|
||||
return consoleInfo;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internal Instance Methods
|
||||
|
||||
/// <summary>
|
||||
/// Saves the current <see cref="MshConsoleInfo"/> object to a file specified
|
||||
/// by <paramref name="path"/>. IsDirty is set to false once file is saved.
|
||||
/// </summary>
|
||||
/// <param name="path">
|
||||
/// If path is not an absolute path, then an absolute path is constructed by
|
||||
/// using Path.GetFullPath() API.
|
||||
/// </param>
|
||||
/// <exception cref="PSArgumentException">
|
||||
/// 1.Path does not specify proper file extension.
|
||||
/// </exception>
|
||||
/// <exception cref="PSArgumentNullException">
|
||||
/// 1. Path is null.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// path contains one or more of the invalid characters defined in System.IO.Path.InvalidPathChars.
|
||||
/// </exception>
|
||||
internal void SaveAsConsoleFile(string path)
|
||||
{
|
||||
if (null == path)
|
||||
{
|
||||
throw PSTraceSource.NewArgumentNullException("path");
|
||||
}
|
||||
|
||||
// Check whether the filename specified is an absolute path.
|
||||
string absolutePath = path;
|
||||
|
||||
if (!Path.IsPathRooted(absolutePath))
|
||||
{
|
||||
absolutePath = Path.GetFullPath(Filename);
|
||||
}
|
||||
|
||||
// Ignore case when looking for file extension.
|
||||
if (!absolutePath.EndsWith(StringLiterals.PowerShellConsoleFileExtension, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
s_mshsnapinTracer.TraceError("Console file {0} doesn't have the right extension {1}.", path, StringLiterals.PowerShellConsoleFileExtension);
|
||||
throw PSTraceSource.NewArgumentException("absolutePath", ConsoleInfoErrorStrings.BadConsoleExtension);
|
||||
}
|
||||
|
||||
//ConsoleFileElement will write to file
|
||||
PSConsoleFileElement.WriteToFile(absolutePath, this.PSVersion, this.ExternalPSSnapIns);
|
||||
//update the console file variable
|
||||
Filename = absolutePath;
|
||||
IsDirty = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the current <see cref="MshConsoleInfo"/> object to its console file.
|
||||
/// IsDirty is set to false once file is saved.
|
||||
/// </summary>
|
||||
/// <exception cref="PSInvalidOperationException">
|
||||
/// Msh is loaded with default mshsnapins. $console is currently empty.
|
||||
/// </exception>
|
||||
internal void Save()
|
||||
{
|
||||
if (null == Filename)
|
||||
{
|
||||
throw PSTraceSource.NewInvalidOperationException(ConsoleInfoErrorStrings.SaveDefaultError);
|
||||
}
|
||||
|
||||
PSConsoleFileElement.WriteToFile(Filename, this.PSVersion, this.ExternalPSSnapIns);
|
||||
IsDirty = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a mshsnapin specified by <paramref name="mshSnapInID"/> to the current list of
|
||||
/// mshsnapins. If the mshsnapin is successfully added, IsDirty property is set to true.
|
||||
/// </summary>
|
||||
/// <param name="mshSnapInID">ID of the mshsnapin which needs to be added.</param>
|
||||
/// <returns>A <see cref="PSSnapInInfo"/> object corresponding to mshSnapInID.</returns>
|
||||
/// <remarks>PSSnapIn information must be present in the registry for this call to succeed.</remarks>
|
||||
/// <exception cref="PSArgumentNullException">
|
||||
/// mshSnapInID is empty or null.
|
||||
/// </exception>
|
||||
/// <exception cref="PSArgumentException">
|
||||
/// PSSnapIn is already loaded.
|
||||
/// No PSSnapIn with given id found.
|
||||
/// PSSnapIn cannot be loaded.
|
||||
/// </exception>
|
||||
/// <exception cref="System.Security.SecurityException">
|
||||
/// Caller doesn't have permission to read keys.
|
||||
/// </exception>
|
||||
internal PSSnapInInfo AddPSSnapIn(string mshSnapInID)
|
||||
{
|
||||
if (string.IsNullOrEmpty(mshSnapInID))
|
||||
{
|
||||
PSTraceSource.NewArgumentNullException("mshSnapInID");
|
||||
}
|
||||
|
||||
// Check whether the mshsnapin is already present in defaultmshsnapins/externalMshSnapins
|
||||
if (IsDefaultPSSnapIn(mshSnapInID, _defaultPSSnapIns))
|
||||
{
|
||||
s_mshsnapinTracer.TraceError("MshSnapin {0} can't be added since it is a default mshsnapin", mshSnapInID);
|
||||
|
||||
throw PSTraceSource.NewArgumentException("mshSnapInID", ConsoleInfoErrorStrings.CannotLoadDefault);
|
||||
}
|
||||
|
||||
if (IsActiveExternalPSSnapIn(mshSnapInID))
|
||||
{
|
||||
s_mshsnapinTracer.TraceError("MshSnapin {0} is already loaded.", mshSnapInID);
|
||||
|
||||
throw PSTraceSource.NewArgumentException("mshSnapInID", ConsoleInfoErrorStrings.PSSnapInAlreadyExists, mshSnapInID);
|
||||
}
|
||||
|
||||
// Check whether the mshsnapin is present in the registry.
|
||||
PSSnapInInfo newPSSnapIn = PSSnapInReader.Read(this.MajorVersion, mshSnapInID);
|
||||
|
||||
if (!Utils.IsPSVersionSupported(newPSSnapIn.PSVersion.ToString()))
|
||||
{
|
||||
s_mshsnapinTracer.TraceError("MshSnapin {0} and current monad engine's versions don't match.", mshSnapInID);
|
||||
|
||||
throw PSTraceSource.NewArgumentException("mshSnapInID",
|
||||
ConsoleInfoErrorStrings.AddPSSnapInBadMonadVersion,
|
||||
newPSSnapIn.PSVersion.ToString(),
|
||||
PSVersion.ToString());
|
||||
}
|
||||
|
||||
// new mshsnapin will never be null
|
||||
//if this is a valid new mshsnapin,add this to external mshsnapins
|
||||
_externalPSSnapIns.Add(newPSSnapIn);
|
||||
s_mshsnapinTracer.WriteLine("MshSnapin {0} successfully added to consoleinfo list.", mshSnapInID);
|
||||
//Set IsDirty to true
|
||||
IsDirty = true;
|
||||
|
||||
return newPSSnapIn;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a mshsnapin specified by <paramref name="mshSnapInID"/> from the current
|
||||
/// list.
|
||||
/// </summary>
|
||||
/// <param name="mshSnapInID">ID of the mshsnapin which needs to be removed</param>
|
||||
/// <returns>PSSnapInInfo object for the mshsnapin that is removed.</returns>
|
||||
/// <remarks>MshSnapin is removed only from the console file. Registry entry
|
||||
/// is not touched.</remarks>
|
||||
/// <exception cref="PSArgumentNullException">
|
||||
/// mshSnapInID is null.
|
||||
/// </exception>
|
||||
/// <exception cref="PSArgumentException">
|
||||
/// 1. mshSnapInID is either a default mshsnapin or not loaded.
|
||||
/// 2. mshSnapInId is not valid.
|
||||
/// </exception>
|
||||
internal PSSnapInInfo RemovePSSnapIn(string mshSnapInID)
|
||||
{
|
||||
if (string.IsNullOrEmpty(mshSnapInID))
|
||||
{
|
||||
PSTraceSource.NewArgumentNullException("mshSnapInID");
|
||||
}
|
||||
|
||||
// Monad has specific restrictions on the mshsnapinid like
|
||||
// mshsnapinid should be A-Za-z0-9.-_ etc.
|
||||
PSSnapInInfo.VerifyPSSnapInFormatThrowIfError(mshSnapInID);
|
||||
|
||||
PSSnapInInfo removedPSSnapIn = null;
|
||||
// Check external mshsnapins
|
||||
foreach (PSSnapInInfo mshSnapIn in _externalPSSnapIns)
|
||||
{
|
||||
if (string.Equals(mshSnapInID, mshSnapIn.Name, System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// We found the mshsnapin..remove from the list and break
|
||||
removedPSSnapIn = mshSnapIn;
|
||||
_externalPSSnapIns.Remove(mshSnapIn);
|
||||
|
||||
// The state of console file is changing..so set
|
||||
// dirty flag.
|
||||
IsDirty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (removedPSSnapIn == null)
|
||||
{
|
||||
if (IsDefaultPSSnapIn(mshSnapInID, _defaultPSSnapIns))
|
||||
{
|
||||
s_mshsnapinTracer.WriteLine("MshSnapin {0} can't be removed since it is a default mshsnapin.", mshSnapInID);
|
||||
|
||||
throw PSTraceSource.NewArgumentException("mshSnapInID", ConsoleInfoErrorStrings.CannotRemoveDefault, mshSnapInID);
|
||||
}
|
||||
|
||||
throw PSTraceSource.NewArgumentException("mshSnapInID", ConsoleInfoErrorStrings.CannotRemovePSSnapIn, mshSnapInID);
|
||||
}
|
||||
|
||||
return removedPSSnapIn;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for mshsnapin in either current console or registry as determined
|
||||
/// by <paramref name="searchRegistry"/>.
|
||||
/// </summary>
|
||||
/// <param name="pattern">
|
||||
/// Id/WildcardPattern of the mshsnapin to search for. This can contain wildcard characters as
|
||||
/// represented by WildCardPattern.
|
||||
/// </param>
|
||||
/// <param name="searchRegistry">
|
||||
/// A boolean which determines whether to search in the current console or registry.
|
||||
/// </param>
|
||||
/// <returns>A collection of mshsnapininfo objects.</returns>
|
||||
/// <exception cref="PSArgumentException">
|
||||
/// 1.Unable to read registry entries for mshsnapins.
|
||||
/// 2.Pattern specified is not valid. If pattern doesnt contain
|
||||
/// wildcard characters, this function checks for the validity
|
||||
/// of the mshsnapin name.
|
||||
/// </exception>
|
||||
/// <exception cref="System.Security.SecurityException">
|
||||
/// Caller doesn't have permission to read keys.
|
||||
/// </exception>
|
||||
internal Collection<PSSnapInInfo> GetPSSnapIn(string pattern, bool searchRegistry)
|
||||
{
|
||||
// We want to improve the search speed by noting whether we want
|
||||
// to perform wildcard search.
|
||||
bool doWildCardSearch = WildcardPattern.ContainsWildcardCharacters(pattern);
|
||||
|
||||
if (!doWildCardSearch)
|
||||
{
|
||||
// Verify PSSnapInID..
|
||||
// This will throw if it not a valid name
|
||||
PSSnapInInfo.VerifyPSSnapInFormatThrowIfError(pattern);
|
||||
}
|
||||
|
||||
// Build the list to search..If searchRegistry is true get all mshsnapins available
|
||||
// from the registry, otherwise get mshsnapins from the current console.
|
||||
Collection<PSSnapInInfo> listToSearch = searchRegistry ?
|
||||
PSSnapInReader.ReadAll() : PSSnapIns;
|
||||
|
||||
// Create a list to return..
|
||||
Collection<PSSnapInInfo> listToReturn = new Collection<PSSnapInInfo>();
|
||||
|
||||
// If there is nothing to search..
|
||||
if (listToSearch == null)
|
||||
return listToReturn;
|
||||
|
||||
if (!doWildCardSearch)
|
||||
{
|
||||
// We are not doing wildcard search..
|
||||
foreach (PSSnapInInfo mshSnapIn in listToSearch)
|
||||
{
|
||||
if (string.Equals(mshSnapIn.Name, pattern, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
listToReturn.Add(mshSnapIn);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WildcardPattern matcher = WildcardPattern.Get(pattern, WildcardOptions.IgnoreCase);
|
||||
// We are doing WildCard search
|
||||
foreach (PSSnapInInfo mshSnapIn in listToSearch)
|
||||
{
|
||||
if (matcher.IsMatch(mshSnapIn.Name))
|
||||
{
|
||||
listToReturn.Add(mshSnapIn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return whatever we found..may be 0..
|
||||
return listToReturn;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Loads a Monad Console file specified by <paramref name="path"/>
|
||||
/// </summary>
|
||||
/// <param name="path">
|
||||
/// The absolute path from which the content is loaded.
|
||||
/// </param>
|
||||
/// <param name="cle">
|
||||
/// PSConsoleLoadException occurred while loading this console file. This object
|
||||
/// also contains specific PSSnapInExceptions that occurred while loading.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A list of <see cref="PSSnapInInfo"/> objects specified in the console file.
|
||||
/// </returns>
|
||||
/// <exception cref="PSArgumentNullException">
|
||||
/// Path is null.
|
||||
/// </exception>
|
||||
/// <exception cref="PSArgumentException">
|
||||
/// 1. Path does not specify proper file extension.
|
||||
/// 2. PSSnapInId doesnt contain valid characters.
|
||||
/// 3. Path is not an Absolute Path.
|
||||
/// Example of valid paths:"\\MyDir\\MyFile.txt" and "C:\\MyDir".
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// path contains one or more of the invalid characters defined in System.IO.Path.InvalidPathChars.
|
||||
/// </exception>
|
||||
/// <exception cref="XmlException">
|
||||
/// Unable to load/parse the file specified by path.
|
||||
/// </exception>
|
||||
private Collection<PSSnapInInfo> Load(string path, out PSConsoleLoadException cle)
|
||||
{
|
||||
// Initialize the out parameter..
|
||||
cle = null;
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Load mshsnapins from console file {0}", path);
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
throw PSTraceSource.NewArgumentNullException("path");
|
||||
}
|
||||
|
||||
// Check whether the path is an absolute path
|
||||
if (!Path.IsPathRooted(path))
|
||||
{
|
||||
s_mshsnapinTracer.TraceError("Console file {0} needs to be a absolute path.", path);
|
||||
|
||||
throw PSTraceSource.NewArgumentException("path", ConsoleInfoErrorStrings.PathNotAbsolute, path);
|
||||
}
|
||||
|
||||
if (!path.EndsWith(StringLiterals.PowerShellConsoleFileExtension, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
s_mshsnapinTracer.TraceError("Console file {0} needs to have {1} extension.", path, StringLiterals.PowerShellConsoleFileExtension);
|
||||
|
||||
throw PSTraceSource.NewArgumentException("path", ConsoleInfoErrorStrings.BadConsoleExtension);
|
||||
}
|
||||
|
||||
PSConsoleFileElement consoleFileElement;
|
||||
|
||||
// exceptions are thrown to the caller
|
||||
consoleFileElement = PSConsoleFileElement.CreateFromFile(path);
|
||||
|
||||
// consoleFileElement will never be null..
|
||||
if (!Utils.IsPSVersionSupported(consoleFileElement.MonadVersion))
|
||||
{
|
||||
s_mshsnapinTracer.TraceError("Console version {0} is not supported in current monad session.", consoleFileElement.MonadVersion);
|
||||
|
||||
throw PSTraceSource.NewArgumentException("PSVersion", ConsoleInfoErrorStrings.BadMonadVersion, consoleFileElement.MonadVersion,
|
||||
PSVersion.ToString());
|
||||
}
|
||||
|
||||
// Create a store for exceptions
|
||||
Collection<PSSnapInException> exceptions = new Collection<PSSnapInException>();
|
||||
|
||||
foreach (string mshsnapin in consoleFileElement.PSSnapIns)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.AddPSSnapIn(mshsnapin);
|
||||
}
|
||||
catch (PSArgumentException ae)
|
||||
{
|
||||
PSSnapInException sle = new PSSnapInException(mshsnapin, ae.Message, ae);
|
||||
|
||||
// Eat ArgumentException and continue..
|
||||
exceptions.Add(sle);
|
||||
}
|
||||
catch (System.Security.SecurityException se)
|
||||
{
|
||||
string message = ConsoleInfoErrorStrings.PSSnapInReadError;
|
||||
PSSnapInException sle = new PSSnapInException(mshsnapin, message, se);
|
||||
// Eat SecurityException and continue..
|
||||
|
||||
exceptions.Add(sle);
|
||||
}
|
||||
}
|
||||
|
||||
// Before returning check whether there are any exceptions
|
||||
if (exceptions.Count > 0)
|
||||
{
|
||||
cle = new PSConsoleLoadException(this, exceptions);
|
||||
}
|
||||
|
||||
// We are able to load console file and currently monad engine
|
||||
// can service this. So mark the isdirty flag.
|
||||
IsDirty = false;
|
||||
|
||||
return _externalPSSnapIns;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the mshsnapin is a default mshsnapin
|
||||
/// </summary>
|
||||
/// <param name="mshSnapInID">Id of the mshsnapin</param>
|
||||
/// <param name="defaultSnapins">List of default mshsnapins</param>
|
||||
/// <returns>True if PSSnapIn is default.False otherwise.</returns>
|
||||
internal static bool IsDefaultPSSnapIn(string mshSnapInID, IEnumerable<PSSnapInInfo> defaultSnapins)
|
||||
{
|
||||
// Check whether the mshsnapin is present in defaultmshsnapins.
|
||||
foreach (PSSnapInInfo mshSnapIn in defaultSnapins)
|
||||
{
|
||||
if (string.Equals(mshSnapInID, mshSnapIn.Name, System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the mshsnapin is already loaded
|
||||
/// </summary>
|
||||
/// <param name="mshSnapInID">Id of the mshsnapin</param>
|
||||
/// <returns>True if PSSnapIn is loaded.False otherwise.</returns>
|
||||
private bool IsActiveExternalPSSnapIn(string mshSnapInID)
|
||||
{
|
||||
// Check whether the mshsnapin is present in externalmshsnapins.
|
||||
foreach (PSSnapInInfo mshSnapIn in _externalPSSnapIns)
|
||||
{
|
||||
if (string.Equals(mshSnapInID, mshSnapIn.Name, System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new list of mshsnapins from default mshsnapins and external mshsnapins.
|
||||
/// </summary>
|
||||
/// <returns>A list of mshsnapins represented by the current console file</returns>
|
||||
private Collection<PSSnapInInfo> MergeDefaultExternalMshSnapins()
|
||||
{
|
||||
//Default mshsnapins should never be null
|
||||
Diagnostics.Assert(_defaultPSSnapIns != null, "Default MshSnapins for the current console is empty");
|
||||
Collection<PSSnapInInfo> mshSnapIns = new Collection<PSSnapInInfo>();
|
||||
|
||||
foreach (PSSnapInInfo mshSnapIn in _defaultPSSnapIns)
|
||||
{
|
||||
mshSnapIns.Add(mshSnapIn);
|
||||
}
|
||||
|
||||
foreach (PSSnapInInfo mshSnapIn in _externalPSSnapIns)
|
||||
{
|
||||
mshSnapIns.Add(mshSnapIn);
|
||||
}
|
||||
|
||||
return mshSnapIns;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -24,25 +24,6 @@ namespace System.Management.Automation.Runspaces
|
||||
[Serializable]
|
||||
public class PSConsoleLoadException : SystemException, IContainsErrorRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// Initiate an instance of PSConsoleLoadException.
|
||||
/// </summary>
|
||||
/// <param name="consoleInfo">Console info object for the exception</param>
|
||||
/// <param name="exceptions">A collection of PSSnapInExceptions.</param>
|
||||
internal PSConsoleLoadException(MshConsoleInfo consoleInfo, Collection<PSSnapInException> exceptions)
|
||||
: base()
|
||||
{
|
||||
if (!String.IsNullOrEmpty(consoleInfo.Filename))
|
||||
_consoleFileName = consoleInfo.Filename;
|
||||
|
||||
if (exceptions != null)
|
||||
{
|
||||
_PSSnapInExceptions = exceptions;
|
||||
}
|
||||
|
||||
CreateErrorRecord();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initiate an instance of PSConsoleLoadException.
|
||||
/// </summary>
|
||||
@@ -69,6 +50,23 @@ namespace System.Management.Automation.Runspaces
|
||||
{
|
||||
}
|
||||
|
||||
private ErrorRecord _errorRecord;
|
||||
|
||||
/// <summary>
|
||||
/// Gets error record embedded in this exception.
|
||||
/// </summary>
|
||||
/// <!--
|
||||
/// This property is required as part of IErrorRecordContainer
|
||||
/// interface.
|
||||
/// -->
|
||||
public ErrorRecord ErrorRecord
|
||||
{
|
||||
get
|
||||
{
|
||||
return _errorRecord;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the internal error record.
|
||||
/// The ErrorRecord created will be stored in the _errorRecord member.
|
||||
@@ -87,28 +85,8 @@ namespace System.Management.Automation.Runspaces
|
||||
}
|
||||
|
||||
_errorRecord = new ErrorRecord(new ParentContainsErrorRecordException(this), "ConsoleLoadFailure", ErrorCategory.ResourceUnavailable, null);
|
||||
_errorRecord.ErrorDetails = new ErrorDetails(String.Format(ConsoleInfoErrorStrings.ConsoleLoadFailure, _consoleFileName, sb.ToString()));
|
||||
}
|
||||
|
||||
private ErrorRecord _errorRecord;
|
||||
|
||||
/// <summary>
|
||||
/// Gets error record embedded in this exception.
|
||||
/// </summary>
|
||||
/// <!--
|
||||
/// This property is required as part of IErrorRecordContainer
|
||||
/// interface.
|
||||
/// -->
|
||||
public ErrorRecord ErrorRecord
|
||||
{
|
||||
get
|
||||
{
|
||||
return _errorRecord;
|
||||
}
|
||||
}
|
||||
|
||||
private string _consoleFileName = "";
|
||||
|
||||
private Collection<PSSnapInException> _PSSnapInExceptions = new Collection<PSSnapInException>();
|
||||
internal Collection<PSSnapInException> PSSnapInExceptions
|
||||
{
|
||||
@@ -135,42 +113,6 @@ namespace System.Management.Automation.Runspaces
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Serialization
|
||||
|
||||
/// <summary>
|
||||
/// Initiate a PSConsoleLoadException instance.
|
||||
/// </summary>
|
||||
/// <param name="info"> Serialization information </param>
|
||||
/// <param name="context"> Streaming context </param>
|
||||
protected PSConsoleLoadException(SerializationInfo info,
|
||||
StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
_consoleFileName = info.GetString("ConsoleFileName");
|
||||
|
||||
CreateErrorRecord();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get object data from serialization information.
|
||||
/// </summary>
|
||||
/// <param name="info"> Serialization information </param>
|
||||
/// <param name="context"> Streaming context </param>
|
||||
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
if (info == null)
|
||||
{
|
||||
throw PSTraceSource.NewArgumentNullException("info");
|
||||
}
|
||||
|
||||
base.GetObjectData(info, context);
|
||||
|
||||
info.AddValue("ConsoleFileName", _consoleFileName);
|
||||
}
|
||||
|
||||
#endregion Serialization
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-611
@@ -1,611 +0,0 @@
|
||||
/********************************************************************++
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
using System.Collections;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using System.Security;
|
||||
using Microsoft.Win32;
|
||||
using Dbg = System.Management.Automation.Diagnostics;
|
||||
|
||||
namespace System.Management.Automation
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is responsible for loading resources using the PSSnapin dll and
|
||||
/// associated registry entries.
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// The class creates an app-domain to load the resource assemblies in. Upon dispose
|
||||
/// the class unloads the app-domain to ensure the assemblies get unloaded. It uses
|
||||
/// ReflectionOnlyLoad and ReflectionOnlyLoadFrom to ensure that no code can execute
|
||||
/// and that dependencies are not loaded. This allows us to load assemblies that were
|
||||
/// built with different version of the CLR.
|
||||
/// </remarks>
|
||||
///
|
||||
internal sealed class RegistryStringResourceIndirect : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an instance of the RegistryStringResourceIndirect class.
|
||||
/// </summary>
|
||||
///
|
||||
/// <returns>
|
||||
/// A new instance of the RegistryStringResourceIndirect class.
|
||||
/// </returns>
|
||||
///
|
||||
internal static RegistryStringResourceIndirect GetResourceIndirectReader()
|
||||
{
|
||||
return new RegistryStringResourceIndirect();
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// Set to true when object is disposed
|
||||
/// </summary>
|
||||
///
|
||||
private bool _disposed;
|
||||
|
||||
/// <summary>
|
||||
/// Dispose method unloads the app domain that was
|
||||
/// created in the constructor.
|
||||
/// </summary>
|
||||
///
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed == false)
|
||||
{
|
||||
if (_domain != null)
|
||||
{
|
||||
AppDomain.Unload(_domain);
|
||||
_domain = null;
|
||||
_resourceRetriever = null;
|
||||
}
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
#endregion IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// The app-domain in which the resources will be loaded.
|
||||
/// </summary>
|
||||
///
|
||||
private AppDomain _domain;
|
||||
|
||||
/// <summary>
|
||||
/// The class that is created in the app-domain which does the resource loading.
|
||||
/// </summary>
|
||||
///
|
||||
private ResourceRetriever _resourceRetriever;
|
||||
|
||||
/// <summary>
|
||||
/// Creates the app-domain and the instance of the ResourceRetriever and
|
||||
/// sets the private fields with the references.
|
||||
/// </summary>
|
||||
///
|
||||
private void CreateAppDomain()
|
||||
{
|
||||
if (_domain == null)
|
||||
{
|
||||
// Create an app-domain to load the resource assemblies in so that they can be
|
||||
// unloaded.
|
||||
|
||||
_domain = AppDomain.CreateDomain("ResourceIndirectDomain");
|
||||
_resourceRetriever =
|
||||
(ResourceRetriever)_domain.CreateInstanceAndUnwrap(
|
||||
Assembly.GetExecutingAssembly().FullName,
|
||||
"System.Management.Automation.ResourceRetriever");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a resource string based on a resource reference stored in the specified
|
||||
/// registry key.
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="key">
|
||||
/// The key in which there is a value that contains the reference to the resource
|
||||
/// to retrieve.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="valueName">
|
||||
/// The name of the value in the registry key that contains the reference to the resource.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="assemblyName">
|
||||
/// The full name of the assembly from which to load the resource.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="modulePath">
|
||||
/// The full path of the assembly from which to load the resource.
|
||||
/// </param>
|
||||
///
|
||||
/// <returns>
|
||||
/// The resource string that was loaded or null if it could not be found.
|
||||
/// </returns>
|
||||
///
|
||||
/// <remarks>
|
||||
/// This method ensures that an appropriate registry entry exists and that it contains
|
||||
/// a properly formatted resource reference ("BaseName,ResourceID"). It then creates an
|
||||
/// app-domain (or uses and existing one if it already exists on the instance of the class)
|
||||
/// and an instance of the ResourceRetriever in that app-domain. It then calls the ResourceRetriever
|
||||
/// to load the specified assembly and retrieve the resource. The assembly is loaded using ReflectionOnlyLoad
|
||||
/// or ReflectionOnlyLoadFrom using the assemblyName or moduleName (respectively) so that
|
||||
/// no code can be executed.
|
||||
///
|
||||
/// The app-domain is unloaded when this class instance is disposed.
|
||||
/// </remarks>
|
||||
///
|
||||
internal string GetResourceStringIndirect(
|
||||
RegistryKey key,
|
||||
string valueName,
|
||||
string assemblyName,
|
||||
string modulePath)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
throw PSTraceSource.NewInvalidOperationException(MshSnapinInfo.ResourceReaderDisposed);
|
||||
}
|
||||
|
||||
if (key == null)
|
||||
{
|
||||
throw PSTraceSource.NewArgumentNullException("key");
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(valueName))
|
||||
{
|
||||
throw PSTraceSource.NewArgumentException("valueName");
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(assemblyName))
|
||||
{
|
||||
throw PSTraceSource.NewArgumentException("assemblyName");
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(modulePath))
|
||||
{
|
||||
throw PSTraceSource.NewArgumentException("modulePath");
|
||||
}
|
||||
|
||||
string result = null;
|
||||
|
||||
do // false loop
|
||||
{
|
||||
// Read the resource reference from the registry
|
||||
string regValue = GetRegKeyValueAsString(key, valueName);
|
||||
|
||||
if (regValue == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
result = GetResourceStringIndirect(assemblyName, modulePath, regValue);
|
||||
} while (false);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a resource string based on a resource reference supplied in <paramref name="baseNameRIDPair"/>.
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="assemblyName">
|
||||
/// The full name of the assembly from which to load the resource.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="modulePath">
|
||||
/// The full path of the assembly from which to load the resource.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="baseNameRIDPair">
|
||||
/// A comma separated basename and resource id pair.
|
||||
/// </param>
|
||||
///
|
||||
/// <returns>
|
||||
/// The resource string that was loaded or null if it could not be found.
|
||||
/// </returns>
|
||||
///
|
||||
/// <remarks>
|
||||
/// This method ensures that <paramref name="baseNameRIDPair"/> is a properly formatted
|
||||
/// resource reference ("BaseName,ResourceID"). It then creates an app-domain (or uses
|
||||
/// an existing one if it already exists on the instance of the class) and an instance
|
||||
/// of the ResourceRetriever in that app-domain. It then calls the ResourceRetriever
|
||||
/// to load the specified assembly and retrieve the resource. The assembly is loaded using ReflectionOnlyLoad
|
||||
/// or ReflectionOnlyLoadFrom using the assemblyName or moduleName (respectively) so that
|
||||
/// no code can be executed.
|
||||
///
|
||||
/// The app-domain is unloaded when this class instance is disposed.
|
||||
/// </remarks>
|
||||
///
|
||||
internal string GetResourceStringIndirect(
|
||||
string assemblyName,
|
||||
string modulePath,
|
||||
string baseNameRIDPair)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
throw PSTraceSource.NewInvalidOperationException(MshSnapinInfo.ResourceReaderDisposed);
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(assemblyName))
|
||||
{
|
||||
throw PSTraceSource.NewArgumentException("assemblyName");
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(modulePath))
|
||||
{
|
||||
throw PSTraceSource.NewArgumentException("modulePath");
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(baseNameRIDPair))
|
||||
{
|
||||
throw PSTraceSource.NewArgumentException("baseNameRIDPair");
|
||||
}
|
||||
|
||||
string result = null;
|
||||
|
||||
do // false loop
|
||||
{
|
||||
// Initialize the app-domain and resource reader if not already initialized
|
||||
if (_resourceRetriever == null)
|
||||
{
|
||||
CreateAppDomain();
|
||||
}
|
||||
|
||||
// If the app-domain failed to load or the ResourceRetriever instance wasn't
|
||||
// created, then return null.
|
||||
|
||||
if (_resourceRetriever == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Parse the resource reference
|
||||
string[] resourceSplit = baseNameRIDPair.Split(Utils.Separators.Comma);
|
||||
if (resourceSplit.Length != 2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
string baseName = resourceSplit[0];
|
||||
string resourceID = resourceSplit[1];
|
||||
|
||||
// Get the resource in the app-domain
|
||||
result = _resourceRetriever.GetStringResource(assemblyName, modulePath, baseName, resourceID);
|
||||
} while (false);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a string value from the registry
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="key">
|
||||
/// The key to retrieve the value from.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="valueName">
|
||||
/// The name of the value to retrieve.
|
||||
/// </param>
|
||||
///
|
||||
/// <returns>
|
||||
/// The string value of the registry key value.
|
||||
/// </returns>
|
||||
///
|
||||
private static string GetRegKeyValueAsString(RegistryKey key, string valueName)
|
||||
{
|
||||
string result = null;
|
||||
try
|
||||
{
|
||||
// Check the type of the value
|
||||
RegistryValueKind kind = key.GetValueKind(valueName);
|
||||
if (kind == RegistryValueKind.String)
|
||||
{
|
||||
// Get the value since it is a string
|
||||
result = key.GetValue(valueName) as string;
|
||||
}
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
}
|
||||
catch (SecurityException)
|
||||
{
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This class is the worker class used by RegistryStringResourceIndirect to load the resource
|
||||
/// assemblies and retrieve the resources inside the alternate app-domain.
|
||||
/// </summary>
|
||||
///
|
||||
internal class ResourceRetriever : MarshalByRefObject
|
||||
{
|
||||
/// <summary>
|
||||
/// Loads the specified assembly in the app-domain and retrieves the specified resource string.
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="assemblyName">
|
||||
/// Full name of the assembly to retrieve the resource from.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="modulePath">
|
||||
/// Full path of the assembly to retrieve the resource from.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="baseName">
|
||||
/// The resource base name to retrieve.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="resourceID">
|
||||
/// The resource ID of the resource to retrieve.
|
||||
/// </param>
|
||||
///
|
||||
/// <returns>
|
||||
/// The value of the specified string resource or null if the resource could not be found or loaded.
|
||||
/// </returns>
|
||||
///
|
||||
internal string GetStringResource(string assemblyName, string modulePath, string baseName, string resourceID)
|
||||
{
|
||||
string result = null;
|
||||
|
||||
do // false loop
|
||||
{
|
||||
// Load the resource assembly
|
||||
Assembly assembly = LoadAssembly(assemblyName, modulePath);
|
||||
|
||||
if (assembly == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
CultureInfo currentCulture = System.Globalization.CultureInfo.CurrentUICulture;
|
||||
Stream stream = null;
|
||||
|
||||
// Get the resource stream from the manifest
|
||||
// Loop until we have reached the default culture (identified by an empty Name string in the
|
||||
// CultureInfo).
|
||||
do
|
||||
{
|
||||
string resourceStream = baseName;
|
||||
if (!String.IsNullOrEmpty(currentCulture.Name))
|
||||
resourceStream += "." + currentCulture.Name;
|
||||
resourceStream += ".resources";
|
||||
|
||||
stream = assembly.GetManifestResourceStream(resourceStream);
|
||||
|
||||
if (stream != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(currentCulture.Name))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
currentCulture = currentCulture.Parent;
|
||||
} while (true);
|
||||
|
||||
if (stream == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Retrieve the string resource from the stream.
|
||||
result = GetString(stream, resourceID);
|
||||
} while (false);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the specified assembly using ReflectionOnlyLoad or ReflectionOnlyLoadFrom
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="assemblyName">
|
||||
/// The FullName of the assembly to load. This takes precedence over the modulePath and
|
||||
/// will be passed to as a parameter to the ReflectionOnlyLoad.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="modulePath">
|
||||
/// The full path of the assembly to load. This is used if the ReflectionOnlyLoad using the
|
||||
/// assemblyName doesn't load the assembly. It is passed as a parameter to the ReflectionOnlyLoadFrom API.
|
||||
/// </param>
|
||||
///
|
||||
/// <returns>
|
||||
/// An loaded instance of the specified resource assembly or null if the assembly couldn't be loaded.
|
||||
/// </returns>
|
||||
///
|
||||
/// <remarks>
|
||||
/// Since the intent of this method is to load resource assemblies, the standard culture fallback rules
|
||||
/// apply. If the assembly couldn't be loaded for the current culture we fallback to the parent culture
|
||||
/// until the neutral culture is reached or an assembly is loaded.
|
||||
/// </remarks>
|
||||
///
|
||||
private static Assembly LoadAssembly(string assemblyName, string modulePath)
|
||||
{
|
||||
Assembly assembly = null;
|
||||
AssemblyName assemblyNameObj = new AssemblyName(assemblyName);
|
||||
|
||||
// Split the path up so we can add the culture directory.
|
||||
string moduleBase = Path.GetDirectoryName(modulePath);
|
||||
string moduleFile = Path.GetFileName(modulePath);
|
||||
|
||||
CultureInfo currentCulture = System.Globalization.CultureInfo.CurrentUICulture;
|
||||
|
||||
// Loop until we have reached the default culture (identified by an empty Name string in the
|
||||
// CultureInfo).
|
||||
do
|
||||
{
|
||||
assembly = LoadAssemblyForCulture(currentCulture, assemblyNameObj, moduleBase, moduleFile);
|
||||
|
||||
if (assembly != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(currentCulture.Name))
|
||||
{
|
||||
break;
|
||||
}
|
||||
currentCulture = currentCulture.Parent;
|
||||
} while (true);
|
||||
|
||||
|
||||
return assembly;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to load the assembly for the specified culture
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="culture">
|
||||
/// The culture for which the assembly should be loaded.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="assemblyName">
|
||||
/// The name of the assembly without culture information (or at least undefined culture information).
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="moduleBase">
|
||||
/// The directory containing the neutral culture assembly.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="moduleFile">
|
||||
/// The name of the assembly file.
|
||||
/// </param>
|
||||
///
|
||||
/// <returns>
|
||||
/// An instance of the loaded resource assembly or null if the assembly could not be loaded.
|
||||
/// </returns>
|
||||
///
|
||||
private static Assembly LoadAssemblyForCulture(
|
||||
CultureInfo culture,
|
||||
AssemblyName assemblyName,
|
||||
string moduleBase,
|
||||
string moduleFile)
|
||||
{
|
||||
Assembly assembly = null;
|
||||
|
||||
// Set the assembly FullName to contain the culture we are trying to load.
|
||||
assemblyName.CultureInfo = culture;
|
||||
|
||||
try
|
||||
{
|
||||
assembly = Assembly.ReflectionOnlyLoad(assemblyName.FullName);
|
||||
}
|
||||
catch (FileLoadException)
|
||||
{
|
||||
}
|
||||
catch (BadImageFormatException)
|
||||
{
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
}
|
||||
|
||||
if (assembly != null)
|
||||
return assembly;
|
||||
|
||||
// Try the resources DLL
|
||||
string oldAssemblyName = assemblyName.Name;
|
||||
try
|
||||
{
|
||||
assemblyName.Name = oldAssemblyName + ".resources";
|
||||
assembly = Assembly.ReflectionOnlyLoad(assemblyName.FullName);
|
||||
}
|
||||
catch (FileLoadException)
|
||||
{
|
||||
}
|
||||
catch (BadImageFormatException)
|
||||
{
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
}
|
||||
|
||||
if (assembly != null)
|
||||
return assembly;
|
||||
|
||||
assemblyName.Name = oldAssemblyName;
|
||||
|
||||
// Add the culture directory into the file path
|
||||
string modulePath = Path.Combine(moduleBase, culture.Name);
|
||||
modulePath = Path.Combine(modulePath, moduleFile);
|
||||
|
||||
if (File.Exists(modulePath))
|
||||
{
|
||||
try
|
||||
{
|
||||
assembly = Assembly.ReflectionOnlyLoadFrom(modulePath);
|
||||
}
|
||||
catch (FileLoadException)
|
||||
{
|
||||
}
|
||||
catch (BadImageFormatException)
|
||||
{
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
}
|
||||
}
|
||||
return assembly;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the specified resource string from the resource stream.
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="stream">
|
||||
/// The resource stream containing the desired resource.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="resourceID">
|
||||
/// The identifier of the string resource to retrieve from the stream.
|
||||
/// </param>
|
||||
///
|
||||
/// <returns>
|
||||
/// The resource string or null if the resourceID could not be found.
|
||||
/// </returns>
|
||||
///
|
||||
private static string GetString(Stream stream, string resourceID)
|
||||
{
|
||||
string result = null;
|
||||
|
||||
ResourceReader rr = new ResourceReader(stream);
|
||||
|
||||
foreach (DictionaryEntry e in rr)
|
||||
{
|
||||
if (String.Equals(resourceID, (string)e.Key, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
result = (string)e.Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* NTRAID#Windows Out Of Band Releases-920971-2005/09/30-JeffJon
|
||||
* Whidbey v2.0.50727 has a bug where GetResourceData throws an NullReferenceException if
|
||||
* the assembly used to get the ResourceReader was loaded with ReflectionOnlyLoad. This code
|
||||
* would be more efficient than the iteration in the foreach loop above and should be enabled
|
||||
* when we move to the RTM version of Whidbey.
|
||||
*
|
||||
string resourceType = null;
|
||||
byte[] resourceData = null;
|
||||
rr.GetResourceData(resourceID, out resourceType, out resourceData);
|
||||
*/
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,754 +0,0 @@
|
||||
/********************************************************************++
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Xml;
|
||||
using System.Reflection;
|
||||
using System.Management.Automation.Internal;
|
||||
|
||||
namespace System.Management.Automation.Runspaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Runspace config for single shell are a special kind of runspace
|
||||
/// configuration that is generated for single shells.
|
||||
///
|
||||
/// This class needs to handle the standard management of
|
||||
///
|
||||
/// 1. consoleInfo: each instance of this class will have
|
||||
/// a consoleInfo object.
|
||||
/// 2. interface to consoleInfo. This includes "open",
|
||||
/// "save", and "change" of consoleInfo and console files.
|
||||
/// 3. interface to mshsnapin's. This includes add, remove
|
||||
/// and list mshsnapins in console file.
|
||||
///
|
||||
/// This class derives from RunspaceConfiguration and supports
|
||||
/// basic information for cmdlets, providers, types, formats,
|
||||
/// etc.
|
||||
///
|
||||
/// Eventually when minishell model goes away, RunspaceConfiguration
|
||||
/// and RunspaceConfigForSingleShell may merge into one class.
|
||||
///
|
||||
/// </summary>
|
||||
internal class RunspaceConfigForSingleShell : RunspaceConfiguration
|
||||
{
|
||||
#region RunspaceConfigForSingleShell Factory
|
||||
|
||||
/// <exception cref="PSSnapInException">
|
||||
/// One or more default mshsnapins cannot be loaded because the
|
||||
/// registry is not populated correctly.
|
||||
/// </exception>
|
||||
/// <exception cref="PSArgumentNullException">
|
||||
/// fileName is null.
|
||||
/// </exception>
|
||||
/// <exception cref="PSArgumentException">
|
||||
/// fileName does not specify proper file extension.
|
||||
/// </exception>
|
||||
/// <exception cref="XmlException">
|
||||
/// Unable to load/parse the file specified by fileName.
|
||||
/// </exception>
|
||||
internal new static RunspaceConfigForSingleShell Create(string consoleFile, out PSConsoleLoadException warning)
|
||||
{
|
||||
PSConsoleLoadException warning1 = null;
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Creating MshConsoleInfo. consoleFile={0}", consoleFile);
|
||||
|
||||
MshConsoleInfo consoleInfo = MshConsoleInfo.CreateFromConsoleFile(consoleFile, out warning1);
|
||||
|
||||
if (warning1 != null)
|
||||
{
|
||||
s_mshsnapinTracer.TraceWarning("There was a warning while creating MshConsoleInfo: {0}", warning1.Message);
|
||||
}
|
||||
|
||||
// At this time, consoleInfo should not be null.
|
||||
// Otherwise, an exception should have been thrown up.
|
||||
if (consoleInfo != null)
|
||||
{
|
||||
RunspaceConfigForSingleShell rspcfg = new RunspaceConfigForSingleShell(consoleInfo);
|
||||
PSConsoleLoadException warning2 = null;
|
||||
|
||||
rspcfg.LoadConsole(out warning2);
|
||||
|
||||
if (warning2 != null)
|
||||
{
|
||||
s_mshsnapinTracer.TraceWarning("There was a warning while loading console: {0}", warning2.Message);
|
||||
}
|
||||
|
||||
warning = CombinePSConsoleLoadException(warning1, warning2);
|
||||
|
||||
return rspcfg;
|
||||
}
|
||||
|
||||
warning = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
private static PSConsoleLoadException CombinePSConsoleLoadException(PSConsoleLoadException e1, PSConsoleLoadException e2)
|
||||
{
|
||||
if ((e1 == null || e1.PSSnapInExceptions.Count == 0) && (e2 == null || e2.PSSnapInExceptions.Count == 0))
|
||||
return null;
|
||||
|
||||
if (e1 == null || e1.PSSnapInExceptions.Count == 0)
|
||||
return e2;
|
||||
|
||||
if (e2 == null || e2.PSSnapInExceptions.Count == 0)
|
||||
return e1;
|
||||
|
||||
foreach (PSSnapInException sile in e2.PSSnapInExceptions)
|
||||
{
|
||||
e1.PSSnapInExceptions.Add(sile);
|
||||
}
|
||||
|
||||
return e1;
|
||||
}
|
||||
|
||||
|
||||
/// <exception cref="PSSnapInException">
|
||||
/// One or more default mshsnapins cannot be loaded because the
|
||||
/// registry is not populated correctly.
|
||||
/// </exception>
|
||||
internal static RunspaceConfigForSingleShell CreateDefaultConfiguration()
|
||||
{
|
||||
s_mshsnapinTracer.WriteLine("Creating default runspace configuration.");
|
||||
|
||||
MshConsoleInfo consoleInfo = MshConsoleInfo.CreateDefaultConfiguration();
|
||||
|
||||
// This should not happen. If there is a failure in creating consoleInfo,
|
||||
// an exception should have been thrown up.
|
||||
if (consoleInfo != null)
|
||||
{
|
||||
RunspaceConfigForSingleShell rspcfg = new RunspaceConfigForSingleShell(consoleInfo);
|
||||
PSConsoleLoadException warning = null;
|
||||
|
||||
rspcfg.LoadConsole(out warning);
|
||||
|
||||
if (warning != null)
|
||||
{
|
||||
s_mshsnapinTracer.TraceWarning("There was a warning while loading console: {0}", warning.Message);
|
||||
}
|
||||
|
||||
return rspcfg;
|
||||
}
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Default runspace configuration created.");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private RunspaceConfigForSingleShell(MshConsoleInfo consoleInfo)
|
||||
{
|
||||
_consoleInfo = consoleInfo;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Console/MshSnapin Manipulation
|
||||
|
||||
private MshConsoleInfo _consoleInfo = null;
|
||||
internal MshConsoleInfo ConsoleInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return _consoleInfo;
|
||||
}
|
||||
}
|
||||
|
||||
internal void SaveConsoleFile()
|
||||
{
|
||||
if (_consoleInfo == null)
|
||||
return;
|
||||
|
||||
_consoleInfo.Save();
|
||||
}
|
||||
|
||||
internal void SaveAsConsoleFile(string filename)
|
||||
{
|
||||
if (_consoleInfo == null)
|
||||
return;
|
||||
|
||||
_consoleInfo.SaveAsConsoleFile(filename);
|
||||
}
|
||||
|
||||
/// <exception cref="PSArgumentNullException">
|
||||
/// mshSnapInID is empty or null.
|
||||
/// </exception>
|
||||
/// <exception cref="PSArgumentException">
|
||||
/// PSSnapIn is already loaded.
|
||||
/// No PSSnapIn with given id found.
|
||||
/// PSSnapIn cannot be loaded.
|
||||
/// </exception>
|
||||
/// <exception cref="System.Security.SecurityException">
|
||||
/// Caller doesn't have permission to read keys.
|
||||
/// </exception>
|
||||
internal override PSSnapInInfo DoAddPSSnapIn(string name, out PSSnapInException warning)
|
||||
{
|
||||
warning = null;
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Adding mshsnapin {0}", name);
|
||||
|
||||
if (_consoleInfo == null)
|
||||
return null;
|
||||
|
||||
PSSnapInInfo mshsnapinInfo = null;
|
||||
|
||||
try
|
||||
{
|
||||
mshsnapinInfo = _consoleInfo.AddPSSnapIn(name);
|
||||
}
|
||||
catch (PSArgumentException mae)
|
||||
{
|
||||
s_mshsnapinTracer.TraceError(mae.Message);
|
||||
s_mshsnapinTracer.WriteLine("Adding mshsnapin {0} failed.", name);
|
||||
throw;
|
||||
}
|
||||
catch (PSArgumentNullException mane)
|
||||
{
|
||||
s_mshsnapinTracer.TraceError(mane.Message);
|
||||
s_mshsnapinTracer.WriteLine("Adding mshsnapin {0} failed.", name);
|
||||
throw;
|
||||
}
|
||||
|
||||
if (mshsnapinInfo == null)
|
||||
return null;
|
||||
|
||||
LoadPSSnapIn(mshsnapinInfo, out warning);
|
||||
|
||||
if (warning != null)
|
||||
{
|
||||
s_mshsnapinTracer.TraceWarning("There was a warning when loading mshsnapin {0}: {1}", name, warning.Message);
|
||||
}
|
||||
|
||||
s_mshsnapinTracer.WriteLine("MshSnapin {0} added", name);
|
||||
|
||||
return mshsnapinInfo;
|
||||
}
|
||||
|
||||
/// <exception cref="PSArgumentNullException">
|
||||
/// mshSnapInID is null.
|
||||
/// </exception>
|
||||
/// <exception cref="PSArgumentException">
|
||||
/// mshSnapInID is either a default mshsnapin or not loaded.
|
||||
/// </exception>
|
||||
internal override PSSnapInInfo DoRemovePSSnapIn(string name, out PSSnapInException warning)
|
||||
{
|
||||
warning = null;
|
||||
|
||||
if (_consoleInfo == null)
|
||||
return null;
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Removing mshsnapin {0}", name);
|
||||
|
||||
PSSnapInInfo mshsnapinInfo = _consoleInfo.RemovePSSnapIn(name);
|
||||
|
||||
UnloadPSSnapIn(mshsnapinInfo, out warning);
|
||||
|
||||
s_mshsnapinTracer.WriteLine("MshSnapin {0} removed", name);
|
||||
|
||||
return mshsnapinInfo;
|
||||
}
|
||||
|
||||
internal void UpdateAll()
|
||||
{
|
||||
string errors = "";
|
||||
|
||||
UpdateAll(out errors);
|
||||
}
|
||||
|
||||
|
||||
internal void UpdateAll(out string errors)
|
||||
{
|
||||
errors = "";
|
||||
|
||||
this.Cmdlets.Update();
|
||||
this.Providers.Update();
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Updating types and formats");
|
||||
|
||||
try
|
||||
{
|
||||
this.Types.Update();
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
s_mshsnapinTracer.TraceWarning("There was a warning updating types: {0}", e.Message);
|
||||
|
||||
errors += e.Message + "\n";
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.Formats.Update();
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
s_mshsnapinTracer.TraceWarning("There was a warning updating formats: {0}", e.Message);
|
||||
|
||||
errors += e.Message + "\n";
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.Assemblies.Update();
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
s_mshsnapinTracer.TraceWarning("There was a warning updating assemblies: {0}", e.Message);
|
||||
|
||||
errors += e.Message + "\n";
|
||||
}
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Types and formats updated successfully");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Load Console/MshSnapin's
|
||||
|
||||
private void LoadConsole(out PSConsoleLoadException warning)
|
||||
{
|
||||
if (_consoleInfo == null)
|
||||
{
|
||||
warning = null;
|
||||
return;
|
||||
}
|
||||
|
||||
LoadPSSnapIns(_consoleInfo.PSSnapIns, out warning);
|
||||
}
|
||||
|
||||
private void LoadPSSnapIn(PSSnapInInfo mshsnapinInfo, out PSSnapInException warning)
|
||||
{
|
||||
warning = null;
|
||||
|
||||
try
|
||||
{
|
||||
LoadPSSnapIn(mshsnapinInfo);
|
||||
}
|
||||
catch (PSSnapInException)
|
||||
{
|
||||
if (!mshsnapinInfo.IsDefault)
|
||||
_consoleInfo.RemovePSSnapIn(mshsnapinInfo.Name);
|
||||
|
||||
// exception during load mshsnapin are fatal.
|
||||
throw;
|
||||
}
|
||||
|
||||
string errors;
|
||||
|
||||
UpdateAll(out errors);
|
||||
|
||||
if (!String.IsNullOrEmpty(errors))
|
||||
{
|
||||
s_mshsnapinTracer.TraceWarning("There was a warning while loading mshsnapin {0}:{1}", mshsnapinInfo.Name, errors);
|
||||
|
||||
warning = new PSSnapInException(mshsnapinInfo.Name, errors, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadPSSnapIns(Collection<PSSnapInInfo> mshsnapinInfos, out PSConsoleLoadException warning)
|
||||
{
|
||||
warning = null;
|
||||
|
||||
Collection<PSSnapInException> mshsnapinExceptions = new Collection<PSSnapInException>();
|
||||
|
||||
bool partialSuccess = false;
|
||||
|
||||
foreach (PSSnapInInfo mshsnapinInfo in mshsnapinInfos)
|
||||
{
|
||||
try
|
||||
{
|
||||
LoadPSSnapIn(mshsnapinInfo);
|
||||
partialSuccess = true;
|
||||
}
|
||||
catch (PSSnapInException e)
|
||||
{
|
||||
if (!mshsnapinInfo.IsDefault)
|
||||
{
|
||||
_consoleInfo.RemovePSSnapIn(mshsnapinInfo.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
mshsnapinExceptions.Add(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (partialSuccess)
|
||||
{
|
||||
string errors;
|
||||
UpdateAll(out errors);
|
||||
|
||||
if (!String.IsNullOrEmpty(errors))
|
||||
{
|
||||
s_mshsnapinTracer.TraceWarning(errors);
|
||||
mshsnapinExceptions.Add(new PSSnapInException(null, errors, true));
|
||||
}
|
||||
}
|
||||
|
||||
if (mshsnapinExceptions.Count > 0)
|
||||
{
|
||||
warning = new PSConsoleLoadException(_consoleInfo, mshsnapinExceptions);
|
||||
s_mshsnapinTracer.TraceWarning(warning.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadPSSnapIn(PSSnapInInfo mshsnapinInfo)
|
||||
{
|
||||
if (mshsnapinInfo == null)
|
||||
return;
|
||||
|
||||
#if !CORECLR // CustomPSSnapIn Not Supported On CSS.
|
||||
if (!String.IsNullOrEmpty(mshsnapinInfo.CustomPSSnapInType))
|
||||
{
|
||||
LoadCustomPSSnapIn(mshsnapinInfo);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
Assembly assembly = null;
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Loading assembly for mshsnapin {0}", mshsnapinInfo.Name);
|
||||
|
||||
assembly = LoadMshSnapinAssembly(mshsnapinInfo);
|
||||
|
||||
if (assembly == null)
|
||||
{
|
||||
s_mshsnapinTracer.TraceError("Loading assembly for mshsnapin {0} failed", mshsnapinInfo.Name);
|
||||
return;
|
||||
}
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Loading assembly for mshsnapin {0} succeeded", mshsnapinInfo.Name);
|
||||
|
||||
Dictionary<string, SessionStateCmdletEntry> cmdlets = null;
|
||||
Dictionary<string, List<SessionStateAliasEntry>> aliases = null;
|
||||
Dictionary<string, SessionStateProviderEntry> providers = null;
|
||||
string throwAwayHelpFile = null;
|
||||
PSSnapInHelpers.AnalyzePSSnapInAssembly(assembly, assembly.Location, mshsnapinInfo, null, false, out cmdlets, out aliases, out providers, out throwAwayHelpFile);
|
||||
if (cmdlets != null)
|
||||
{
|
||||
foreach (var c in cmdlets)
|
||||
{
|
||||
CmdletConfigurationEntry cmdlet = new CmdletConfigurationEntry(c.Key, c.Value.ImplementingType,
|
||||
c.Value.HelpFileName, mshsnapinInfo);
|
||||
_cmdlets.AddBuiltInItem(cmdlet);
|
||||
}
|
||||
}
|
||||
if (providers != null)
|
||||
{
|
||||
foreach (var p in providers)
|
||||
{
|
||||
ProviderConfigurationEntry provider = new ProviderConfigurationEntry(p.Key, p.Value.ImplementingType,
|
||||
p.Value.HelpFileName,
|
||||
mshsnapinInfo);
|
||||
_providers.AddBuiltInItem(provider);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string file in mshsnapinInfo.Types)
|
||||
{
|
||||
string path = Path.Combine(mshsnapinInfo.ApplicationBase, file);
|
||||
|
||||
TypeConfigurationEntry typeEntry = new TypeConfigurationEntry(path, path, mshsnapinInfo);
|
||||
this.Types.AddBuiltInItem(typeEntry);
|
||||
}
|
||||
|
||||
foreach (string file in mshsnapinInfo.Formats)
|
||||
{
|
||||
string path = Path.Combine(mshsnapinInfo.ApplicationBase, file);
|
||||
|
||||
FormatConfigurationEntry formatEntry = new FormatConfigurationEntry(path, path, mshsnapinInfo);
|
||||
this.Formats.AddBuiltInItem(formatEntry);
|
||||
}
|
||||
|
||||
AssemblyConfigurationEntry assemblyEntry = new AssemblyConfigurationEntry(mshsnapinInfo.AssemblyName, mshsnapinInfo.AbsoluteModulePath, mshsnapinInfo);
|
||||
this.Assemblies.AddBuiltInItem(assemblyEntry);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#if !CORECLR // CustomPSSnapIn Not Supported On CSS.
|
||||
|
||||
private void LoadCustomPSSnapIn(PSSnapInInfo mshsnapinInfo)
|
||||
{
|
||||
if (mshsnapinInfo == null)
|
||||
return;
|
||||
|
||||
if (String.IsNullOrEmpty(mshsnapinInfo.CustomPSSnapInType))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Assembly assembly = null;
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Loading assembly for mshsnapin {0}", mshsnapinInfo.Name);
|
||||
|
||||
assembly = LoadMshSnapinAssembly(mshsnapinInfo);
|
||||
|
||||
if (assembly == null)
|
||||
{
|
||||
s_mshsnapinTracer.TraceError("Loading assembly for mshsnapin {0} failed", mshsnapinInfo.Name);
|
||||
return;
|
||||
}
|
||||
|
||||
CustomPSSnapIn customPSSnapIn = null;
|
||||
try
|
||||
{
|
||||
Type type = assembly.GetType(mshsnapinInfo.CustomPSSnapInType, true, false);
|
||||
|
||||
if (type != null)
|
||||
{
|
||||
customPSSnapIn = (CustomPSSnapIn)Activator.CreateInstance(type);
|
||||
}
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Loading assembly for mshsnapin {0} succeeded", mshsnapinInfo.Name);
|
||||
}
|
||||
catch (TypeLoadException tle)
|
||||
{
|
||||
throw new PSSnapInException(mshsnapinInfo.Name, tle.Message);
|
||||
}
|
||||
catch (ArgumentException ae)
|
||||
{
|
||||
throw new PSSnapInException(mshsnapinInfo.Name, ae.Message);
|
||||
}
|
||||
catch (MissingMethodException mme)
|
||||
{
|
||||
throw new PSSnapInException(mshsnapinInfo.Name, mme.Message);
|
||||
}
|
||||
catch (InvalidCastException ice)
|
||||
{
|
||||
throw new PSSnapInException(mshsnapinInfo.Name, ice.Message);
|
||||
}
|
||||
catch (TargetInvocationException tie)
|
||||
{
|
||||
if (tie.InnerException != null)
|
||||
{
|
||||
throw new PSSnapInException(mshsnapinInfo.Name, tie.InnerException.Message);
|
||||
}
|
||||
|
||||
throw new PSSnapInException(mshsnapinInfo.Name, tie.Message);
|
||||
}
|
||||
|
||||
MergeCustomPSSnapIn(mshsnapinInfo, customPSSnapIn);
|
||||
return;
|
||||
}
|
||||
|
||||
private void MergeCustomPSSnapIn(PSSnapInInfo mshsnapinInfo, CustomPSSnapIn customPSSnapIn)
|
||||
{
|
||||
if (mshsnapinInfo == null || customPSSnapIn == null)
|
||||
return;
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Merging configuration from custom mshsnapin {0}", mshsnapinInfo.Name);
|
||||
|
||||
if (customPSSnapIn.Cmdlets != null)
|
||||
{
|
||||
foreach (CmdletConfigurationEntry entry in customPSSnapIn.Cmdlets)
|
||||
{
|
||||
CmdletConfigurationEntry cmdlet = new CmdletConfigurationEntry(entry.Name, entry.ImplementingType, entry.HelpFileName, mshsnapinInfo);
|
||||
_cmdlets.AddBuiltInItem(cmdlet);
|
||||
}
|
||||
}
|
||||
|
||||
if (customPSSnapIn.Providers != null)
|
||||
{
|
||||
foreach (ProviderConfigurationEntry entry in customPSSnapIn.Providers)
|
||||
{
|
||||
ProviderConfigurationEntry provider = new ProviderConfigurationEntry(entry.Name, entry.ImplementingType, entry.HelpFileName, mshsnapinInfo);
|
||||
_providers.AddBuiltInItem(provider);
|
||||
}
|
||||
}
|
||||
|
||||
if (customPSSnapIn.Types != null)
|
||||
{
|
||||
foreach (TypeConfigurationEntry entry in customPSSnapIn.Types)
|
||||
{
|
||||
string path = Path.Combine(mshsnapinInfo.ApplicationBase, entry.FileName);
|
||||
TypeConfigurationEntry type = new TypeConfigurationEntry(entry.Name, path, mshsnapinInfo);
|
||||
_types.AddBuiltInItem(type);
|
||||
}
|
||||
}
|
||||
|
||||
if (customPSSnapIn.Formats != null)
|
||||
{
|
||||
foreach (FormatConfigurationEntry entry in customPSSnapIn.Formats)
|
||||
{
|
||||
string path = Path.Combine(mshsnapinInfo.ApplicationBase, entry.FileName);
|
||||
FormatConfigurationEntry format = new FormatConfigurationEntry(entry.Name, path, mshsnapinInfo);
|
||||
_formats.AddBuiltInItem(format);
|
||||
}
|
||||
}
|
||||
|
||||
AssemblyConfigurationEntry assemblyEntry = new AssemblyConfigurationEntry(mshsnapinInfo.AssemblyName, mshsnapinInfo.AbsoluteModulePath, mshsnapinInfo);
|
||||
this.Assemblies.AddBuiltInItem(assemblyEntry);
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Configuration from custom mshsnapin {0} merged", mshsnapinInfo.Name);
|
||||
}
|
||||
#endif
|
||||
|
||||
private void UnloadPSSnapIn(PSSnapInInfo mshsnapinInfo, out PSSnapInException warning)
|
||||
{
|
||||
warning = null;
|
||||
|
||||
if (mshsnapinInfo != null)
|
||||
{
|
||||
this.Cmdlets.RemovePSSnapIn(mshsnapinInfo.Name);
|
||||
this.Providers.RemovePSSnapIn(mshsnapinInfo.Name);
|
||||
this.Assemblies.RemovePSSnapIn(mshsnapinInfo.Name);
|
||||
this.Types.RemovePSSnapIn(mshsnapinInfo.Name);
|
||||
this.Formats.RemovePSSnapIn(mshsnapinInfo.Name);
|
||||
|
||||
string errors;
|
||||
UpdateAll(out errors);
|
||||
|
||||
if (!String.IsNullOrEmpty(errors))
|
||||
{
|
||||
s_mshsnapinTracer.TraceWarning(errors);
|
||||
warning = new PSSnapInException(mshsnapinInfo.Name, errors, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Assembly LoadMshSnapinAssembly(PSSnapInInfo mshsnapinInfo)
|
||||
{
|
||||
Assembly assembly = null;
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Loading assembly from GAC. Assembly Name: {0}", mshsnapinInfo.AssemblyName);
|
||||
|
||||
try
|
||||
{
|
||||
// WARNING: DUPLICATE CODE see InitialSessionState
|
||||
assembly = Assembly.Load(new AssemblyName(mshsnapinInfo.AssemblyName));
|
||||
}
|
||||
catch (FileLoadException e)
|
||||
{
|
||||
s_mshsnapinTracer.TraceWarning("Not able to load assembly {0}: {1}", mshsnapinInfo.AssemblyName, e.Message);
|
||||
}
|
||||
catch (BadImageFormatException e)
|
||||
{
|
||||
s_mshsnapinTracer.TraceWarning("Not able to load assembly {0}: {1}", mshsnapinInfo.AssemblyName, e.Message);
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
s_mshsnapinTracer.TraceWarning("Not able to load assembly {0}: {1}", mshsnapinInfo.AssemblyName, e.Message);
|
||||
}
|
||||
|
||||
if (assembly != null)
|
||||
return assembly;
|
||||
|
||||
s_mshsnapinTracer.WriteLine("Loading assembly from path: {0}", mshsnapinInfo.AssemblyName);
|
||||
|
||||
try
|
||||
{
|
||||
AssemblyName assemblyName = AssemblyName.GetAssemblyName(mshsnapinInfo.AbsoluteModulePath);
|
||||
if (string.Compare(assemblyName.FullName, mshsnapinInfo.AssemblyName, StringComparison.OrdinalIgnoreCase) != 0)
|
||||
{
|
||||
string message = StringUtil.Format(ConsoleInfoErrorStrings.PSSnapInAssemblyNameMismatch, mshsnapinInfo.AbsoluteModulePath, mshsnapinInfo.AssemblyName);
|
||||
s_mshsnapinTracer.TraceError(message);
|
||||
throw new PSSnapInException(mshsnapinInfo.Name, message);
|
||||
}
|
||||
|
||||
assembly = Assembly.LoadFrom(mshsnapinInfo.AbsoluteModulePath);
|
||||
}
|
||||
catch (FileLoadException e)
|
||||
{
|
||||
s_mshsnapinTracer.TraceError("Not able to load assembly {0}: {1}", mshsnapinInfo.AssemblyName, e.Message);
|
||||
throw new PSSnapInException(mshsnapinInfo.Name, e.Message);
|
||||
}
|
||||
catch (BadImageFormatException e)
|
||||
{
|
||||
s_mshsnapinTracer.TraceError("Not able to load assembly {0}: {1}", mshsnapinInfo.AssemblyName, e.Message);
|
||||
throw new PSSnapInException(mshsnapinInfo.Name, e.Message);
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
s_mshsnapinTracer.TraceError("Not able to load assembly {0}: {1}", mshsnapinInfo.AssemblyName, e.Message);
|
||||
throw new PSSnapInException(mshsnapinInfo.Name, e.Message);
|
||||
}
|
||||
|
||||
return assembly;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region RunspaceConfiguration Api implementation
|
||||
|
||||
/// <summary>
|
||||
/// Gets the shell id for current runspace configuration.
|
||||
/// </summary>
|
||||
///
|
||||
public override string ShellId
|
||||
{
|
||||
get
|
||||
{
|
||||
return Utils.DefaultPowerShellShellID;
|
||||
}
|
||||
}
|
||||
|
||||
private RunspaceConfigurationEntryCollection<CmdletConfigurationEntry> _cmdlets =
|
||||
new RunspaceConfigurationEntryCollection<CmdletConfigurationEntry>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cmdlets defined in runspace configuration.
|
||||
/// </summary>
|
||||
public override RunspaceConfigurationEntryCollection<CmdletConfigurationEntry> Cmdlets
|
||||
{
|
||||
get
|
||||
{
|
||||
return _cmdlets;
|
||||
}
|
||||
}
|
||||
|
||||
private RunspaceConfigurationEntryCollection<ProviderConfigurationEntry> _providers = new RunspaceConfigurationEntryCollection<ProviderConfigurationEntry>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the providers defined in runspace configuration.
|
||||
/// </summary>
|
||||
public override RunspaceConfigurationEntryCollection<ProviderConfigurationEntry> Providers
|
||||
{
|
||||
get
|
||||
{
|
||||
return _providers;
|
||||
}
|
||||
}
|
||||
|
||||
private RunspaceConfigurationEntryCollection<TypeConfigurationEntry> _types;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type data files defined in runspace configuration.
|
||||
/// </summary>
|
||||
public override RunspaceConfigurationEntryCollection<TypeConfigurationEntry> Types
|
||||
{
|
||||
get { return _types ?? (_types = new RunspaceConfigurationEntryCollection<TypeConfigurationEntry>()); }
|
||||
}
|
||||
|
||||
private RunspaceConfigurationEntryCollection<FormatConfigurationEntry> _formats;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the format data files defined in runspace configuration.
|
||||
/// </summary>
|
||||
public override RunspaceConfigurationEntryCollection<FormatConfigurationEntry> Formats
|
||||
{
|
||||
get {
|
||||
return _formats ?? (_formats = new RunspaceConfigurationEntryCollection<FormatConfigurationEntry>());
|
||||
}
|
||||
}
|
||||
|
||||
private RunspaceConfigurationEntryCollection<ScriptConfigurationEntry> _initializationScripts;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the initialization scripts defined in runspace configuration.
|
||||
/// </summary>
|
||||
public override RunspaceConfigurationEntryCollection<ScriptConfigurationEntry> InitializationScripts
|
||||
{
|
||||
get {
|
||||
return _initializationScripts ??
|
||||
(_initializationScripts = new RunspaceConfigurationEntryCollection<ScriptConfigurationEntry>());
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private static PSTraceSource s_mshsnapinTracer = PSTraceSource.GetTracer("MshSnapinLoadUnload", "Loading and unloading mshsnapins", false);
|
||||
}
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
/********************************************************************++
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using Microsoft.Win32;
|
||||
using System.IO;
|
||||
using System.Management.Automation.Runspaces;
|
||||
|
||||
namespace System.Management.Automation
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// Raw mshsnapin is a class for allowing mshsnapin developers to directly
|
||||
/// specify the set of cmdlets, providers, types, formats, assemblies
|
||||
/// available in the mshsnapin.
|
||||
///
|
||||
/// To use this class, mshsnapin developers will drive from it and fill
|
||||
/// in details about cmdlet, provider, type, format, assemblies.
|
||||
///
|
||||
/// This class will also facilitate the registration of the mshsnapin
|
||||
/// through installutil.exe.
|
||||
///
|
||||
/// This class will be built with monad core engine dll.
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// Developers should derive from this class to implement their own
|
||||
/// custom mshsnapins.
|
||||
///
|
||||
/// Derived mshsnapins should be denoted with [RunInstaller] attribute
|
||||
/// so that installutil.exe can directly install the mshsnapin into registry.
|
||||
/// </remarks>
|
||||
public abstract class CustomPSSnapIn : PSSnapInInstaller
|
||||
{
|
||||
internal string CustomPSSnapInType
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.GetType().FullName;
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<CmdletConfigurationEntry> _cmdlets;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cmdlets defined in custom mshsnapin.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This member can be derived to provide the list of cmdlets to be included for this mshsnapin.
|
||||
/// </remarks>
|
||||
public virtual Collection<CmdletConfigurationEntry> Cmdlets
|
||||
{
|
||||
get { return _cmdlets ?? (_cmdlets = new Collection<CmdletConfigurationEntry>()); }
|
||||
}
|
||||
|
||||
private Collection<ProviderConfigurationEntry> _providers;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the providers defined in custom mshsnapin.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This member can be derived to provide the list of providers to be included for this mshsnapin.
|
||||
/// </remarks>
|
||||
public virtual Collection<ProviderConfigurationEntry> Providers
|
||||
{
|
||||
get { return _providers ?? (_providers = new Collection<ProviderConfigurationEntry>()); }
|
||||
}
|
||||
|
||||
private Collection<TypeConfigurationEntry> _types;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the types defined in custom mshsnapin.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This member can be derived to provide the list of types to be included for this mshsnapin.
|
||||
/// </remarks>
|
||||
public virtual Collection<TypeConfigurationEntry> Types
|
||||
{
|
||||
get { return _types ?? (_types = new Collection<TypeConfigurationEntry>()); }
|
||||
}
|
||||
|
||||
private Collection<FormatConfigurationEntry> _formats;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the formatsdefined in raw mshsnapin.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This member can be derived to provide the list of formats to be included for this mshsnapin.
|
||||
/// </remarks>
|
||||
public virtual Collection<FormatConfigurationEntry> Formats
|
||||
{
|
||||
get { return _formats ?? (_formats = new Collection<FormatConfigurationEntry>()); }
|
||||
}
|
||||
|
||||
private Dictionary<String, object> _regValues = null;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal override Dictionary<String, object> RegValues
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_regValues == null)
|
||||
{
|
||||
_regValues = base.RegValues;
|
||||
|
||||
if (!String.IsNullOrEmpty(this.CustomPSSnapInType))
|
||||
_regValues[RegistryStrings.MshSnapin_CustomPSSnapInType] = this.CustomPSSnapInType;
|
||||
}
|
||||
|
||||
return _regValues;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/********************************************************************++
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Configuration.Install;
|
||||
using System.Reflection;
|
||||
using Microsoft.Win32;
|
||||
using System.IO;
|
||||
using System.Management.Automation;
|
||||
|
||||
namespace Microsoft.PowerShell
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// MshCoreMshSnapin (or MshCoreMshSnapinInstaller) is a class for facilitating registry
|
||||
/// of necessary information for monad core mshsnapin.
|
||||
///
|
||||
/// This class will be built with monad core engine dll
|
||||
/// (System.Management.Automation.dll).
|
||||
///
|
||||
/// </summary>
|
||||
///
|
||||
[RunInstaller(true)]
|
||||
public sealed class PSCorePSSnapIn : PSSnapIn
|
||||
{
|
||||
/// <summary>
|
||||
/// Create an instance of this class.
|
||||
/// </summary>
|
||||
public PSCorePSSnapIn()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get name of this mshsnapin.
|
||||
/// </summary>
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return RegistryStrings.CoreMshSnapinName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the default vendor string for this mshsnapin.
|
||||
/// </summary>
|
||||
public override string Vendor
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Microsoft";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get resource information for vendor. This is a string of format: resourceBaseName,resourceName.
|
||||
/// </summary>
|
||||
public override string VendorResource
|
||||
{
|
||||
get
|
||||
{
|
||||
return "CoreMshSnapInResources,Vendor";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the default description string for this mshsnapin.
|
||||
/// </summary>
|
||||
public override string Description
|
||||
{
|
||||
get
|
||||
{
|
||||
return "This PSSnapIn contains MSH management cmdlets used to manage components affecting the MSH engine.";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get resource information for description. This is a string of format: resourceBaseName,resourceName.
|
||||
/// </summary>
|
||||
public override string DescriptionResource
|
||||
{
|
||||
get
|
||||
{
|
||||
return "CoreMshSnapInResources,Description";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get type files to be used for this mshsnapin.
|
||||
/// </summary>
|
||||
public override string[] Types { get; } = new string[] { "types.ps1xml" };
|
||||
|
||||
/// <summary>
|
||||
/// Get format files to be used for this mshsnapin.
|
||||
/// </summary>
|
||||
public override string[] Formats { get; } = new string[] {
|
||||
"Certificate.format.ps1xml",
|
||||
"DotNetTypes.format.ps1xml",
|
||||
"FileSystem.format.ps1xml",
|
||||
"Help.format.ps1xml",
|
||||
"HelpV3.format.ps1xml",
|
||||
"PowerShellCore.format.ps1xml",
|
||||
"PowerShellTrace.format.ps1xml",
|
||||
"Registry.format.ps1xml"
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,220 +0,0 @@
|
||||
/********************************************************************++
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Configuration.Install;
|
||||
using System.Reflection;
|
||||
using Microsoft.Win32;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Globalization;
|
||||
using Dbg = System.Management.Automation.Diagnostics;
|
||||
|
||||
namespace System.Management.Automation
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// PSInstaller is a class for facilitating installation
|
||||
/// of monad engine and monad PSSnapin's.
|
||||
///
|
||||
/// This class implements installer api from CLR. At install
|
||||
/// time, installation utilities (like InstallUtil.exe) will
|
||||
/// call api implementation functions in this class automatically.
|
||||
/// This includes functions like Install, Uninstall, Rollback
|
||||
/// and Commit.
|
||||
///
|
||||
/// This class is an abstract class for handling installation needs
|
||||
/// that are common for all monad components, which include,
|
||||
///
|
||||
/// 1. accessing system registry
|
||||
/// 2. support of additional command line parameters.
|
||||
/// 3. writing registry files
|
||||
/// 4. automatically extract information like vender, version, etc.
|
||||
///
|
||||
/// Different monad component will derive from this class. Two common
|
||||
/// components that need install include,
|
||||
///
|
||||
/// 1. PSSnapin. Installation of PSSnapin will require information
|
||||
/// about PSSnapin assembly, version, vendor, etc to be
|
||||
/// written to registry.
|
||||
///
|
||||
/// 2. Engine. Installation of monad engine will require information
|
||||
/// about engine assembly, version, CLR information to be
|
||||
/// written to registry.
|
||||
///
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// This is an abstract class to be derived by monad engine and PSSnapin installers
|
||||
/// only. Developer should not directly derive from this class.
|
||||
/// </remarks>
|
||||
public abstract class PSInstaller : Installer
|
||||
{
|
||||
private static string[] MshRegistryRoots
|
||||
{
|
||||
get
|
||||
{
|
||||
// For 3.0 PowerShell, we use "3" as the registry version key only for Engine
|
||||
// related data like ApplicationBase.
|
||||
// For 3.0 PowerShell, we still use "1" as the registry version key for
|
||||
// Snapin and Custom shell lookup/discovery.
|
||||
return new string[] {
|
||||
"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\PowerShell\\" + PSVersionInfo.RegistryVersion1Key + "\\"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal abstract string RegKey
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal abstract Dictionary<String, object> RegValues
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="stateSaver"></param>
|
||||
public sealed override void Install(IDictionary stateSaver)
|
||||
{
|
||||
base.Install(stateSaver);
|
||||
|
||||
WriteRegistry();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private void WriteRegistry()
|
||||
{
|
||||
foreach (string root in MshRegistryRoots)
|
||||
{
|
||||
RegistryKey key = GetRegistryKey(root + RegKey);
|
||||
|
||||
foreach (var pair in RegValues)
|
||||
{
|
||||
key.SetValue(pair.Key, pair.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private RegistryKey GetRegistryKey(string keyPath)
|
||||
{
|
||||
RegistryKey root = GetRootHive(keyPath);
|
||||
|
||||
if (root == null)
|
||||
return null;
|
||||
|
||||
return root.CreateSubKey(GetSubkeyPath(keyPath));
|
||||
}
|
||||
|
||||
private static string GetSubkeyPath(string keyPath)
|
||||
{
|
||||
int index = keyPath.IndexOf('\\');
|
||||
if (index > 0)
|
||||
{
|
||||
return keyPath.Substring(index + 1);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static RegistryKey GetRootHive(string keyPath)
|
||||
{
|
||||
string root;
|
||||
|
||||
int index = keyPath.IndexOf('\\');
|
||||
if (index > 0)
|
||||
{
|
||||
root = keyPath.Substring(0, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
root = keyPath;
|
||||
}
|
||||
|
||||
switch (root.ToUpperInvariant())
|
||||
{
|
||||
case "HKEY_CURRENT_USER":
|
||||
return Registry.CurrentUser;
|
||||
case "HKEY_LOCAL_MACHINE":
|
||||
return Registry.LocalMachine;
|
||||
case "HKEY_CLASSES_ROOT":
|
||||
return Registry.ClassesRoot;
|
||||
case "HKEY_CURRENT_CONFIG":
|
||||
return Registry.CurrentConfig;
|
||||
case "HKEY_PERFORMANCE_DATA":
|
||||
return Registry.PerformanceData;
|
||||
case "HKEY_USERS":
|
||||
return Registry.Users;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uninstall this msh component
|
||||
/// </summary>
|
||||
/// <param name="savedState"></param>
|
||||
public sealed override void Uninstall(IDictionary savedState)
|
||||
{
|
||||
base.Uninstall(savedState);
|
||||
|
||||
if (this.Context != null && this.Context.Parameters != null && this.Context.Parameters.ContainsKey("RegFile"))
|
||||
{
|
||||
string regFile = this.Context.Parameters["RegFile"];
|
||||
|
||||
// If regfile is specified. Don't uninstall.
|
||||
if (!String.IsNullOrEmpty(regFile))
|
||||
return;
|
||||
}
|
||||
|
||||
string keyName;
|
||||
string parentKey;
|
||||
|
||||
int index = RegKey.LastIndexOf('\\');
|
||||
if (index >= 0)
|
||||
{
|
||||
parentKey = RegKey.Substring(0, index);
|
||||
keyName = RegKey.Substring(index + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
parentKey = "";
|
||||
keyName = RegKey;
|
||||
}
|
||||
|
||||
foreach (string root in MshRegistryRoots)
|
||||
{
|
||||
RegistryKey key = GetRegistryKey(root + parentKey);
|
||||
|
||||
key.DeleteSubKey(keyName);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rollback this msh component
|
||||
/// </summary>
|
||||
/// <param name="savedState"></param>
|
||||
public sealed override void Rollback(IDictionary savedState)
|
||||
{
|
||||
Uninstall(savedState);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/********************************************************************++
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using Microsoft.Win32;
|
||||
using System.IO;
|
||||
using System.Management.Automation.Runspaces;
|
||||
|
||||
namespace System.Management.Automation
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// MshSnapin is a class for regular mshsnapin's which is constructed
|
||||
/// based on mshsnapin assembly.
|
||||
///
|
||||
/// This class derives from PSSnapInInstaller and will be used as the base
|
||||
/// for all regular mshsnapins.
|
||||
///
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// Developers should derive from this class when implementing their own
|
||||
/// mshsnapins.
|
||||
///
|
||||
/// Derived mshsnapins should be denoted with [RunInstaller] attribute
|
||||
/// so that installutil.exe can directly install the mshsnapin into registry.
|
||||
/// </remarks>
|
||||
public abstract class PSSnapIn : PSSnapInInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets list of format files to be loaded for this mshsnapin.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This member can be derived to provide the list of formats to be loaded for this mshsnapin.
|
||||
/// </remarks>
|
||||
public virtual string[] Formats
|
||||
{
|
||||
get
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets list of type files to be loaded for this mshsnapin.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This member can be derived to provide the list of types to be loaded for this mshsnapin.
|
||||
/// </remarks>
|
||||
public virtual string[] Types
|
||||
{
|
||||
get
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<String, object> _regValues = null;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal override Dictionary<String, object> RegValues
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_regValues == null)
|
||||
{
|
||||
_regValues = base.RegValues;
|
||||
|
||||
if (this.Types != null && this.Types.Length > 0)
|
||||
_regValues[RegistryStrings.MshSnapin_BuiltInTypes] = this.Types;
|
||||
|
||||
if (this.Formats != null && this.Formats.Length > 0)
|
||||
_regValues[RegistryStrings.MshSnapin_BuiltInFormats] = this.Formats;
|
||||
}
|
||||
|
||||
return _regValues;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
/********************************************************************++
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration.Install;
|
||||
using System.IO;
|
||||
|
||||
namespace System.Management.Automation
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// MshSnapinBase (or MshSnapinInstaller) is a class for facilitating registry of necessary
|
||||
/// information for monad mshsnapin's.
|
||||
///
|
||||
/// This class will be built with monad core engine dll
|
||||
/// (System.Management.Automation.dll).
|
||||
///
|
||||
/// This is the base class for two kinds of mshsnapins: MshSnapin and CustomMshSnapin.
|
||||
///
|
||||
/// Each mshsnapin assembly should derive from this class (indirectly) and fill
|
||||
/// in information about mshsnapin name, vendor, and version.
|
||||
///
|
||||
/// At install time, installation utilities (like InstallUtil.exe) will
|
||||
/// call install this engine assembly based on the implementation in
|
||||
/// this class.
|
||||
///
|
||||
/// This class derives from base class PSInstaller. PSInstaller will
|
||||
/// handle the details about how information got written into registry.
|
||||
/// Here, the information about registry content is provided.
|
||||
///
|
||||
/// The reason of not calling this class MshSnapinInstaller is to "hide" the details
|
||||
/// that MshSnapin class is actually doing installation. It is also more intuitive
|
||||
/// since people deriving from this class will think there are really
|
||||
/// implementing a class for mshsnapin.
|
||||
///
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// This is an abstract class to be derived by monad mshsnapin and custom mshsnapin.
|
||||
/// MshSnapin developer should not directly derive from this class.
|
||||
/// </remarks>
|
||||
public abstract class PSSnapInInstaller : PSInstaller
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract string Name
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract string Vendor
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public virtual string VendorResource
|
||||
{
|
||||
get
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract string Description
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public virtual string DescriptionResource
|
||||
{
|
||||
get
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private string MshSnapinVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.GetType().Assembly.GetName().Version.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
private string _psVersion = null;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private string PSVersion
|
||||
{
|
||||
get { return _psVersion ?? (_psVersion = PSVersionInfo.FeatureVersionString); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal sealed override string RegKey
|
||||
{
|
||||
get
|
||||
{
|
||||
PSSnapInInfo.VerifyPSSnapInFormatThrowIfError(this.Name);
|
||||
|
||||
return RegistryStrings.MshSnapinKey + "\\" + Name;
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<String, object> _regValues = null;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal override Dictionary<String, object> RegValues
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_regValues == null)
|
||||
{
|
||||
_regValues = new Dictionary<String, object>();
|
||||
_regValues[RegistryStrings.MshSnapin_MonadVersion] = this.PSVersion;
|
||||
|
||||
if (!String.IsNullOrEmpty(this.Vendor))
|
||||
_regValues[RegistryStrings.MshSnapin_Vendor] = this.Vendor;
|
||||
|
||||
if (!String.IsNullOrEmpty(this.Description))
|
||||
_regValues[RegistryStrings.MshSnapin_Description] = this.Description;
|
||||
|
||||
if (!String.IsNullOrEmpty(this.VendorResource))
|
||||
_regValues[RegistryStrings.MshSnapin_VendorResource] = this.VendorResource;
|
||||
|
||||
if (!String.IsNullOrEmpty(this.DescriptionResource))
|
||||
_regValues[RegistryStrings.MshSnapin_DescriptionResource] = this.DescriptionResource;
|
||||
|
||||
_regValues[RegistryStrings.MshSnapin_Version] = this.MshSnapinVersion;
|
||||
_regValues[RegistryStrings.MshSnapin_ApplicationBase] = Path.GetDirectoryName(this.GetType().Assembly.Location);
|
||||
_regValues[RegistryStrings.MshSnapin_AssemblyName] = this.GetType().Assembly.FullName;
|
||||
_regValues[RegistryStrings.MshSnapin_ModuleName] = this.GetType().Assembly.Location;
|
||||
}
|
||||
|
||||
return _regValues;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-82
@@ -69,89 +69,9 @@ namespace System.Management.Automation.Runspaces
|
||||
private const string DuplicateFile = "DuplicateFile";
|
||||
internal const string ValidationException = "ValidationException";
|
||||
|
||||
private static string GetBaseFolder(
|
||||
RunspaceConfiguration runspaceConfiguration,
|
||||
Collection<string> independentErrors)
|
||||
private static string GetBaseFolder(Collection<string> independentErrors)
|
||||
{
|
||||
string returnValue = CommandDiscovery.GetShellPathFromRegistry(runspaceConfiguration.ShellId);
|
||||
if (returnValue == null)
|
||||
{
|
||||
returnValue = Path.GetDirectoryName(PsUtils.GetMainModule(System.Diagnostics.Process.GetCurrentProcess()).FileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
returnValue = Path.GetDirectoryName(returnValue);
|
||||
if (!Directory.Exists(returnValue))
|
||||
{
|
||||
string newReturnValue = Path.GetDirectoryName(typeof(FormatAndTypeDataHelper).GetTypeInfo().Assembly.Location);
|
||||
string error = StringUtil.Format(TypesXmlStrings.CannotFindRegistryKeyPath, returnValue,
|
||||
Utils.GetRegistryConfigurationPath(runspaceConfiguration.ShellId), "\\Path", newReturnValue);
|
||||
independentErrors.Add(error);
|
||||
returnValue = newReturnValue;
|
||||
}
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
internal static Collection<PSSnapInTypeAndFormatErrors> GetFormatAndTypesErrors(
|
||||
RunspaceConfiguration runspaceConfiguration,
|
||||
PSHost host,
|
||||
IEnumerable<RunspaceConfigurationEntry> configurationEntryCollection,
|
||||
Collection<string> independentErrors,
|
||||
Collection<int> entryIndicesToRemove)
|
||||
{
|
||||
Collection<PSSnapInTypeAndFormatErrors> returnValue = new Collection<PSSnapInTypeAndFormatErrors>();
|
||||
|
||||
string baseFolder = GetBaseFolder(runspaceConfiguration, independentErrors);
|
||||
var psHome = Utils.DefaultPowerShellAppBase;
|
||||
|
||||
// this hashtable will be used to check whether this is duplicated file for types or formats.
|
||||
HashSet<string> fullFileNameSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
int index = -1;
|
||||
|
||||
foreach (var configurationEntry in configurationEntryCollection)
|
||||
{
|
||||
string fileName;
|
||||
string psSnapinName = configurationEntry.PSSnapIn == null ? runspaceConfiguration.ShellId : configurationEntry.PSSnapIn.Name;
|
||||
index++;
|
||||
var typeEntry = configurationEntry as TypeConfigurationEntry;
|
||||
if (typeEntry != null)
|
||||
{
|
||||
fileName = typeEntry.FileName;
|
||||
|
||||
if (fileName == null)
|
||||
{
|
||||
returnValue.Add(new PSSnapInTypeAndFormatErrors(psSnapinName, typeEntry.TypeData, typeEntry.IsRemove));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FormatConfigurationEntry formatEntry = (FormatConfigurationEntry)configurationEntry;
|
||||
fileName = formatEntry.FileName;
|
||||
|
||||
if (fileName == null)
|
||||
{
|
||||
returnValue.Add(new PSSnapInTypeAndFormatErrors(psSnapinName, formatEntry.FormatData));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
bool checkFileExists = configurationEntry.PSSnapIn == null || string.Equals(psHome, configurationEntry.PSSnapIn.AbsoluteModulePath, StringComparison.OrdinalIgnoreCase);
|
||||
bool needToRemoveEntry = false;
|
||||
string fullFileName = GetAndCheckFullFileName(psSnapinName, fullFileNameSet, baseFolder, fileName, independentErrors, ref needToRemoveEntry, checkFileExists);
|
||||
if (fullFileName == null)
|
||||
{
|
||||
if (needToRemoveEntry)
|
||||
{
|
||||
entryIndicesToRemove.Add(index);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
returnValue.Add(new PSSnapInTypeAndFormatErrors(psSnapinName, fullFileName));
|
||||
}
|
||||
return returnValue;
|
||||
return Path.GetDirectoryName(PsUtils.GetMainModule(System.Diagnostics.Process.GetCurrentProcess()).FileName);
|
||||
}
|
||||
|
||||
private static string GetAndCheckFullFileName(
|
||||
@@ -56,6 +56,20 @@ Describe "Update-FormatData basic functionality" -Tags "CI" {
|
||||
{ Update-FormatData -Append $testfile -WhatIf } | Should Not Throw
|
||||
{ Update-FormatData -Prepend $testfile -WhatIf } | Should Not Throw
|
||||
}
|
||||
|
||||
It "Update with invalid format xml should fail" -Pending {
|
||||
$xmlContent = @"
|
||||
<Configuration>
|
||||
<ViewDefinitions>
|
||||
<View>
|
||||
<Name>T2</Name>
|
||||
</View>
|
||||
</ViewDefinitions>
|
||||
</Configuration>
|
||||
"@
|
||||
$xmlContent | Out-File -FilePath "$testdrive\test.format.ps1xml" -Encoding ascii
|
||||
{ Update-FormatData -Path "$testdrive\test.format.ps1xml" -ErrorAction Stop } | ShouldBeErrorId "FormatXmlUpdateException,Microsoft.PowerShell.Commands.UpdateFormatDataCommand"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ Describe 'Basic engine APIs' -Tags "CI" {
|
||||
|
||||
$result = $ps.Invoke()
|
||||
$result.Count | Should Be 1
|
||||
$result[0].PSSnapIn.Name | Should Be "Microsoft.WSMan.Management"
|
||||
$result[0].Source | Should Be "Microsoft.WSMan.Management"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user