I am trying to refine this to get only the Title and Type attributes for font files. I have used that function to verify that my target file has those attributes, and I have this
$shell = new-object -com shell.application
$folder = $shell.namespace("\\px\Rollouts\Misc\Fonts\Arial")
$item = $folder.Items().Item('arial.ttf')
$item.ExtendedProperty('Title')
$item.ExtendedProperty('Type')
which correctly returns the Type, but not the Title. So, I have two questions.
1: What is the difference between those two properties, that one works and one doesn't?
and
2: Is there a better, native PowerShell or PS with .NET way too get at this info, that doesn't require putting to COM? My searching shows examples of using the COM kludge even in C#, which just seems like madness.
EDIT: I can use this
$folder.getDetailsOf($item, 21)
$folder.getDetailsOf($item, 191)
but I wonder if those numbers really are universal. My first thought was that I would prefer to use the property name, but then I though, is the name the same on a French machine? Ah, nothing's easy. :)
EDIT 2: Nope, not universal. That 191 reference for the font type is 182 in Windows 7. Ugh.
EDIT 3: OK, I have this, and it works on Windows 7 & Windows 10.
$shell = new-object -com shell.application
$folder = $shell.namespace("\\px\Rollouts\Misc\Fonts\Arial")
$item = $folder.Items().Item('arial.ttf')
foreach ($i in 0..266) {
if ($folder.getDetailsOf($folder.items, $i) -eq 'Title') {
$title = "Title: $($folder.getDetailsOf($item, $i))"
}
if ($folder.getDetailsOf($folder.items, $i) -eq 'Type') {
$type = "Type: $($folder.getDetailsOf($item, $i))"
}
if ($title -and $type) {
break
}
}
$title
$type
Performance is acceptable, so if someone can verify that this will work on machines with alternate languages I guess I have A solution. But would still love to hear about a GOOD solution.
EDIT 4: OK, this is getting ever more complicated. The [Windows.Media.GlyphTypeface]
approach was looking good for Arial. But then I looked at You Gothic (YuGothM.ttc), which is in the registry as Yu Gothic Medium & Yu Gothic UI Regular (TrueType)
, and that string can't even be constructed from data in the file. I am a bit at a loss for how one is to start from a file and end up with a font that is installed for all users exactly the same way it would have been before Microsoft @$%#$ed this up. I mean, I CAN do it now for English, but I really want universal support. What's even more odd is the fact that Yu Gothic isn't even available in Wordpad to test if getting the registry property name right is even important. But one that is is sitka.ttc, which uses Sitka Small & Sitka Text & Sitka Subheading & Sitka Heading & Sitka Display & Sitka Banner (TrueType)
. I changed that to just Sitka Small, which is available via the Win32FamilyNames property, and that seems to work, the others like Sitka Display and Sitka Heading are still available in Wordpad. But does that suggest that the name of the property in the registry is somewhat arbitrary? And it still begs the question, when installing with right click Install how is Windows determining what to call this stuff? It has to be info in the file, right?
EDIT 5: Based on @filimonic answer I now have this, and it is SOOOO close. Odd thing is that with Segoe UI Light the weight is reported as 350. I guess I'll need to test the weight and not use it if it's an integer. Likely I need to test every font and see what they all report, and hope integer is a viable filter.
$file = '\\Localhost\c$\Windows\Fonts\seguisli.ttf'
$glyph = [System.Windows.Media.GlyphTypeface]::new([uri]::new($file))
if ($null -eq ($familyNames = $glyph.Win32FamilyNames['en-us'])) {
$familyNames = $gi.Win32FamilyNames.Values.Item(0)
}
$weight = $glyph.Weight
$style = $glyph.Style
$familyNames
$weight
$style