Neko Musume’s helpful answer provides a solution to your immediate problem.
However, it’s worth taking a step back:
To synchronously execute console applications or batch files, call them directly (ng build ...
or & ng build ...
), do not use Start-Process
– see this answer and this GitHub docs issue detailing appropriate vs. non-appropriate use cases and requesting that guidance be added to the Start-Process
help topic.
Therefore:
# Execute ng synchronously, with its output streams connected to PowerShell's
ng build --prod D:\pathToAngularProject
As for what you tried:
To add to Neko’s answer:
The reason that your first command worked is that the following:
Start-Process -FilePath ng build ...
is equivalent to:
Start-Process -FilePath -FilePath ng -ArgumentList build ...
That is, the build
argument was bound positionally, without the need to name its target parameter, -ArgumentList
, explicitly.
Taking advantage of this, and also that -FilePath
is implied for the first positional argument, the immediate solution to your problem could be simplified to:
# The 1st positional argument, 'ng', binds to -FilePath
# The 2nd positional argument, the *array* of arguments to pass to 'ng',
# 'build' and '--prod', binds to -ArgumentList
Start-Process ng build, --prod ...
That said, Start-Process
has a long-standing bug that causes it to pass arguments with embedded spaces incorrectly – see GitHub issue #5576.
To preserve backward compatibility, this bug will likely not get fixed (except perhaps by introducing a new parameter).
It is therefore preferable to pass the arguments as a single array element, effectively as a command line (without the executable), where the boundaries between the arguments can properly be signaled with embedded "..."
quoting, if necessary:
# Pass the arguments for 'ng' *as a single string*, potentially
# with embedded "..." quoting (not needed here).
Start-Process ng 'build --prod' ...
An example with embedded quoting:
# Project path needs embedded "..." quoting, because it contains spaces.
Start-Process ng 'build --prod "D:\Work Projects\Foo"' ...
An example that uses an expandable (double-quoted) string ("..."
) in order to embed the values of variables / subexpressions (the embedded "
chars. must then be escaped as `"
(or ""
)):
$projDir="D:\Work Projects"
Start-Process ng "build --prod `"$projDir\Foo`"" ...
A general note on quoting array elements:
Because command arguments in PowerShell are parsed using the so-called argument (parsing) mode (shell-like), the (string) elements of the (implied) -ArgumentList
do not generally require quoting.
That is, array build, --prod
in argument mode is the equivalent of 'build', '--prod'
in expression mode (programming-language-like).
See this answer for an overview of PowerShell’s parsing modes.
However, you may use the quoted form in argument mode too, and – depending on the element values – you may have to quote, such as when elements contain spaces or other shell metacharacter; additionally, if the first element looks like a PowerShell parameter name (e.g., -prod
rather than --prod
), it must be quoted too.
A few examples:
Note: For simplicity, Write-Output
is used in the examples, which simply echoes each array element on its own line. An array passed to any cmdlet is parsed in argument mode.
# No quoting needed.
# Elements contain no PowerShell metacharacters.
Write-Output one, two
# Quoting needed for the 2nd array element, due to containing
# PowerShell metacharacters (space, parentheses)
Write-Output one, 'two (2)'
# Quoting needed for the 1st array element, because it looks
# like a PowerShell parameter name.
# (Of course, you may choose to quote *both* elements in this case,
# for consistency).
Write-Output '-one', two
# If the parameter-like argument isn't the *first* array element,
# the need for quoting goes away
Write-Output one, -two