/********************************************************************++ Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System.Diagnostics.CodeAnalysis; using System.Text; namespace System.Management.Automation { /// /// A ProxyCommand class used to represent a Command constructed Dynamically /// public sealed class ProxyCommand { #region Private Constructor /// /// Private Constructor to restrict inheritance /// private ProxyCommand() { } #endregion #region Public Static Methods /// /// This method constructs a string representing the command specified by . /// The returned string is a ScriptBlock which can be used to configure a Cmdlet/Function in a Runspace. /// /// /// An instance of CommandMetadata representing a command. /// /// /// A string representing Command ScriptBlock. /// /// /// commandMetadata is null. /// public static string Create(CommandMetadata commandMetadata) { if (null == commandMetadata) { throw PSTraceSource.NewArgumentNullException("commandMetaData"); } return commandMetadata.GetProxyCommand("", true); } /// /// This method constructs a string representing the command specified by . /// The returned string is a ScriptBlock which can be used to configure a Cmdlet/Function in a Runspace. /// /// /// An instance of CommandMetadata representing a command. /// /// /// The string to be used as the help comment. /// /// /// A string representing Command ScriptBlock. /// /// /// commandMetadata is null. /// public static string Create(CommandMetadata commandMetadata, string helpComment) { if (null == commandMetadata) { throw PSTraceSource.NewArgumentNullException("commandMetaData"); } return commandMetadata.GetProxyCommand(helpComment, true); } /// /// This method constructs a string representing the command specified by . /// The returned string is a ScriptBlock which can be used to configure a Cmdlet/Function in a Runspace. /// /// /// An instance of CommandMetadata representing a command. /// /// /// The string to be used as the help comment. /// /// /// A boolean that determines whether the generated proxy command should include the functionality required /// to proxy dynamic parameters of the underlying command. /// /// /// A string representing Command ScriptBlock. /// /// /// commandMetadata is null. /// public static string Create(CommandMetadata commandMetadata, string helpComment, bool generateDynamicParameters) { if (null == commandMetadata) { throw PSTraceSource.NewArgumentNullException("commandMetaData"); } return commandMetadata.GetProxyCommand(helpComment, generateDynamicParameters); } /// /// This method constructs a string representing the CmdletBinding attribute of the command /// specified by . /// /// /// An instance of CommandMetadata representing a command. /// /// /// A string representing the CmdletBinding attribute of the command. /// /// /// commandMetadata is null. /// public static string GetCmdletBindingAttribute(CommandMetadata commandMetadata) { if (null == commandMetadata) { throw PSTraceSource.NewArgumentNullException("commandMetaData"); } return commandMetadata.GetDecl(); } /// /// This method constructs a string representing the param block of the command /// specified by . The returned string only contains the /// parameters, it is not enclosed in "param()". /// /// /// An instance of CommandMetadata representing a command. /// /// /// A string representing the parameters of the command. /// /// /// commandMetadata is null. /// [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] public static string GetParamBlock(CommandMetadata commandMetadata) { if (null == commandMetadata) { throw PSTraceSource.NewArgumentNullException("commandMetaData"); } return commandMetadata.GetParamBlock(); } /// /// This method constructs a string representing the begin block of the command /// specified by . The returned string only contains the /// script, it is not enclosed in "begin { }". /// /// /// An instance of CommandMetadata representing a command. /// /// /// A string representing the begin block of the command. /// /// /// commandMetadata is null. /// public static string GetBegin(CommandMetadata commandMetadata) { if (null == commandMetadata) { throw PSTraceSource.NewArgumentNullException("commandMetaData"); } return commandMetadata.GetBeginBlock(); } /// /// This method constructs a string representing the process block of the command /// specified by . The returned string only contains the /// script, it is not enclosed in "process { }". /// /// /// An instance of CommandMetadata representing a command. /// /// /// A string representing the process block of the command. /// /// /// commandMetadata is null. /// public static string GetProcess(CommandMetadata commandMetadata) { if (null == commandMetadata) { throw PSTraceSource.NewArgumentNullException("commandMetaData"); } return commandMetadata.GetProcessBlock(); } /// /// This method constructs a string representing the dynamic parameter block of the command /// specified by . The returned string only contains the /// script, it is not enclosed in "dynamicparam { }". /// /// /// An instance of CommandMetadata representing a command. /// /// /// A string representing the dynamic parameter block of the command. /// /// /// commandMetadata is null. /// public static string GetDynamicParam(CommandMetadata commandMetadata) { if (null == commandMetadata) { throw PSTraceSource.NewArgumentNullException("commandMetaData"); } return commandMetadata.GetDynamicParamBlock(); } /// /// This method constructs a string representing the end block of the command /// specified by . The returned string only contains the /// script, it is not enclosed in "end { }". /// /// /// An instance of CommandMetadata representing a command. /// /// /// A string representing the end block of the command. /// /// /// commandMetadata is null. /// public static string GetEnd(CommandMetadata commandMetadata) { if (null == commandMetadata) { throw PSTraceSource.NewArgumentNullException("commandMetaData"); } return commandMetadata.GetEndBlock(); } private static T GetProperty(PSObject obj, string property) where T: class { T result = null; if (obj != null && obj.Properties[property] != null) { result = obj.Properties[property].Value as T; } return result; } private static string GetObjText(object obj) { string text = null; PSObject psobj = obj as PSObject; if (psobj != null) { text = GetProperty(psobj, "Text"); } if (text == null) { text = obj.ToString(); } return text; } private static void AppendContent(StringBuilder sb, string section, object obj) { if (obj != null) { string text = GetObjText(obj); if (!string.IsNullOrEmpty(text)) { sb.Append("\n"); sb.Append(section); sb.Append("\n\n"); sb.Append(text); sb.Append("\n"); } } } private static void AppendContent(StringBuilder sb, string section, PSObject[] array) { if (array != null) { bool first = true; foreach (PSObject obj in array) { string text = GetObjText(obj); if (!string.IsNullOrEmpty(text)) { if (first) { first = false; sb.Append("\n\n"); sb.Append(section); sb.Append("\n\n"); } sb.Append(text); sb.Append("\n"); } } if (!first) { sb.Append("\n"); } } } private static void AppendType(StringBuilder sb, string section, PSObject parent) { PSObject type = GetProperty(parent, "type"); PSObject name = GetProperty(type, "name"); if (name != null) { sb.Append("\n\n"); sb.Append(section); sb.Append("\n\n"); sb.Append(GetObjText(name)); sb.Append("\n"); } else { PSObject uri = GetProperty(type, "uri"); if (uri != null) { sb.Append("\n\n"); sb.Append(section); sb.Append("\n\n"); sb.Append(GetObjText(uri)); sb.Append("\n"); } } } /// /// Construct the text that can be used in a multi-line comment for get-help. /// /// A custom PSObject created by Get-Help. /// A string that can be used as the help comment for script for the input HelpInfo object. /// When the help argument is null. /// When the help argument is not recognized as a HelpInfo object. public static string GetHelpComments(PSObject help) { if (help == null) { throw new ArgumentNullException("help"); } bool isHelpObject = false; foreach (string typeName in help.InternalTypeNames) { if (typeName.Contains("HelpInfo")) { isHelpObject = true; break; } } if (!isHelpObject) { string error = ProxyCommandStrings.HelpInfoObjectRequired; throw new InvalidOperationException(error); } StringBuilder sb = new StringBuilder(); AppendContent(sb, ".SYNOPSIS", GetProperty(help, "Synopsis")); AppendContent(sb, ".DESCRIPTION", GetProperty(help, "Description")); PSObject parameters = GetProperty(help, "Parameters"); PSObject[] parameter = GetProperty(parameters, "Parameter"); if (parameter != null) { foreach (PSObject param in parameter) { PSObject name = GetProperty(param, "Name"); PSObject[] description = GetProperty(param, "Description"); sb.Append("\n.PARAMETER "); sb.Append(name); sb.Append("\n\n"); foreach (PSObject obj in description) { string text = GetProperty(obj, "Text"); if (text == null) { text = obj.ToString(); } if (!string.IsNullOrEmpty(text)) { sb.Append(text); sb.Append("\n"); } } } } PSObject examples = GetProperty(help, "examples"); PSObject[] example = GetProperty(examples, "example"); if (example != null) { foreach (PSObject ex in example) { StringBuilder exsb = new StringBuilder(); PSObject[] introduction = GetProperty(ex, "introduction"); if (introduction != null) { foreach (PSObject intro in introduction) { if (intro != null) { exsb.Append(GetObjText(intro)); } } } PSObject code = GetProperty(ex, "code"); if (code != null) { exsb.Append(code.ToString()); } PSObject[] remarks = GetProperty(ex, "remarks"); if (remarks != null) { exsb.Append("\n"); foreach (PSObject remark in remarks) { string remarkText = GetProperty(remark, "text"); exsb.Append(remarkText.ToString()); } } if (exsb.Length > 0) { sb.Append("\n\n.EXAMPLE\n\n"); sb.Append(exsb.ToString()); } } } PSObject alertSet = GetProperty(help, "alertSet"); AppendContent(sb, ".NOTES", GetProperty(alertSet, "alert")); PSObject inputtypes = GetProperty(help, "inputTypes"); PSObject inputtype = GetProperty(inputtypes, "inputType"); AppendType(sb, ".INPUTS", inputtype); PSObject returnValues = GetProperty(help, "returnValues"); PSObject returnValue = GetProperty(returnValues, "returnValue"); AppendType(sb, ".OUTPUTS", returnValue); PSObject relatedLinks = GetProperty(help, "relatedLinks"); PSObject[] navigationLink = GetProperty(relatedLinks, "navigationLink"); if (navigationLink != null) { foreach (PSObject link in navigationLink) { // Most likely only one of these will append anything, but it // isn't wrong to append them both. AppendContent(sb, ".LINK", GetProperty(link, "uri")); AppendContent(sb, ".LINK", GetProperty(link, "linkText")); } } AppendContent(sb, ".COMPONENT", GetProperty(help, "Component")); AppendContent(sb, ".ROLE", GetProperty(help, "Role")); AppendContent(sb, ".FUNCTIONALITY", GetProperty(help, "Functionality")); return sb.ToString(); } #endregion } }