Fonts
This is a silent installer for distributing additional fonts. Always be sure to be entitled to use the fonts you are distributing.
Contents
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"