2024年11月6日 星期三

PowerShell 如何捕捉 cmdlet 中 Write-Host 的信息到變數上

PowerShell 如何捕捉 cmdlet 中 Write-Host 的信息到變數上

在 PS 中通道其實是有屬於 PS 內自訂的通道, Write-Host 是 6 號通道

所以其實只要把 6 號轉換到 1 號就可以獲取了

function WriteTestMessage {
    Write-Host "這是使用 Write-Host 輸出的測試消息。"
}
$msg = WriteTestMessage 6>&1
Write-Host "msg = $msg"


其他通道的用處

1: Success (成功輸出)

2: Error (錯誤)

3: Warning (警告)

4: Verbose (詳細資訊)

5: Debug (除錯)

6: Information (資訊)


如果要個別獲取貌似只能重新定向到個別檔案上,無法透過 6>$msg 定向到變數獲取

例如 WriteTestMessage 6>"a.txt" 2>"b.txt" 這樣的寫法會直接輸出到檔案上。



這裡比較坑人的是 PS 有自己的流,這裡我先把他稱作為 PS流,與之相似的是與外部程式互動的,我們直接在終端看到的那個我把它稱為 Console流

PS中會同時出現兩種流的,當你呼叫一個外部程式那個外部程式產生的 stderr 是屬於 Console流 而不是 PS流

這不是在繞你啊,舉例來說下面的代碼

$stderr = App.exe 2>&1

嘗試獲取外部的 stderr 但實際上代碼中的 2>&1 所控制的是PS流,所以你啥也拿不到因為外部程式輸出的是Console流

如何獲取 Console流 中的 stderr 解法請參照這篇 CHG: PowerShell 如何捕捉 StdErr 通道的錯誤信息流 的 Invoke-CommandInfo 函式





PowerShell 如何捕捉 StdErr 通道的錯誤信息流

PowerShell 如何捕捉 StdErr 通道的錯誤信息流

這個要依靠 [Console]::SetError() 重設當前的流就可以捕捉到了


廢話不多說直接上代碼

function Get-StdErrOutput {
    param (
        [ScriptBlock]$ScriptBlock
    )

    # 創建 StringWriter 捕捉錯誤輸出
    $enc = [Console]::Error.Encoding
    $sw = New-Object System.IO.StringWriter
    [Console]::SetError($sw)

    try {
        & $ScriptBlock
    } finally {
        # 重置錯誤輸出流
        $originalErrorStream = [IO.StreamWriter]::new([Console]::OpenStandardError(), $enc)
        $originalErrorStream.AutoFlush = $true
        [Console]::SetError($originalErrorStream)
    }

    # 取得錯誤訊息並釋放資源
    $errorOutput = $sw.ToString() -replace "(`r?`n)$", ""
    $sw.Dispose()

    return $errorOutput
}


這是已經寫成函式的代碼下面是用例子

# 捕獲標準錯誤輸出
$std = Get-StdErrOutput {
    [Console]::Error.WriteLine("這是使用 Console.Error 輸出的測試消息。")
}

# 顯示捕獲到的錯誤訊息
Write-Host "Captured Error output = $std"

# 確認是否有復原原本的錯誤輸出
[Console]::Error.WriteLine("確認是否有復原原本的錯誤輸出") | Out-Null


此一來就可以把 stderr 的錯誤信息流輸出擷取到變數裡面了



如果要獲取外部程式的這裡也有個函式可以參考

SSHKeyLoader/SSHKeyLoader.ps1 at main · hunandy14/SSHKeyLoader



2024年11月2日 星期六

如何安裝 npm(nodejs) 與 vue 在Windows上

如何安裝 npm(nodejs) 與 vue 在Windows上


大概筆記一下有兩種裝法

  1. 使用安裝檔案 Node.js — 下載 Node.js®
  2. 使用免安裝檔案(需要自行添加環境變數) Node.js — 下載 Node.js®


第一個安裝檔案就是一路按到底就好,過程會有一個要求 chocolatey 編譯安裝,這個預設是沒打勾不要去按就好。

這東西是你要用 node-sass bcrypt sqlite3 的時候才會需要,事後也可以安裝,他在 npm 所在目錄有一個 install_tools.bat 執行就好。

所以初始安裝跳過就好,以後你要用的時候自己會去把它裝回來的。


免安裝檔案就把解壓縮目錄添加環境變數即可,然後如果要用 PowerShell 記得對 npm.ps1 這個檔案右鍵內容,解除封鎖。解封後就可以從 PowerShell 執行 npm 了。


對於模組目錄兩者預設在不同位置,也就是當你使用 -g 比如說 npm install -g @vue/cli 安裝時的目錄位置

  • 安裝檔案: %AppData%\npm\node_modules
  • 免安裝檔:解壓縮目錄底下的 node_modules