Downloads
97911.zip

 Executive Summary:

Windows automatically registers fonts you drag and drop into the Fonts folder. If you use a VBScript or Windows PowerShell script rather than Windows Explorer to copy fonts into that folder, you don't get the automatic registration unless you use the Shell.Application object. Here are the three steps you need to follow when using the Shell.Application object to install fonts through a VBScript or Windows PowerShell script.

Windows automatically recognizes fonts you drag and drop into the Fonts folder. However, if you try to install fonts by copying the file at a command prompt or through a script, you can't see them in the Fonts folder or in the Windows font listings. The problem is that fonts need to be registered. When you drag and drop them into the Fonts folder, the Windows Explorer shell copy operation triggers the registration process. If you don't use Windows Explorer, you don't get the automatic registration.

Fortunately, you can use Windows Explorer to register fonts when copying them through a script. The trick is to use the Shell.Application COM object, which is essentially what Windows Explorer uses during a drag-and-drop operation. With the Shell.Application object, you can connect to special namespaces in Windows such as the Fonts folder and perform special operations (e.g., copying) in that folder. You won't see a file copy onscreen, but it works.

Here are the steps you need to follow:

  1. Get a reference to the Shell.Application object.
  2. Use the Shell.Application object's NameSpace method to connect to the Fonts folder. Each special namespace has a numeric identifier known as a CSIDL that you use with the NameSpace method. For the Fonts folder, the CSIDL is 20. Although I won't be covering other folders or the techniques for accessing them here, if you're interested in CSIDL details, you can see some of the values listed in the ShellSpecialFolderConstants enumeration in the ShellSpecialFolderConstants Enumerated Type Web page (http://msdn2.microsoft.com/en-us/library/bb774096.aspx). For programming use, these numeric constants are deprecated in favor of globally unique identifiers (GUIDs) called KNOWNFOLDERIDs, which identify standard folders registered with the system. (For more information about these GUIDs, go to http://msdn2.microsoft.com/en-us/library/bb762584.aspx.) I'm using the CLSID values here because they're easier to use and backward compatible.
  3. Use the Shell.Application object's CopyHere method to copy the file.

For example, the following VBScript code snippet installs the font in the file ManchuFont2005.ttf from the SourceForge Manchu Font project (http://sourceforge.net/project/showfiles.php?group_id=118623):

Set sa = CreateObject("Shell.Application")
Set fonts  = sa.NameSpace(20)
fonts.CopyHere "C:\tmp\ManchuFont2005.ttf"

You can install the same font with this PowerShell command:

$sa =  new-object -comobject shell.application
$Fonts =  $sa.NameSpace(0x14)
$Fonts.CopyHere ("C:\tmp\ManchuFont2005.ttf")

In this command, I'm using the hexadecimal equivalent of 20—that is, 0x14—as the CLSID value. With PowerShell, you can extend this operation and install as many fonts as you want by using the pipeline and the ForEach-Object cmdlet, like this:

gci  "C:\dsp\Special Fonts\*.ttf" | %\{$fonts.CopyHere($_.FullName)\}

You can even put the PowerShell code into a script, as Install-Font.ps1 in Listing 1 shows. This means the only thing you need to do is get a collection of fonts and pipe them into Install-Font.ps1 using code such as

gci  "C:\dsp\Special Fonts\*.ttf" | Install-Font

Note that installing fonts is a privileged operation in Windows Vista. If you run the script from a nonprivileged account, the process won't necessarily fail; the CopyHere attempt triggers the User Account Control (UAC) dialog box, allowing it to work. Unfortunately, this happens for each and every font file in the installation set. I also recently encountered a situation on 64-bit Vista machine in which the UAC dialog box wasn't invoked and the installation silently failed. For these reasons, it's better to open a PowerShell session as administrator and use the script from there to install the fonts without any prompting.

 Share Your Scripting Experiences:

Share your scripting discoveries, comments, solutions to problems, and experiences with products. Email your contributions to r2r@scriptingprovip.com. Please include your full name and phone number. We edit submissions for style, grammar, and length. If we print your submission, you'll get $100.