欢迎光临 Enjoy IT (ITECN.NET) 登录 | 注册 | 帮助

Windows PowerShell每周提示(34):列出计算机上所安装的TrueType字体

2008冬季脚本编写比赛中最受欢迎的项目之一是初级组的第二项活动,该活动要求你列出在计算机上所安装的所有字体。参加比赛的选手真的很喜欢这项活动,因为事实上他们中的很多人需要这样一个脚本来完成这件事:列出在计算机上安装的所有字体。

冬季脚本编写比赛内部消息. 那么脚本专家选择这项活动是因为我们知道很多人会对此感兴趣并从中获益?当然不,事实上,该活动是被设计成一项读取注册表的练习活动和字体并无关系。我们最后决定使用与字体有关的注册表键值只是因为该注册表键值:a)在其中有很多项;b)能在几乎所有版本的Windows的同一处找到。对很多人来说这项活动被证明是有趣和有用这件事只不过是一个愉快的意外事件。

当然,我们承认这件事也无妨。就如你所知的,我们始终都在计划和字体有关的事。

正如我们所注释的,活动2的解决方法需要你从注册表中读取字体信息。这没有什么错,但这导致了一个很明显的问题:是否有更好更“PowerShelly”的方法来列出字体信息而不是在注册表中费力的查找。当我们在这个问题上经过一段时间的摸索后,我们得到了以下结论:也许。

为什么是也许?好的,正像你即将看到的那样,Windows PowerShell使得从计算机上返回TrueType字体变得的确很轻而易举。我们没有找到的——至少还没有——是一种相对简单的方法来返回在你计算机上所安装的所有其它字体的列表(比如,OpenType字体)。如果你需要所有的字体,那么读取注册表仍然是需要做的事。

但是如果你只想得到TrueType字体:

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

$objFonts = New-Object System.Drawing.Text.InstalledFontCollection

$objFonts.Families

瞧见没?当我们说这件事的确很轻而易举时并没有在开玩笑吧?我们在这里所做的是创建一个.Net Framework System.Drawing.Text.InstalledFontCollection类的实例,一旦我们有了这个类的实例我们就回显Families属性的值。结果就是,得到类似以下内容的输出:

Abcdaire Enfantin

Agency FB

Aharoni

AIFragment

Algerian

Andalus

Angsana New

AngsanaUPC

aPapa

当然这没什么,我们还可以让这件事变得更简单。事实证明,我们可以使用一行代码来得到同样的结果:

(New-Object System.Drawing.Text.InstalledFontCollection).Families

很酷吧?

你知道,我们现在所想的是,这只不过是酷的一种方式。为什么?列出字体名这不错,我们现在知道AIFragmentAndalusaPapa这三个字体都安装在本地计算机上。但是这使我们开始思考。(脚本专家并不经常思考,但是一旦开始了就很难停止。)一份字体的列表这不错,然而更好的是一份不仅包括字体名而且还包括以该字体输入的文字的列表。如你所知,类似这样:

但是就我们所知没有办法来创建像这样的列表,一点也没有。

除非你使用Windows PowerShell来提取字体的集合,然后向Internet Explorer写入信息:

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

 

$objFonts = New-Object System.Drawing.Text.InstalledFontCollection

$colFonts = $objFonts.Families

 

$objIE = New-Object -com "InternetExplorer.Application"

$objIE.Navigate("about:blank")

$objIE.ToolBar = 0

$objIE.StatusBar = 0

$objIE.Visible = $True

 

$objDoc = $objIE.Document.DocumentElement.LastChild

 

foreach ($objFont in $colFonts)

    {

        $strHTML = $strHTML + "<font size='5' face='" + $objFont.Name + "'>" + $objFont.Name + "</font><br>"

    }

 

$objDoc.InnerHTML = $strHTML

我们在这里所做的是将计算机上所安装的所有TrueType字体提取成一个集合。然而,我们并不回显字体名称而是将该信息储存在名为$colFonts的变量中:

$objFonts = New-Object System.Drawing.Text.InstalledFontCollection

$colFonts = $objFonts.Families

在安全的把我们字体名称保存供后续使用后,我们使用这个代码块(及New-Object cmdlet)来创建一个空白(及可见)的Internet Explorer的实例:

$objIE = New-Object -com "InternetExplorer.Application"

$objIE.Navigate("about:blank")

$objIE.ToolBar = 0

$objIE.StatusBar = 0

$objIE.Visible = $True

你是对的:一个空白的Internet Explorer窗体并不是很有趣。因为记得这件事,所以我们下一步使用下面这行代码来创建Internet Explorer文档Body的对象引用:

$objDoc = $objIE.Document.DocumentElement.LastChild

我们然后建立起foreach循环来遍历集合中的每一个TrueType字体。在循环内,我们就执行这行代码:

$strHTML = $strHTML + "<font size='5' face='" + $objFont.Name + "'>" + $objFont.Name + "</font><br>"

这里我们构建了一个字符串值(使用标准的HTML格式)来列出字体名称并使用相关的字体样式。换句话说,Arial字体将以Arial样式列出;Times New Roman字体将以Times New Roman样式列出,等等。对于字符串本身,我们只是将已有值绑定到变量$strHTML的以下位置:

l   "<font size='5' face='"开始的尖括号作为标记的开始,然后设置字体大小为5,然后face参数等于我们列表中的下一个项目。

l   $objFont.Name。字体名称,恰好也是我们向face参数提供的值。

l   "'>"。与开始尖括号相对的结束标志。

l   $objFont.Name。字体名。这是出现在我们开始与结束标记之间的文字内容。

l   "</font><br>"。作为标记的结束,同时也带上了断行符。

换句话说,我们向$strHTML中附加的是类似以下的内容:

<font size='5' face='Arial'>Arial</font><br>

当我们循环完整个字体集合后,我们将Body对象的InnerHTML属性设为$strHTML

$objDoc.InnerHTML = $strHTML

最终结果就是,是的,你已经在我们的测试计算机上看到最终结果了。在你自己的计算机上尝试下并看下会发生什么吧。

这就是我们本周的所有内容。我们会在下周五再次相见。下周也是和字体有关的事?我们输了。无需多说,计划不是我们的强项,估计你们不得不亲自回来瞧一瞧我们到底带来了什么提示。

英文原文

http://www.microsoft.com/technet/scriptcenter/resources/pstips/mar08/pstip0328.mspx

已发表 2008年4月20日 18:30 作者 ghjconan

评论

禁止匿名发表评论