Below script works perfectly fine when it is directly executed from a .ps1 file, but ever since i put it in a .psm1 file the function still works, but does no longer redirect the output from &dotnet ...
to the output. I am looking for a way to make it print its output from within the function too. Moving it back to the ps1 is not an option.
I have tried a variation of
& dotnet *>&1
& dotnet | Out-Host
& dotnet | Write-Host
but apparently my powershell knowledge is too limited here.
function Build-Android {
[CmdletBinding()]
param(
[Parameter(Mandatory,ValueFromPipeline)]
[string] $KeyStorePath,
[Parameter(Mandatory,ValueFromPipeline)]
[string] $SignPassword,
[Parameter(Mandatory,ValueFromPipeline)]
[string] $ProjectPath,
[Parameter(Mandatory,ValueFromPipeline)]
[string] $PublishDirectory
)
[Environment]::SetEnvironmentVariable('PCR3PW', $SignPassword, 'Process')
$keyAlias = "PCR3"
$keyPass = "env:PCR3PW"
$storePass = "env:PCR3PW"
# https://learn.microsoft.com/de-de/dotnet/maui/android/deployment/publish-cli
$publishCode = "dotnet publish $ProjectPath -f net7.0-android -c Release -o `"$PublishDirectory`" -p:AndroidKeyStore=true -p:AndroidSigningKeyStore=$KeyStorePath -p:AndroidSigningKeyAlias=$keyAlias -p:AndroidSigningKeyPass=$keyPass -p:AndroidSigningStorePass=$storePass"
Write-Host "$publishCode" -ForegroundColor DarkGreen
#Invoke-Expression -Command $publishCode -ErrorAction Stop
&dotnet publish $ProjectPath -f net7.0-android -c Release -o `"$PublishDirectory`" -p:AndroidKeyStore=true -p:AndroidSigningKeyStore=$KeyStorePath -p:AndroidSigningKeyAlias=$keyAlias -p:AndroidSigningKeyPass=$keyPass -p:AndroidSigningStorePass=$storePass
if($LASTEXITCODE -ne 0)
throw "There was an issue running the specified dotnet command."
$apk = Get-ChildItem "$PublishDst" -Filter "*.apk" | %{$_.FullName}
return $apk
}
param (
[Parameter(Mandatory=$true, HelpMessage="Signing password for publish process")]
[string]$SignPassword,
[Parameter(Mandatory=$true, HelpMessage="Destination folder for APK publish")]
[string]$PublishDst
)
Import-Module ".\functions.psm1"
$keyStore = [System.Uri]::new([System.Uri]::new("$PSScriptRoot\.", [System.UriKind]::Absolute), [System.Uri]::new("PCR3.keystore", [System.UriKind]::Relative)).LocalPath
$apkProject = [System.Uri]::new([System.Uri]::new("$PSScriptRoot\.", [System.UriKind]::Absolute), [System.Uri]::new("..\src\MyProject\MyProject.csproj", [System.UriKind]::Relative)).LocalPath
$apkPath = Build-Android -KeyStorePath $keyStore -SignPassword $SignPassword -ProjectPath $apkProject -PublishDirectory $PublishDst
I have looked into this to look for clues on how to redirect my output: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_redirection?view=powershell-7.3
The cause of this apparently in some way is Terminal. While $PSVersionTable is the same as PS Core 7 - Terminal produces no output from the & expression while powershell itself does.
Look at the call site:
$apkPath = Build-Android -KeyStorePath $keyStore -SignPassword $SignPassword -ProjectPath $apkProject -PublishDirectory $PublishDst
You're assigning the output from Build-Android
to the local variable $apkPath
, so that's where the output will end up.
If you want to sidestep the normal flow of output and instead print it to the host application immediately, use Out-Host
:
&dotnet publish $ProjectPath -f net7.0-android -c Release -o `"$PublishDirectory`" -p:AndroidKeyStore=true -p:AndroidSigningKeyStore=$KeyStorePath -p:AndroidSigningKeyAlias=$keyAlias -p:AndroidSigningKeyPass=$keyPass -p:AndroidSigningStorePass=$storePass |Out-Host
Here's a simplified example showing the effect with ping.exe
instead:
PS ~> @'
>> function f {
>> [CmdletBinding()]
>> param()
>>
>> ping.exe 1.1.1.1 -n 1 |Out-Host
>>
>> return 'Not from ping'
>> }
>> '@ |Set-Content myModule.psm1
PS ~> Import-Module myModule.psm1 -Force
PS ~> $functionOutput = f
Pinging 1.1.1.1 with 32 bytes of data:
Reply from 1.1.1.1: bytes=32 time=13ms TTL=56
Ping statistics for 1.1.1.1:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 13ms, Maximum = 13ms, Average = 13ms
PS ~> $functionOutput
Not from ping
As you can see, the output piped to Out-Host
is written directly to the host application's screen buffer immediately as f
executes, whereas the regular output that isn't ends up in the variable.