You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.psm1模块中Cmdlet函数为何吞掉&dotnet的输出?

问题描述

原本直接在.ps1文件中执行& dotnet命令能正常显示输出,但将这段逻辑封装到.psm1模块的Build-Android Cmdlet函数后,函数功能正常,但& dotnet的输出不再显示。经排查该问题与终端环境相关:在PowerShell Core 7环境下,终端不会显示&表达式的输出,但PowerShell本身可以,且无法将代码移回.ps1文件。

尝试过的无效方法

  • & dotnet *>&1
  • & dotnet | Out-Host
  • & dotnet | Write-Host

相关代码

functions.psm1

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"

    $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

    &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
}

MyScript.ps1

param (
    [Parameter(Mandatory=$true, HelpMessage="发布过程的签名密码")]
    [string]$SignPassword,
    [Parameter(Mandatory=$true, HelpMessage="APK发布的目标文件夹")]
    [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

解决方案

在模块函数中,需要将dotnet命令的标准输出和错误流同时重定向,再通过Out-Host强制输出到控制台。修改执行dotnet的代码行如下:

# 重定向所有流到标准输出,再输出到主机
& 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 2>&1 | Out-Host

若需要同时捕获输出内容并显示,可先捕获再输出:

# 捕获所有输出,再输出到主机
$dotnetOutput = & 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 2>&1
$dotnetOutput | Out-Host

原理:模块函数默认会将命令输出作为返回值的一部分捕获,Out-Host可强制将内容直接输出到终端,绕过PowerShell的输出捕获机制;2>&1将错误流合并到标准输出,确保错误信息也能正常显示。

内容的提问来源于stack exchange,提问作者Dbl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 08:54:52