22// Licensed under the MIT License.
33
44using System ;
5+ using System . Collections . Generic ;
56using System . IO ;
67using System . Linq . Expressions ;
78using System . Management . Automation ;
1112
1213namespace Microsoft . PowerShell . EditorServices . Utility
1314{
14- internal static class PSCommandExtensions
15+ internal static class PSCommandHelpers
1516 {
1617 private static readonly Func < CommandInfo , Command > s_commandCtor ;
1718
18- static PSCommandExtensions ( )
19+ static PSCommandHelpers ( )
1920 {
2021 var ctor = typeof ( Command ) . GetConstructor (
2122 BindingFlags . Instance | BindingFlags . NonPublic | BindingFlags . Public ,
@@ -31,9 +32,14 @@ static PSCommandExtensions()
3132 . Compile ( ) ;
3233 }
3334
34- // PowerShell's missing an API for us to AddCommand using a CommandInfo.
35- // An issue was filed here: https://github.com/PowerShell/PowerShell/issues/12295
36- // This works around this by creating a `Command` and passing it into PSCommand.AddCommand(Command command)
35+ /// <summary>
36+ /// PowerShell's missing an API for us to AddCommand using a CommandInfo.
37+ /// An issue was filed here: https://github.com/PowerShell/PowerShell/issues/12295
38+ /// This works around this by creating a `Command` and passing it into PSCommand.AddCommand(Command command)
39+ /// </summary>
40+ /// <param name="command"></param>
41+ /// <param name="commandInfo"></param>
42+ /// <returns></returns>
3743 public static PSCommand AddCommand ( this PSCommand command , CommandInfo commandInfo )
3844 {
3945 var rsCommand = s_commandCtor ( commandInfo ) ;
@@ -81,6 +87,7 @@ public static PSCommand AddProfileLoadIfExists(this PSCommand psCommand, PSObjec
8187 /// <summary>
8288 /// Get a representation of the PSCommand, for logging purposes.
8389 /// </summary>
90+ /// <param name="command"></param>
8491 public static string GetInvocationText ( this PSCommand command )
8592 {
8693 Command currentCommand = command . Commands [ 0 ] ;
@@ -119,5 +126,31 @@ private static StringBuilder AddCommandText(this StringBuilder sb, Command comma
119126
120127 return sb ;
121128 }
129+
130+ public static PSCommand BuildCommandFromArguments ( string command , IReadOnlyList < string > arguments )
131+ {
132+ if ( arguments is null or { Count : 0 } )
133+ {
134+ return new PSCommand ( ) . AddCommand ( command ) ;
135+ }
136+
137+ // HACK: We use AddScript instead of AddArgument/AddParameter to reuse Powershell parameter binding logic.
138+ // We quote the command parameter so that expressions can still be used in the arguments.
139+ var sb = new StringBuilder ( )
140+ . Append ( '&' )
141+ . Append ( ' ' )
142+ . Append ( '"' )
143+ . Append ( command )
144+ . Append ( '"' ) ;
145+
146+ foreach ( string arg in arguments )
147+ {
148+ sb
149+ . Append ( ' ' )
150+ . Append ( ArgumentEscaping . Escape ( arg ) ) ;
151+ }
152+
153+ return new PSCommand ( ) . AddScript ( sb . ToString ( ) ) ;
154+ }
122155 }
123156}
0 commit comments