我正在开发一个 Windows 程序,该程序将值添加到 PATH 环境变量中。PATH 变量以分号 ( ;
) 分隔,可以包含任何有效的文件夹路径。但是,;
在文件夹路径中有效,因此在将包含分号的路径添加到路径时必须用双引号括起来:
C:\Program Files (x86);"C:\;My Folder";C:\Program Files
为了避免分号问题,我的程序将所有路径括在双引号中。但是,最近有人告诉我, Powershell 无法处理 PATH 变量中的引号值,因为它将引号视为普通字符:
我查看了 PowerShell 如何处理 Path 变量(基于此代码:PowerShell/PowerShell@16176ef/src/System.Management.Automation/engine/CommandDiscovery.cs#L1187-L1240)。据我所知,PowerShell 不会删除双引号 - 它只是在看到分号的地方拆分路径。
因此,PATH 值C:\Program Files (x86);"C:\;My Folder";C:\Program Files
被错误地解释为如下形式(如果我正确理解了发生了什么的话):
C:\Program Files (x86)
"C:\
My Folder"
C:\Program Files
以下视频演示了该行为(该行为仅发生在 Powershell 中,不发生在 cmd 中): https: //www.mediafire.com/file/aih2ky9fz07x5w0/powershellpathwithsemicolonsbug.mp4/file
我的程序处理这个问题的最佳方法是什么?而且,更紧迫的是,为什么 Powershell 不能处理带有引号的 PATH 值(即使 CMD 可以)?使用手动方式编辑路径值以包含分号 - Edit the system environment variables -> Path -> Edit
- 会导致 Windows 自动将所需路径括在引号中,从而破坏 Powershell。所以这不是我的程序或情况的问题 - 这是 Powershell 处理 PATH 方式的固有问题。
Powershell 中的这种行为是故意的吗?有没有解决方法,或者我必须妥协,要么 A. 将包含分号的路径括在引号中并允许这种错误行为发生,要么 B. 不允许在 PATH 中使用分号?
iRon 的有用答案向您展示了如何
$env:PATH
以尊重双引号条目的方式手动解析值。至于你的问题:
我不这么认为,而且这可以说是一个错误,正如GitHub 问题 #24002中讨论的那样;引用这条评论(我的):
假设已打开短(8.3)文件名创建功能(默认情况下处于打开状态),您可以利用这样一个事实:包含的文件名
;
始终会为其生成一个短名称,即使它的字符数不超过 8 个。在基本名称中,扩展名包含 3 个或更少的字符,并且保证生成的短名称不包含;
或空格;例如:换句话说:
将那些
$env:PATH
由于嵌入而需要"..."
括起来以消除歧义的条目替换;
为其短版本(8.3).........并删除其周围的双引号。
请注意,特定的 8.3 名称可能会因存在具有类似长名称的其他文件夹而有所不同,因此应在每台机器上确定它们。
据我所知,PowerShell 根本没有任何本机命令(或自动变量)可以为您返回环境路径中的路径列表。这意味着您必须自己编写脚本。
如果您选择简单的方法,只是像上面那样拆分环境路径,那么
$env:Path -split ';'
最终可能会遇到包含分号的文字路径问题。这意味着您必须想出一种更聪明的方法来拆分路径或使用现有的转换器/解析器。知道该
ConvertFrom-Csv
cmdlet 与您想要执行的操作非常接近,您可以考虑使用它:解释
$Env:Path
包含一个字符串,其中所有环境路径都用分号 (;
)连接起来ConvertFrom-Csv -Delimiter ';'
使用分号作为分隔符来分割环境路径,同时也考虑分隔符周围的引号值和空格。-Header (0..99)
为每个值定义一个数字标题(从0
最多到)99
ConvertFrom-Csv
返回一个PSCustomObject
,要检索它的所有属性,可以使用隐藏PSObject
属性:.PSObject.Properties
.Value
属性只会返回所有不为 的值$Null
。请注意,这是建立在不一致的基础上的,其中考虑了文件ConvertFrom-Csv
最后一行中的最后一个空单元格(而不是空字符串),请参阅:#17702csv
$Null