Re: [心得] PowerShell 那些惱人的路徑 BUG
經過一些嘗試之後找到了一個方法來為 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 處處都是地雷......
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 39.9.131.112 (臺灣)
※ 文章網址: https://www.ptt.cc/bbs/Windows/M.1728588204.A.E74.html
→
10/11 13:54,
3月前
, 1F
10/11 13:54, 1F
→
10/11 13:56,
3月前
, 2F
10/11 13:56, 2F
→
10/11 13:59,
3月前
, 3F
10/11 13:59, 3F
→
10/11 13:59,
3月前
, 4F
10/11 13:59, 4F
→
10/11 14:00,
3月前
, 5F
10/11 14:00, 5F
→
10/11 14:01,
3月前
, 6F
10/11 14:01, 6F
→
10/11 14:39,
3月前
, 7F
10/11 14:39, 7F
→
10/11 14:39,
3月前
, 8F
10/11 14:39, 8F
感謝
但我不知道這怎麼做,有沒有範例參考?
受此啟發,我想到方法是這樣
using namespace System.Management.Automation
function Get-Item {
$command = Get-Command Microsoft.PowerShell.Management\Get-Item
$strCmdletBindingAttribute =
[ProxyCommand]::GetCmdletBindingAttribute($command)
$strParamBlock = [ProxyCommand]::GetParamBlock($command)
$otherBlocks = {
# 修改 $PSBoundParameters
Microsoft.PowerShell.Management\Get-Item @PSBoundParameters
}
$strScript = "$strCmdletBindingAttribute`nparam($strParamBlock)`n" +
$otherBlocks.ToString()
$script = [Scriptblock]::Create($strScript)
& $script @args
}
※ 編輯: falcon (27.247.32.27 臺灣), 10/11/2024 17:19:37
我發現這個方法會影響一些命令相關的 cmdlet
例如 Get-Help, Get-Command
另外,我還發現 Module 的作用範圍好像超乎預期的大
假如我匯入兩個 Module 如下
# module-a.psm1
function SaySomething {
'Hello! World!'
}
# module-b.psm1
function TryToSaySomething {
SaySomething
}
# Console
PS > Import-Module .\module-a.psm1
PS > Import-Module .\module-b.psm1
PS > TryToSaySomething
Hello! World!
引用 module_b 的函式時,也會受到 module_a 的影響
也就是說我在模組中定義一個函式用來代替 cmdlet
這個影響不只目前腳本,還將遍及所有其它的模組
這不知道該開心還是難過
※ 編輯: falcon (27.247.32.27 臺灣), 10/11/2024 21:36:43
→
10/12 01:18,
3月前
, 9F
10/12 01:18, 9F
→
10/12 01:19,
3月前
, 10F
10/12 01:19, 10F
我放棄了安裝使用的念頭,風險太大了
但在個別腳本或臨時匯入使用
高度可控的情況下應該比較沒問題
→
10/12 01:22,
3月前
, 11F
10/12 01:22, 11F
→
10/12 01:26,
3月前
, 12F
10/12 01:26, 12F
→
10/12 23:00,
3月前
, 13F
10/12 23:00, 13F
感謝示範技巧,有空來研究看看
現在想想
還是使用 -LiteralPath 與絕對路徑最妥當
遇到萬用字元或相對路徑
就用自己實作解析函式取得絕對路徑
再餵給 cmdlet
→
10/13 02:25,
3月前
, 14F
10/13 02:25, 14F
→
10/13 04:16,
3月前
, 15F
10/13 04:16, 15F
※ 編輯: falcon (27.51.88.255 臺灣), 10/13/2024 13:23:22
→
10/13 14:20,
3月前
, 16F
10/13 14:20, 16F
→
10/13 14:20,
3月前
, 17F
10/13 14:20, 17F
→
10/13 14:20,
3月前
, 18F
10/13 14:20, 18F
→
10/13 14:20,
3月前
, 19F
10/13 14:20, 19F
→
10/13 14:27,
3月前
, 20F
10/13 14:27, 20F
→
10/13 17:26,
3月前
, 21F
10/13 17:26, 21F
→
10/13 17:26,
3月前
, 22F
10/13 17:26, 22F
→
10/13 17:26,
3月前
, 23F
10/13 17:26, 23F
→
10/13 17:26,
3月前
, 24F
10/13 17:26, 24F
※ 編輯: falcon (27.51.88.255 臺灣), 10/13/2024 20:57:56
→
10/14 08:53,
3月前
, 25F
10/14 08:53, 25F
→
10/14 08:54,
3月前
, 26F
10/14 08:54, 26F
→
10/14 08:54,
3月前
, 27F
10/14 08:54, 27F
→
10/14 08:55,
3月前
, 28F
10/14 08:55, 28F
→
10/14 08:56,
3月前
, 29F
10/14 08:56, 29F
討論串 (同標題文章)
完整討論串 (本文為第 3 之 3 篇):
Windows 近期熱門文章
PTT數位生活區 即時熱門文章