Re: [心得] PowerShell 那些惱人的路徑 BUG

作者: falcon (falken)   2024-10-11 03:23:22
經過一些嘗試之後找到了一個方法來為 cmdlet 修復工作目錄路徑問題
儘管看起很蠢,但是管用
至於可不可靠,那就不知道了
# 為同名 cmdlet 修復工作目錄路徑問題
function Get-Item {
# 不能使用 [Parameter()] 修飾參數
# 否則,未宣告的參數會被拒絕
param (
[string[]] $Path,
[string[]] $LiteralPath
)
# 重現以下幾種管道功能
# $pathArray | cmdlet
# $pathArray | cmdlet -Path {$_}
# $pathArray | cmdlet -LiteralPath {$_}
[string[]] $vlueFromPipeLine = $input | ForEach-Object { $_ }
if ($vlueFromPipeLine.Count -gt 0) {
if ($null -ne $LiteralPath -and $LiteralPath[0] -eq '$_') {
$LiteralPath = $vlueFromPipeLine
}
elseif ($null -eq $Path -or $Path[0] -eq '$_') {
$Path = $vlueFromPipeLine
}
else {
Write-Error ''
return
}
}
$param = @{}
if ($LiteralPath.Count -gt 0) {
$param += @{
LiteralPath = $LiteralPath | ForEach-Object {
# 展開為路徑為 PSDrive:\path\to\item
}
}
}
if ($Path.Count -gt 0) {
$param += @{
Path = $Path | ForEach-Object {
# 展開為路徑為 PSDrive:\path\to\item
# 展開的部分要對特殊字元跳脫處理
}
}
}
# 呼叫 cmdlet 執行修改過的參數內容
Microsoft.PowerShell.Management\Get-Item @param @args
}
另外我還發現 Start-Process 下面三個路徑參數壞得更徹底
只要有特殊字元就發生錯誤,連跳脫處理都無效
-RedirectStandardError
-RedirectStandardInput
-RedirectStandardOutput
PowerShell 處處都是地雷......
作者: hunandy14 (Charlott.HonG)   2024-10-11 13:54:00
代理這事我找到方法解決了,動態抽取出來劫持確定可以實現完美轉發了,中間自己加料就好using namespace System.Management.Automation$m = [CommandMetadata]::new((Get-Command Get-Item))$script = [ProxyCommand]::Create($m)剩下的你應該知道我想幹嘛了XD 動態劫持並重載fun代理的元函式的輸入 函式名,{劫持參數:{代碼塊}}輸出看要輸出修改後的塊,還是不輸出直接注入準確的來說不是影響到模組,而是影響到環境蓋掉原始函式這事情很大,任何情況都不建議就算200%確定無bug 考慮到utf8補完計畫 就..真的慎選介面我是奔著通用函式做的 https://imgur.com/cNrh93v
作者: labbat (labbat)   2024-10-13 02:25:00
放棄掙扎投入標準UTF-8唄,UCS-2之上的任何補完都是徒勞
作者: smallreader (小讀者)   2024-10-13 04:16:00
什麼都4202年了竟然還有UTF-8的坑要跳?!
作者: hunandy14 (Charlott.HonG)   2024-10-13 14:20:00
等等 前面講得太簡短,我想說的不是utf8的問題。覆蓋函式的做法導致自己寫的代碼只能在這種被覆蓋的環境下執行,相對短期來看沒問題,長期來看或許會留下隱形的成本。補完計劃的事先當我沒說,模糊焦點了。
作者: falcon (falken)   2024-10-13 17:26:00
不過,對於外部程式要避免路徑與管道問題,也只能使用Process 物件來啟動程式。但之前提供的方法用在某些程式上會遇到死鎖WaitForExit()的問題,例如iconv.exe。要避免這問題,是需要用到非同步或多執行緒讀寫管道?
作者: hunandy14 (Charlott.HonG)   2024-10-14 08:53:00
第一推薦的做法是查一下有沒有 -oBatchMode=yes 的選項第二推薦的辦法是測一下給空白本身會不會報錯如果答案是會,那就直接關掉輸入他自己就會報錯了第一個是完全解完全不需要考慮會不會bug第二個可能要想一下組合考慮後果了未必可行

Links booklink

Contact Us: admin [ a t ] ucptt.com