我之前曾问过这个问题Change PowerShell Console Font and Layout in Windows 10,但上一个问题没有明确的答案(使用不同的方法),我的新问题尝试通过不同的方法解决这个问题。
我意识到字体、缓冲区、布局信息存储在 Windows 控制台的 .lnk 文件中,即 PowerShell 或 CMD 控制台的 .lnk 文件与指向 URL 的 Web 链接或指向的快捷方式有很大不同文件系统中的文件/文件夹,尽管所有三种类型共享 .lnk 扩展名。
然后我想到我可以做以下事情:
PowerShell.lnk
PowerShell20.lnk
PowerShell20.lnk
的属性并将其更改为字体大小20并关闭属性。现在,我需要做的就是对两个 .lnk 文件进行位比较,以查看确切发生了什么变化,并将该信息保存到第二个 PowerShell 脚本中,我可以使用该脚本将此更改应用于第一个 .lnk 文件。 lnk,这样我就可以将这些更改应用到 any 控制台 .lnk。然后,我可以在任何新的 Windows 10 或 11 上使用该修改器脚本来完全按照我的需要调整属性,所有这些都来自 PowerShell。
以下内容几乎完成了所有这些工作,创建了修改器脚本,该脚本确实将更改应用于
PowerShell.lnk
但它不太有效,并且最终的 PowerShell.lnk
快捷方式已损坏。我们如何使用两个控制台快捷方式之间发现的位差异来构建一个通用脚本,该脚本可以在不破坏快捷方式的情况下更改控制台快捷方式字体(或其他属性)?
# Paths to the shortcut files
$originalShortcutPath = "$env:UserProfile\Desktop\PowerShell.lnk"
$modifiedShortcutPath = "$env:UserProfile\Desktop\PowerShell20.lnk"
$fixScriptPath = "$env:UserProfile\Desktop\FixPowerShell.ps1"
# Read shortcut files as binary data
$originalBytes = [System.IO.File]::ReadAllBytes($originalShortcutPath)
$modifiedBytes = [System.IO.File]::ReadAllBytes($modifiedShortcutPath)
# Find differing bits and generate fix script
$differences = @()
$fixScriptContent = @()
for ($i = 0; $i -lt $originalBytes.Length; $i++) {
$originalByte = $originalBytes[$i]
$modifiedByte = $modifiedBytes[$i]
for ($j = 0; $j -lt 8; $j++) {
$originalBit = ($originalByte -band ([math]::Pow(2, $j))) -shr $j
$modifiedBit = ($modifiedByte -band ([math]::Pow(2, $j))) -shr $j
if ($originalBit -ne $modifiedBit) {
$bitIndex = $i * 8 + $j
$differences += "Bit $bitIndex is different, has value: $modifiedBit"
$fixScriptContent += "Set-Content -Path '$originalShortcutPath' -Value ([System.BitConverter]::ToString([System.BitConverter]::ToInt32(@(Get-Content -Path '$originalShortcutPath' -Encoding Byte), 0) -bxor (1 -shl $bitIndex)), 0) -Encoding Byte -NoNewline"
}
}
}
# Write fix script
$fixScriptContent | Out-File -FilePath $fixScriptPath -Encoding ASCII
if ($differences.Count -eq 0) {
Write-Host "No differences found between the two files."
} else {
Write-Host "Listing every bit that is different in $($modifiedShortcutPath):"
$differences
Write-Host "Fix script generated at $fixScriptPath"
}
执行了以下操作:
FC.EXE /B
00000815: 14 18
符合我的预期,即 0x14=20 和 0x18=24。这将我带到以下 PowerShell 脚本:
$filePath = "$PSScriptRoot\CustomPowerShell.lnk"
$bytes = [System.IO.File]::ReadAllBytes($filePath)
$address = 0x7F1
$newValue = 20
if($bytes[$address] = 14) {
$bytes[$address] = 20
[System.IO.File]::WriteAllBytes($filePath, $bytes)
}
此脚本通过首先检查 0x7F1 处的值是否与预期值 14 匹配来修改
$filePath
中定义的文件的文件内容,如果是,则用 20 替换该值并将新文件内容写回开车。
只要 Windows 永远不会更改此快捷方式文件的内容,这就很好。但如果 Windows 将来确实提供了更改版本怎么办?
在进一步检查该文件时,我发现值 14 (0x0E) 仅在一个地方找到,即字体大小。
Windows 的未来版本似乎不太可能将此字体大小更改为其他内容,而且未来版本的快捷方式文件也不太可能由于字体大小以外的其他原因而包含值 0x0E (14) - 这就是此版本的原因脚本进来:
$filePath = "$PSScriptRoot\CustomPowerShell.lnk"
$bytes = [System.IO.File]::ReadAllBytes($filePath)
0x771..0x871 | & {
begin {
$ChangeCount = 0
}
process{
if($bytes[$_] -eq 14) {
$bytes[$_] = 20
$ChangeCount++
}
}
end {
if ($ChangeCount -eq 1) {
[System.IO.File]::WriteAllBytes($filePath, $bytes)
}
else {
Write-Host "ERROR: Found $ChangeCount instances of the value 14, where only 1 was expected. File not altered."
}
}
}
第二个版本假设以下内容:
第二个脚本将仅在从 0x771 到 0x871 的位置找到值 0x0E (14) 的一个实例时才修改快捷方式文件。如果它找到多个值 0x0E (14),或者找不到该值,则会报告失败并保持文件不变。