Use-RawPipeline.psm1
Function Resolve-PathAsFileSystemPath { [CmdletBinding()] Param ( [Parameter(Mandatory = $true)] [string]$Path ) Process { Try { $local:resolved = @(Resolve-Path -Path $Path); If ($local:resolved.Count -gt 1) { Throw "Resolves to multiple paths: $Path"; Return; } If ($local:resolved.Count -lt 1) { Throw "Resolves to no path: $Path"; Return; } $local:resolved = $local:resolved[0]; If ($local:resolved.Provider.Name -ne 'FileSystem') { Throw "Does not resolve to a file system path: $Path"; Return; } $local:resolved.ProviderPath | Write-Output; } Catch { Throw; } } } Function Get-RawPipelineFromFile { [CmdletBinding(HelpUri = 'https://github.com/GeeLaw/PowerShellThingies/tree/master/modules/Use-RawPipeline')] Param ( [Parameter(Mandatory = $true, Position = 0)] [Alias('i')] [Alias('if')] [Alias('in')] [Alias('stdin')] [ValidateNotNullOrEmpty()] [string]$InputFile ) Process { $local:result = $null; Try { $local:input = Resolve-PathAsFileSystemPath -Path $InputFile -ErrorAction 'Stop'; $local:result = [GeeLaw.PSUseRawPipeline.ConcatenateFileStartInfo]::new($local:input); } Catch { $local:result = $null; Throw; } $local:result | Write-Output; } } Function Invoke-NativeCommand { [CmdletBinding(HelpUri = 'https://github.com/GeeLaw/PowerShellThingies/tree/master/modules/Use-RawPipeline', DefaultParameterSetName = 'CreateProcess')] Param ( [Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'CreateProcess')] [Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'CreateProcessWithStandardErrorRedirection')] [ValidateNotNullOrEmpty()] [string]$FilePath, [Parameter(Mandatory = $false, Position = 1, ValueFromRemainingArguments = $true, ParameterSetName = 'CreateProcess')] [Parameter(Mandatory = $false, Position = 1, ValueFromRemainingArguments = $true, ParameterSetName = 'CreateProcessWithStandardErrorRedirection')] [string[]]$ArgumentList, [Parameter(Mandatory = $false, ParameterSetName = 'CreateProcess')] [Parameter(Mandatory = $false, ParameterSetName = 'CreateProcessWithStandardErrorRedirection')] [ValidateNotNullOrEmpty()] [string]$WorkingDirectory = '.', [Parameter(Mandatory = $false, ValueFromPipeline = $true, ParameterSetName = 'CreateProcess')] [Parameter(Mandatory = $false, ValueFromPipeline = $true, ParameterSetName = 'CreateProcessWithStandardErrorRedirection')] [GeeLaw.PSUseRawPipeline.ITeedProcessStartInfo]$StandardInput, [Parameter(Mandatory = $true, ParameterSetName = 'CreateProcessWithStandardErrorRedirection')] [string]$ErrorFile, [Parameter(Mandatory = $false, ParameterSetName = 'CreateProcessWithStandardErrorRedirection')] [switch]$AppendError ) Process { $local:result = $null; Try { $local:baseDirectory = Resolve-PathAsFileSystemPath -Path '.' -ErrorAction 'Stop'; $WorkingDirectory = Resolve-PathAsFileSystemPath -Path $WorkingDirectory -ErrorAction 'Stop'; <# If you pass $null to a [string] argument, you get [string]::Empty instead. #> If ($PSCmdlet.ParameterSetName -eq 'CreateProcessWithStandardErrorRedirection') { $local:result = [GeeLaw.PSUseRawPipeline.PipedProcessStartInfo]::new(` $FilePath, $local:baseDirectory, $WorkingDirectory, ` $ArgumentList, $StandardInput, $ErrorFile, $AppendError); } Else { $local:result = [GeeLaw.PSUseRawPipeline.PipedProcessStartInfo]::new(` $FilePath, $local:baseDirectory, $WorkingDirectory, ` $ArgumentList, $StandardInput); } } Catch { $local:result = $null; Throw; } $local:result | Write-Output; } } Function Receive-RawPipeline { [CmdletBinding(HelpUri = 'https://github.com/GeeLaw/PowerShellThingies/tree/master/modules/Use-RawPipeline', DefaultParameterSetName = 'CommonEncoding')] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'CommonEncoding')] [Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'CustomEncoding')] [ValidateNotNull()] [GeeLaw.PSUseRawPipeline.ITeedProcessStartInfo]$StandardInput, [Parameter(Mandatory = $false, Position = 0, ParameterSetName = 'CommonEncoding')] [ValidateSet('Auto', 'Byte', 'UTF8', 'UTF16LE', 'UTF16BE', 'UTF32')] [string]$CommonEncoding = 'Auto', [Parameter(Mandatory = $true, ParameterSetName = 'CustomEncoding')] [string]$Encoding, [Parameter(Mandatory = $false, ParameterSetName = 'CommonEncoding')] [Parameter(Mandatory = $false, ParameterSetName = 'CustomEncoding')] [switch]$Raw ) Process { Try { If ($PSCmdlet.ParameterSetName -eq 'CommonEncoding' -and $CommonEncoding -eq 'Byte') { $local:startedProcess = $StandardInput.Invoke(); [GeeLaw.PSUseRawPipeline.Helper]::EnumerateBytesInStandardOutput($local:startedProcess); Return; } $local:chosenEncoding = $null; If ($PSCmdlet.ParameterSetName -eq 'CommonEncoding') { If ($CommonEncoding -eq 'UTF8') { $local:chosenEncoding = [System.Text.Encoding]::UTF8; } ElseIf ($CommonEncoding -eq 'UTF16LE') { $local:chosenEncoding = [System.Text.Encoding]::Unicode; } ElseIf ($CommonEncoding -eq 'UTF16BE') { $local:chosenEncoding = [System.Text.Encoding]::BigEndianUnicode; } ElseIf ($CommonEncoding -eq 'UTF32') { $local:chosenEncoding = [System.Text.Encoding]::UTF32; } } Else { $local:chosenEncoding = [System.Text.Encoding]::GetEncoding($Encoding); } $local:startedProcess = $StandardInput.Invoke(); If ($Raw) { [GeeLaw.PSUseRawPipeline.Helper]::StringFromStandardOutput($local:startedProcess, $local:chosenEncoding); Return; } [GeeLaw.PSUseRawPipeline.Helper]::EnumerateLinesInStandardOutput($local:startedProcess, $local:chosenEncoding); Return; } Catch { Throw; } } } Function Set-RawPipelineToFile { [CmdletBinding(HelpUri = 'https://github.com/GeeLaw/PowerShellThingies/tree/master/modules/Use-RawPipeline')] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [ValidateNotNull()] [GeeLaw.PSUseRawPipeline.ITeedProcessStartInfo]$StandardInput, [Parameter(Mandatory = $true, Position = 0)] [ValidateNotNullOrEmpty()] [string]$OutputFile ) Process { $local:fs = $null; Try { $local:baseDirectory = Resolve-PathAsFileSystemPath -Path '.' -ErrorAction 'Stop'; $local:currentDirectory = [System.IO.Directory]::GetCurrentDirectory(); Try { [System.IO.Directory]::SetCurrentDirectory($local:baseDirectory); $local:fs = [System.IO.FileStream]::new($OutputFile, [System.IO.FileMode]::Create, ` [System.IO.FileAccess]::Write); } Finally { [System.IO.Directory]::SetCurrentDirectory($local:currentDirectory); } $local:startedProcess = $StandardInput.Invoke(); [GeeLaw.PSUseRawPipeline.Helper]::CopyStandardOutput($local:startedProcess, $local:fs); Return; } Catch { Throw; } Finally { If ($local:fs -ne $null) { $local:fs.Close(); } } } } Function Add-RawPipelineToFile { [CmdletBinding(HelpUri = 'https://github.com/GeeLaw/PowerShellThingies/tree/master/modules/Use-RawPipeline')] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [ValidateNotNull()] [GeeLaw.PSUseRawPipeline.ITeedProcessStartInfo]$StandardInput, [Parameter(Mandatory = $true, Position = 0)] [ValidateNotNullOrEmpty()] [string]$OutputFile ) Process { $local:fs = $null; Try { $local:baseDirectory = Resolve-PathAsFileSystemPath -Path '.' -ErrorAction 'Stop'; $local:currentDirectory = [System.IO.Directory]::GetCurrentDirectory(); Try { [System.IO.Directory]::SetCurrentDirectory($local:baseDirectory); $local:fs = [System.IO.FileStream]::new($OutputFile, [System.IO.FileMode]::Append); } Finally { [System.IO.Directory]::SetCurrentDirectory($local:currentDirectory); } $local:startedProcess = $StandardInput.Invoke(); [GeeLaw.PSUseRawPipeline.Helper]::CopyStandardOutput($local:startedProcess, $local:fs); Return; } Catch { Throw; } Finally { If ($local:fs -ne $null) { $local:fs.Close(); } } } } Set-Alias -Name 'run' -Value 'Invoke-NativeCommand'; Set-Alias -Name '2ps' -Value 'Receive-RawPipeline'; Set-Alias -Name 'stdin' -Value 'Get-RawPipelineFromFile'; Set-Alias -Name 'out2' -Value 'Set-RawPipelineToFile'; Set-Alias -Name 'add2' -Value 'Add-RawPipelineToFile'; Export-ModuleMember -Function @('Invoke-NativeCommand', ` 'Receive-RawPipeline', 'Get-RawPipelineFromFile', ` 'Set-RawPipelineToFile', 'Add-RawPipelineToFile') ` -Alias @('run', '2ps', 'stdin', 'out2', 'add2'); |