【发布时间】:2025-12-07 15:55:01
【问题描述】:
我正在尝试优化 this 以仅获取字体文件的 Title 和 Type 属性。我已经使用该函数来验证我的目标文件是否具有这些属性,并且我有这个
$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')
正确返回类型,但不返回标题。所以,我有两个问题。
1:这两个属性有什么区别,一个有效,一个无效?
和
2: 有没有更好的原生 PowerShell 或带有 .NET 的 PS 方式也可以获取此信息,而不需要放入 COM?我的搜索显示了即使在 C# 中也使用 COM kludge 的示例,这看起来很疯狂。
编辑:我可以用这个
$folder.getDetailsOf($item, 21)
$folder.getDetailsOf($item, 191)
但我想知道这些数字是否真的是通用的。我的第一个想法是我更喜欢使用属性名称,但后来我想,法语机器上的名称是否相同?啊,没有什么是容易的。 :)
编辑 2: 不,不是通用的。字体类型的 191 引用在 Windows 7 中是 182。呃。
编辑 3: 好的,我有这个,它适用于 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
性能是可以接受的,所以如果有人可以验证这将在使用其他语言的机器上工作,我想我有一个解决方案。但仍然很想听听一个好的解决方案。
编辑 4:好的,这变得越来越复杂。 [Windows.Media.GlyphTypeface] 方法看起来很适合 Arial。但后来我查看了 You Gothic (YuGothM.ttc),它在注册表中为 Yu Gothic Medium & Yu Gothic UI Regular (TrueType),甚至无法从文件中的数据构造该字符串。对于如何从文件开始并最终为所有用户安装的字体与 Microsoft @$%#$ 之前完全相同的方式,我有点不知所措。我的意思是,我现在可以用英语做,但我真的想要普遍的支持。更奇怪的是,Yu Gothic 甚至无法在写字板中测试获取正确的注册表属性名称是否重要。但是其中一个是sitka.ttc,它使用Sitka Small & Sitka Text & Sitka Subheading & Sitka Heading & Sitka Display & Sitka Banner (TrueType)。我将其更改为仅 Sitka Small,可通过 Win32FamilyNames 属性获得,这似乎有效,其他像 Sitka Display 和 Sitka Heading 仍然在写字板中可用。但这是否表明注册表中的属性名称有些随意?它仍然引出了一个问题,当使用右键单击安装时,Windows 是如何确定调用这些东西的?它必须是文件中的信息,对吧?
编辑 5:基于@filimonic 的回答,我现在有了这个,而且非常接近。奇怪的是,使用 Segoe UI Light 时,重量报告为 350。我想我需要测试重量,如果它是整数则不要使用它。可能我需要测试每种字体并查看它们都报告了什么,并希望整数是一个可行的过滤器。
$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
【问题讨论】:
-
也许
[Windows.Media.GlyphTypeface]::new('\\Path\To\arial.ttf')提供了您需要的属性? -
@Theo,这是部分的,因为 FamilyNames 似乎与 Title 匹配,但没有类型信息。当需要手动添加字体以绕过 Microsoft @%#$ing 安装字体并重定向到当前用户时,我需要将注册表中的属性名称格式化为 Arial (TrueType),所以我想提取标题/面部如果可能,直接从文件中输入名称和类型。
-
输入信息
$item.ExtendedProperty('Type')仅依赖于文件扩展名。您可以尝试将 any.txt文件重命名为.ttf,您将得到TrueType font file。这是一个垃圾信息,IMO。正如@Theo 所说,依靠GlyphTypeface。如果需要,请保留文件扩展名$ext = [System.IO.Path]::GetExtension($path) -
@filimonic 好的,我开始走这条路,但现在我遇到了一个新难题,请参阅编辑#4。
-
@Gordon,你的最终结果是什么?你开始谈论安装等。如果你想列出 INSTALLED 字体,它比列出文件夹更容易。我的意思是也许你走错路了
标签: powershell