我正在尝试制作一个添加一些注册表项的 powershell 脚本。 但是(我认为)我未能将 HKCR 下的 * 文件夹识别为通配符 powershell 的目标是在 Windows 11 的右键单击上下文菜单中为我提供“使用 Notepad++ 打开”选项,最好(但不是必需)仅适用于 .bat 和 .cmd 文件。
前 3 个键处理得很好,但是一旦需要处理第 4 个键,它似乎会永远运行,不再生成任何输出,并且脚本也不会完成。
我认为导致问题的行是: 'HKCR:`*\shell\Open with Notepad++'
我的原始代码在星号之前没有反引号,但是在星号之前没有单反引号和双反引号,问题仍然相同。
谢谢您的帮助!
# Check if 'HKEY_CLASSES_ROOT' path has been set
If (Get-PSDrive |
Where {
($PSitem.Name -Match 'HKCR') -and
($PSitem.Root -Match 'HKEY_CLASSES_ROOT')
}
)
{
}
Else {
New-PSDrive -PSProvider registry -Root "HKEY_CLASSES_ROOT" -Name "HKCR" >$Null 2>&1
}
# Define the registry values to add/update
$registryValues = @(
@{
Path = 'HKCR:\batfile\shell\Open with\command'
Name = '(default)'
Value = '{09799AFB-AD67-11d1-ABCD-00C04FC30936}'
},
@{
Path = 'HKCR:\batfile\shell\edit\command'
Name = '(default)'
Value = '"C:\Program Files (x86)\Notepad++\notepad++.exe %1"'
},
@{
Path = 'HKCR:\cmdfile\shell\edit\command'
Name = '(default)'
Value = '"C:\Program Files (x86)\Notepad++\notepad++.exe %1"'
},
@{
Path = 'HKCR:\`*\shell\Open with Notepad++'
Name = 'Icon'
Value = 'C:\Program Files (x86)\Notepad++\notepad++.exe'
},
@{
Path = 'HKCR:\`*\shell\Open with Notepad++\command'
Name = '(default)'
Value = '"C:\Program Files (x86)\Notepad++\notepad++.exe %1"'
}
)
# Function to create or update registry values
function Set-RegistryValue {
param(
[string]$Path,
[string]$Name,
[string]$Value
)
# Create the key if it does not exist
If (-NOT (Test-Path $Path)) {
New-Item -Path $Path -Force | Out-Null
}
# Now set the value
New-ItemProperty -Path $Path -Name $Name -Value $Value -PropertyType String -Force
}
# Add or update the registry values
foreach ($entry in $registryValues) {
Set-RegistryValue -Path $entry.Path -Name $entry.Name -Value $entry.Value
}
tl;博士
唯一需要的立即修复就是更换
New-Item -Path $Path -Force
与 New-Item -Path $Path.Replace('`', '') -Force
- 请参阅底部部分的说明。
但是,我建议重构您的代码以在整个代码中使用literal(逐字)路径,如下一节所示。
由于您只处理概念上的literal(逐字)路径,因此我建议避免尝试escapewildcard元字符,例如
*
与`
(`*
),这不仅简化了代码,而且考虑到转义行为不一致的问题,也更加健壮(请参阅 GitHub 问题 #7999)。
请注意以下代码中的以下内容:
-LiteralPath
用于代替 -Path
以及支持此区别的所有 cmdlet(文字(逐字)与基于通配符的路径)。
New-Item
是使用的 cmdlet,它仅有一个 -Path
参数,并且它对传递给它的参数的处理是不一致:
-Name
参数,则使用 -Path
参数字面意义。-Name
参数时,-Path
参数被解释为 通配符模式。由于所有路径现在都由目标 cmdlet 字面解释,因此无需将 *
转义为
`*
。
HKCR:
drive,
HKEY_CLASSES_ROOT
配置单元是直接目标,只需在关键路径前加上 PowerShell 提供程序的名称前缀即可,即
registry::HKEY_CLASSES_ROOT
# Define the registry values to add/update
$registryValues = @(
# ... first 2 entries omitted for brevity
@{
LiteralPath = 'registry::HKEY_CLASSES_ROOT\*\shell\Open with Notepad++'
Name = 'Icon'
Value = 'C:\Program Files (x86)\Notepad++\notepad++.exe'
},
@{
LiteralPath = 'registry::HKEY_CLASSES_ROOT\*\shell\Open with Notepad++\command'
Name = '(default)'
Value = '"C:\Program Files (x86)\Notepad++\notepad++.exe %1"'
}
)
# Function to create or update registry values
function Set-RegistryValue {
param(
[string]$LiteralPath,
[string]$Name,
[string]$Value
)
# Create the key if it does not exist
If (-NOT (Test-Path -LiteralPath $LiteralPath)) {
New-Item -Path $LiteralPath -Force | Out-Null
}
# Now set the value
New-ItemProperty -LiteralPath $LiteralPath -Name $Name -Value $Value -PropertyType String -Force
}
# Add or update the registry values
foreach ($entry in $registryValues) {
Set-RegistryValue -LiteralPath $entry.Path -Name $entry.Name -Value $entry.Value
}
你尝试过的:
New-Item
(在没有
-Name
)的情况下,解释其-Path
参数字母
(verbatim),
New-Item -Path $Path -Force
创建了关键路径leterally以
`*
而不是从*
.开始。 由于我不知道的原因,您意外转义的关键路径还会导致执行速度过慢,就好像
`
之前的*
。
New-ItemProperty
-Path
参数does将其参数解释为通配符模式,因此您的转义路径原则上按预期工作,但由于
New-Item
命令创建了与预期不同的不同父键,因此整个New-ItemProperty
命令失败了。