如何在PowerShell中获取OpenType字体的准确名称
Great question! That "Bold" suffix comes from the font's subfamily name (stored in the font's internal Name Table), which defines the specific style/weight variant of the font family. Here's how to get that full friendly name programmatically in PowerShell, matching what shows up in the registry:
Why Your Original Code Only Returns the Family Name
The $fontCollection.Families[-1].Name call grabs just the base font family name (like "FreightSansLFPro"), but the registry entry combines this with the font's subfamily (e.g., "Bold", "Italic") and font type (TrueType/OpenType) to create the full display name.
How to Get the Full Friendly Name
The most reliable way to pull the exact names Windows uses is to read the font's internal Name Table directly. For PowerShell, using the System.Windows.Media.Typeface class (from the PresentationCore assembly) works perfectly for this—it accesses the same metadata Windows uses when installing fonts.
Here's a complete script that will output the exact registry-friendly name for each of your fonts:
# Load required .NET assemblies Add-Type -AssemblyName PresentationCore # Define your font file paths $fontPaths = @( "C:\Windows\Fonts\FreigSanLFProBol.otf", "C:\Windows\Fonts\FreigSanLFProBoo.otf", "C:\Windows\Fonts\FreigSanLFProBooIta.otf" ) foreach ($path in $fontPaths) { $file = Get-Item $path # Create a Typeface object pointing to the font file $fontUri = [System.Uri]"file:///$($file.FullName)" $typeface = New-Object System.Windows.Media.Typeface($fontUri) # Get the English language names (matches Windows' display) $lang = [System.Windows.Media.XmlLanguage]::GetLanguage("en-US") $familyName = $typeface.FamilyNames[$lang] $subFamilyName = $typeface.FaceNames[$lang] # Determine if it's OpenType or TrueType $fontType = if ($file.Extension -match '\.otf$') { "OpenType" } else { "TrueType" } # Build the full registry name $fullDisplayName = "$familyName $subFamilyName ($fontType)" # Output results Write-Host "Font File: $($file.Name)" Write-Host "Registry Name: $fullDisplayName`n" }
What's Happening Here?
- Family Name: Comes from the font's Name Table ID 1 (the base family identifier)
- Subfamily Name: Comes from Name Table ID 2 (defines weight/style like "Bold", "Italic", or "Regular")
- Font Type: Determined by the file extension (OTF = OpenType, TTF = TrueType), matching how Windows labels it in the registry
This will give you the exact string you see in the registry entry (like "FreightSansLFPro Bold (TrueType)") for each font file.
If you need to stick with System.Drawing instead of PresentationCore, you can infer the style from the FontFamily properties, but it's less flexible (it only gives boolean values for IsBold/IsItalic, not nuanced weights like "Light" or "Black"):
Add-Type -AssemblyName System.Drawing $path = "C:\Windows\Fonts\FreigSanLFProBol.otf" $fontCollection = New-Object System.Drawing.Text.PrivateFontCollection $fontCollection.AddFontFile((Get-Item $path).FullName) $family = $fontCollection.Families[-1] $displayName = $family.Name if ($family.IsBold) { $displayName += " Bold" } if ($family.IsItalic) { $displayName += " Italic" } $fontType = if ((Get-Item $path).Extension -match '\.otf$') { "OpenType" } else { "TrueType" } $fullDisplayName = "$displayName ($fontType)" Write-Host $fullDisplayName
Final Note
Windows uses the English-language names from the font's Name Table by default for registry entries, which is why we specify en-US in the Typeface method. This ensures consistency with what you see after manual installation.
内容的提问来源于stack exchange,提问作者nmcspadden

