-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Description
Motivations
Very long history and fears of inevitable breaking changes
#1995
#7388
#1908
#13068
#12491
#12975
#10722
#10741
#9006
#3996
#13393
#13579
#13640 (comment) PSNativePSPathResolution
#10509 (comment)
#9343
PowerShell/PowerShell-RFC#90
PowerShell/PowerShell-RFC#88
It seems to be not all
Proposal
Introduce new PSNativeCmdlet class as an successor of the PSCmdlet class which will work as a wrapper for native apps.
Capabilities
All traditional cmdlet capabilities:
- Parameter completion
- Strong typed parameters
- Argument validation attributes
- Transformation attributes
- Parameter sets
- Dynamic parameters
Additionally:
- input/output encodings
- specific error output handling
- specific error code handling
- specific argument parsing, escaping (requires a hook in Binder)
- output parser (for strong typed output to PowerShell pipeline) Feature: Register-OutputParser #10741
- having special wrappers for specific applications like cmd.exe or msiexec
- specific hook for Suggestion System
- alternative optimizations for native pipelines
Benefits
The main thing is that this class can be integrated into the Engine subsystems selectively and gradually without total breaking changes.
And all subsystems themselves can be enhanced gradually.
All existing Engine possibilities remain. Wrappers can overlap its or bypass to its.
The class itself can also improve gradually.
We can add flags which subsystems a particular wrapper can support. For example say that only Completions. Or run it like a regular cmdlet. Or run it as a normal external command, but use the output parser.
We could add new option in Start-Process so that it uses capabilities of the new class too.
It is compiled and works fast. (We could think about script support too)
Easy adoption
Easy adoption for #1995 - We can implement @mklement0's Invoke-NativeShell internally in PSNativeCmdlet. Users can load a module with wrappers and get new behaviors or unload the module and get previous behavior. Or we could add flags in PSNativeCmdlet which turn on/off capabilities on the fly for the specific wrapper.
Git is a good example of gradual adoption. We could implement git wrapper to address argument parsing issues and it will work with posh-git module. Later we could enhance the wrapper with posh-git capabilities in some way.
Based on telemetry we will able to decide when to make the new behavior as default for all.
We can collect wrappers for the most popular commands in a separate standard module and a separate PowerShell project repository. The community will be able to quickly add wrappers and improve them. Other vendors and communities may publish modules with their wrappers for their applications.
Additional thoughts
This approach could address questions in @JamesWTruher's blog posts about how PowerShell can take better advantage of native executables
https://devblogs.microsoft.com/powershell/native-commands-in-powershell-a-new-approach/
https://devblogs.microsoft.com/powershell/native-commands-in-powershell-a-new-approach-part-2/
Since all native applications are built without a single parameter schema, these wrappers seem to be the only universal solution.
For Windows OS MSFT could make https://github.com/dotnet/command-line-api standard for all OS utilities. As result, PowerShell could benefits from this automatically loading meta data from managed dll-s.