Fonts

This is a silent installer for distributing additional fonts. Always be sure to be entitled to use the fonts you are distributing.

Batch File Method

Basic info

To install new fonts on a Windows machine, you have to do two things:

  • copy the font file to %WINDIR%\Fonts\ directory,
  • add a registry entry.

Example Batch file

An example.bat file would look like this:

%COMSPEC% /c copy /Y "%SOFTWARE%\Fonts\*.TTF" "%WINDIR%\Fonts\"
regedit /s "%SOFTWARE%\Fonts\add-fonts.reg"


Example Registry file

An example registry file would look like this:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts]
"Frankfurt Gothic (TrueType)"="FRANKGON.TTF"


For Postscript Type 1 Fonts it is stored here:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Type 1 Installer\Type 1 Fonts]
"sxr Font"=hex(7):54,00,00,00,73,00,78,00,72,00,2e,00,50,00,46,00,4d,00,00,00,73,00,78,00,72,00,2e,00,50,00,46,00,42,00,00,00,00,00

Remember to copy both files to Fonts directory (here sxr.PFM and sxr.PFB)

Example XML install file for WPKG

<?xml version="1.0" encoding="UTF-8"?>
<packages>
<package id="additional-fonts" name="Additional fonts" revision="1" reboot="false" priority="950" execute="once">

  <install cmd='"%SOFTWARE%\Fonts\add-fonts.bat"' />

</package>
</packages>

VBScript Method

Example using a VBscript

The Microsoft Scripting Guys provide a .vbs solution that does not require a restart, as it copies the fonts using the shell object so Windows automatically installs the new fonts. Under some circumstances, this can require that the user acknowledge an Interactive Services Detection prompt.

<package id="additional-fonts" name="Additional fonts" revision="1" reboot="false" priority="950" execute="once">
  <install cmd='wscript.exe "%SOFTWARE%\Packages\Fonts\FontInstall.vbs"' />
</package>

FontInstall.vbs:

Const FONTS = &H14&

Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(FONTS)
MyDir = left(Wscript.ScriptFullName,len(Wscript.ScriptFullName)- len(Wscript.ScriptName)-1)

objFolder.CopyHere MyDir &"\MyNewFont.ttf"

Or, to install all .ttf, .otf, .pfm, .fon files from the folder containing your FontInstall.vbs script:

Const FONTS	= &H14&
 
Set objShell	= CreateObject("Shell.Application")
Set ofso	= CreateObject("Scripting.FileSystemObject")
 
SourceFolder	= ofso.GetParentFolderName(Wscript.ScriptFullName)
Set oSource	= objShell.Namespace(SourceFolder)
Set oWinFonts	= objShell.Namespace(FONTS)

Set regEx	= New RegExp
regEx.IgnoreCase = True
regEx.Pattern	= "([\w\s]+?)(_[^_]*)?(\.(ttf|otf|pfm|fon))$"
 
FOR EACH FontFile IN oSource.Items()
	fontFileName = ofso.GetFileName(FontFile.Path)
	IF regEx.Test(fontFileName) THEN
		Set objMatch = regEx.Execute(fontFileName)
		win7FontFileName = objMatch.Item(0).Submatches(0) & objMatch.Item(0).Submatches(2)
		localFontPath = oWinFonts.Self.Path & "\" & fontFileName
		win7LocalFontPath = oWinFonts.Self.Path & "\" & win7FontFileName
		IF NOT ofso.FileExists(localFontPath) AND NOT ofso.FileExists(win7LocalFontPath) THEN
			oWinFonts.CopyHere FontFile.Path
		END IF
	END IF
NEXT

Inno Method

Example Inno Setup Script

Because I had problems with the registry setting I found another way to install fonts by writing an installer. Inno Setup makes this easy and a script like the following will package a number of fonts into a pseudo-application.

[Files]
Source: C:\WINDOWS\Fonts\CALIBRI.TTF; DestDir: {fonts}; FontInstall: Calibri; Flags: onlyifdoesntexist uninsneveruninstall
Source: C:\WINDOWS\Fonts\FuturaStd-Book.otf; DestDir: {fonts}; FontInstall: FuturaStd-Book (OpenType); Flags: onlyifdoesntexist uninsneveruninstall fontisnttruetype
...

[Setup]
AppName=Font Installer
AppVerName=Font Installer 1.0
CreateAppDir=false
DisableProgramGroupPage=true
ShowLanguageDialog=no

The package definition would be

<package id="additional-fonts" name="Additional fonts" revision="10" reboot="false" priority="950">
  <check type="uninstall" condition="exists" path="Font Installer 1.0" />
  <install cmd='%SOFTWARE%\font-setup.exe /sp- /silent /norestart' />
  <upgrade cmd='%SOFTWARE%\font-setup.exe /sp- /silent /norestart' />
</package>

Example Inno Setup Script PS Type 1 Fonts

I tested this with success on Windows XP Machines with PS Type 1 Fonts. Copy the font and add the registry entry in the right section. After a reboot the font is fully installed. Adopt the silent install script for WPKG from above.

[Setup]
AppName=Font Installer
AppVerName=Font Installer 1.0
CreateAppDir=false
DisableProgramGroupPage=true
ShowLanguageDialog=no

[Files]
; FontInstall does not work with my SP3
Source: "BENSCNBL.PFB"; DestDir: "{fonts}"; Flags: onlyifdoesntexist
Source: "BENSCNBL.pfm"; DestDir: "{fonts}"; Flags: onlyifdoesntexist

[Registry]
; Create Registry entrys for the fonts
Root: HKLM; Subkey: "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Type 1 Installer\Type 1 Fonts"; ValueType: multisz; ValueName: "BentonSansCond Black"; ValueData: "T{break}BENSCNBL.pfm{break}BENSCNBL.PFB"; Flags: uninsdeletevalue

MS fontinst.exe Method

Microsoft has a very underused app called fontinst.exe. You can pass a .inf file as parameter to fontinst.exe and it will install a list of fonts for you.

The .inf file is formatted like this:

[fonts]
font01.TTF
font02.TTF
font03.TTF

Just pop the exe, ttf's and the inf in a folder and call it like this:

fontinst.exe /F MyFontName.inf

However, fontinst.exe appears to be a 16bit application, and will not run on an x64 system.

fontreg.exe Method

A simple method is using fontreg.exe from http://code.kliu.org/misc/fontreg/

Just copy the font files to the Windows font directory and call

fontreg.exe

Fontreg will check the directory and add the new fonts to the registry. It will also remove stale registry keys.

Alternativly call

fontreg.exe /copy

This will copy all font files from the current directory to the windows font directory and register them.

Example XML

Since WPKG doesn't support foreach loops or expanding lists, you might want to write a script to make package definitions if you have a lot of fonts to make packages for.

This package does not force a reboot, but the fonts it installs might not be visible to applications until after the computer's restarted.

<?xml version="1.0" encoding="UTF-8"?>
<packages>
  <package
     id="MyNiceFont"
     name="myfont"
     revision="1"
     reboot="false"
     priority="2">

    <variable name="FONTREG_PATH" value="%SOFTWARE%\tools\fontreg-2.1.3-redist\bin.x86-32\FontReg.exe" architecture="x86" />
    <variable name="FONTREG_PATH" value="%SOFTWARE%\tools\fontreg-2.1.3-redist\bin.x86-64\FontReg.exe" architecture="x64" />

    <check type="file" condition="exists" path="%WINDIR%\fonts\MyFontCGaugeItalic.otf" />
    <check type="file" condition="exists" path="%WINDIR%\fonts\MyFontDGaugeItalic.otf" />
    <check type="file" condition="exists" path="%WINDIR%\fonts\MyFontAGauge.otf" />
    <check type="file" condition="exists" path="%WINDIR%\fonts\MyFontBGauge.otf" />
    <!-- et cetera, one for each file -->

    <install cmd='"%COMSPEC%" /c robocopy /z /np /ndl /nfl /njh /njs "%SOFTWARE%\fonts\MyFont" "%WINDIR%\fonts" MyFontCGaugeItalic.otf MyFontDGaugeItalic.otf MyFontAGauge.otf MyFontBGauge.otf ' >
      <exit code="0" />
      <exit code="1" />
      <exit code="2" />
      <exit code="3" />
    </install>
    <install cmd="%FONTREG_PATH%" />

    <upgrade include="install" />

    <remove cmd='"%COMSPEC%" /c del "%WINDIR%\fonts\MyFontCGaugeItalic.otf"'>
      <exit code = "any" />
    </remove>
    <remove cmd='"%COMSPEC%" /c del "%WINDIR%\fonts\MyFont\DGaugeItalic.otf"'>
      <exit code = "any" />
    </remove>
    <remove cmd='"%COMSPEC%" /c del "%WINDIR%\fonts\MyFontAGauge.otf"'>
      <exit code = "any" />
    </remove>
    <remove cmd='"%COMSPEC%" /c del "%WINDIR%\fonts\MyFontBGauge.otf"'>
      <exit code = "any" />
    </remove>
    <!-- etc, one for each file -->

    <remove cmd="%FONTREG_PATH%" />
  </package>

</packages>

MSI package Method

Create MSI package with fonts for silent install and unistall. You will need:

Example

Clone this repository and put your fonts to FontsDir. Then run make and install created package.

msiexec /qn /i fonts-13.04.3001.msi /L*v! "%temp%\fonts-install-log.txt"