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