Windows 7/PS2.0 New-Object System.Drawing.Text.PrivateFontCollection not working, but does work in Windows 10

Viewed 129

I have successfully used this in Windows 10, and it reports the font family name as expected.

$fontFile = '\\px\Rollouts\Misc\Fonts\Arial Narrow\ARIALN.TTF'
$fontCol = [System.Drawing.Text.PrivateFontCollection]::new()
$fontCol.AddFontFile($fontFile)
Write-Host "$($fontCol.Families.Name)"

However, when I switch to using New-Object, to support Windows 7/PS2, like so

$fontFile = '\\px\Rollouts\Misc\Fonts\Arial Narrow\ARIALN.TTF'
$fontCol = New-Object System.Drawing.Text.PrivateFontCollection
$fontCol.AddFontFile($fontFile)
Write-Host "$($fontCol.Families.Name)"

It only works in Windows 10. In Windows 7 I don't get an error, but I also don't get a font family name.

But the Microsoft documentation suggest that the class is available all the way back to .NET Framework 1.1. And the Families property is documented as going back that far too. So, am I doing something incorrectly, or missing some evidence somewhere that this isn't workable in Ps2.0, or...?

Interestingly '$fontCol.Families' shows the Name property is there, and properly populated. So, it seems I need to access it differently for Windows 7?

1 Answers

While it might be easy to overlook, your code actually makes use of a feature that was only introduced in Windows PowerShell 3.0 - namely property enumeration!

$fontCol.Families is an enumerable collection, so when you do $fontCol.Families.Name in PowerShell 5.1 on Windows 10, PowerShell goes "$fontCol.Families doesn't have that property, but let my try and enumerate the items in the collection and resolve the Name value of those instead"

But in PowerShell 2.0, the runtime engine simply goes "the collection doesn't have a Name property" and the expression evaluates to $null.

Given that you're only importing 1 font in your example, you can do:

$fontCol.Families[0].Name

Or if you want to support multiple fonts in the collection at once, manually enumerate the collection:

$fontCol.Families |ForEach-Object {$_.Name}
Related