Added support for per-user fonts on Windows 10 Version 1803 and later.

This commit is contained in:
Martijn Laan 2020-07-03 10:05:28 +02:00
parent 87e306ba1d
commit 767dbb835d
11 changed files with 103 additions and 51 deletions

View File

@ -320,6 +320,7 @@ This " contains " embedded " quotes
<keyword value="{autocf64}" anchor="autocf64" />
<keyword value="{autodesktop}" anchor="autodesktop" />
<keyword value="{autodocs}" anchor="autodocs" />
<keyword value="{autofonts}" anchor="autofonts" />
<keyword value="{autopf}" anchor="autopf" />
<keyword value="{autopf32}" anchor="autopf32" />
<keyword value="{autopf64}" anchor="autopf64" />
@ -352,6 +353,7 @@ This " contains " embedded " quotes
<keyword value="{dotnet4032}" anchor="dotnet4032" />
<keyword value="{dotnet4064}" anchor="dotnet4064" />
<keyword value="{drive:...}" anchor="drive" />
<keyword value="{commonfonts}" anchor="commonfonts" />
<keyword value="{fonts}" anchor="fonts" />
<keyword value="{group}" anchor="group" />
<keyword value="{groupname}" anchor="groupname" />
@ -383,6 +385,7 @@ This " contains " embedded " quotes
<keyword value="{userdesktop}" anchor="userdesktop" />
<keyword value="{userdocs}" anchor="userdocs" />
<keyword value="{userfavorites}" anchor="userfavorites" />
<keyword value="{userfonts}" anchor="userfonts" />
<keyword value="{userinfoname}" anchor="userinfoname" />
<keyword value="{userinfoorg}" anchor="userinfoorg" />
<keyword value="{userinfoserial}" anchor="userinfoserial" />
@ -487,9 +490,9 @@ For example: If you used <tt>{src}\MYPROG.EXE</tt> on an entry and the user is i
<p>Temporary directory used by Setup or Uninstall. This is <i>not</i> the value of the user's TEMP environment variable. It is a subdirectory of the user's temporary directory which is created by Setup or Uninstall at startup (with a name like "C:\WINDOWS\TEMP\IS-xxxxx.tmp"). All files and subdirectories in this directory are deleted when Setup or Uninstall exits. During Setup, this is primarily useful for extracting files that are to be executed in the [Run] section but aren't needed after the installation.</p>
</dd>
<dt><b><a name="fonts">{fonts}</a></b></dt>
<dt><b><a name="commonfonts">{commonfonts}</a></b></dt>
<dd>
<p>Fonts directory. Normally named "FONTS" under the Windows directory.</p>
<p>Fonts directory. Normally named "Fonts" under the Windows directory.</p>
</dd>
<dt><b><a name="dao">{dao}</a></b></dt>
@ -589,6 +592,11 @@ For example: If you used <tt>{src}\MYPROG.EXE</tt> on an entry and the user is i
<p>The path to the current user's Favorites folder. (There is no common Favorites folder.)</p>
</dd>
<dt><b><a name="userfonts">{userfonts}</a></b></dt>
<dd>
<p>The path to the current user's Fonts folder. Only Windows 10 Version 1803 and later supports <tt>{userfonts}</tt>. Same directory as <tt>{localappdata}\Microsoft\Windows\Fonts</tt>.</p>
</dd>
<dt><b><a name="userpf">{userpf}</a></b></dt>
<dd>
<p>The path to the current user's Program Files directory. Only Windows 7 and later supports <tt>{userpf}</tt>; if used on previous Windows versions, it will translate to the same directory as <tt>{localappdata}\Programs</tt>.</p>
@ -640,6 +648,7 @@ For example: If you used <tt>{src}\MYPROG.EXE</tt> on an entry and the user is i
<tr><td><tt><a name="autocf64">autocf64</a></tt></td><td><tt>commoncf64</tt></td><td><tt>usercf</tt></td></tr>
<tr><td><tt><a name="autodesktop">autodesktop</a></tt></td><td><tt>commondesktop</tt></td><td><tt>userdesktop</tt></td></tr>
<tr><td><tt><a name="autodocs">autodocs</a></tt></td><td><tt>commondocs</tt></td><td><tt>userdocs</tt></td></tr>
<tr><td><tt><a name="autofonts">autofonts</a></tt></td><td><tt>commonfonts</tt></td><td><tt>userfonts</tt></td></tr>
<tr><td><tt><a name="autopf">autopf</a></tt></td><td><tt>commonpf</tt></td><td><tt>userpf</tt></td></tr>
<tr><td><tt><a name="autopf32">autopf32</a></tt></td><td><tt>commonpf32</tt></td><td><tt>userpf</tt></td></tr>
<tr><td><tt><a name="autopf64">autopf64</a></tt></td><td><tt>commonpf64</tt></td><td><tt>userpf</tt></td></tr>
@ -660,6 +669,7 @@ For example: If you used <tt>{src}\MYPROG.EXE</tt> on an entry and the user is i
<tr><td><tt><a name="cf">cf</a></tt></td><td><tt>commoncf</tt></td></tr>
<tr><td><tt><a name="cf32">cf32</a></tt></td><td><tt>commoncf32</tt></td></tr>
<tr><td><tt><a name="cf64">cf64</a></tt></td><td><tt>commoncf64</tt></td></tr>
<tr><td><tt><a name="fonts">fonts</a></tt></td><td><tt>commonfonts</tt></td></tr>
<tr><td><tt><a name="pf">pf</a></tt></td><td><tt>commonpf</tt></td></tr>
<tr><td><tt><a name="pf32">pf32</a></tt></td><td><tt>commonpf32</tt></td></tr>
<tr><td><tt><a name="pf64">pf64</a></tt></td><td><tt>commonpf64</tt></td></tr>
@ -1624,11 +1634,11 @@ ExternalSize: 1048576; Flags: external
<param name="FontInstall">
<p>Tells Setup the file is a font that needs to be installed. The value of this parameter is the name of the font as stored in the registry or WIN.INI. This must be exactly the same name as you see when you double-click the font file in Explorer. Note that Setup will automatically append " (TrueType)" to the end of the name.</p>
<p>If the file is not a TrueType font, you must specify the flag <tt>fontisnttruetype</tt> in the Flags parameter.</p>
<p>It's recommended that you use the flags <tt>onlyifdoesntexist</tt> and <tt>uninsneveruninstall</tt> when installing fonts to the {fonts} directory.</p>
<p>To successfully install a font, the user must be a member of the Administrators groups.</p>
<p>For compatibility with 64-bit Windows, fonts should not be installed to the <tt>{sys}</tt> directory. Use <tt>{fonts}</tt> as the destination directory instead.</p>
<p>It's recommended that you use the flags <tt>onlyifdoesntexist</tt> and <tt>uninsneveruninstall</tt> when installing fonts to the {autofonts} directory.</p>
<p>If the installation is running in <link topic="admininstallmode">non administrative install mode</link>, Windows 10 Version 1803 or later is required successfully install a font.</p>
<p>For compatibility with 64-bit Windows, fonts should not be installed to the <tt>{sys}</tt> directory. Use <tt>{autofonts}</tt> as the destination directory instead.</p>
<example>
<pre>Source: "OZHANDIN.TTF"; DestDir: "{fonts}"; FontInstall: "Oz Handicraft BT"; Flags: onlyifdoesntexist uninsneveruninstall</pre>
<pre>Source: "OZHANDIN.TTF"; DestDir: "{autofonts}"; FontInstall: "Oz Handicraft BT"; Flags: onlyifdoesntexist uninsneveruninstall</pre>
</example>
</param>

View File

@ -1892,7 +1892,7 @@ end;</pre>
</function>
<function>
<name>UnregisterFont</name>
<prototype>procedure UnregisterFont(const FontName, FontFilename: String);</prototype>
<prototype>procedure UnregisterFont(const FontName, FontFilename: String; const PerUserFont: Boolean);</prototype>
<description><p>Unregisters the font with the specified face and filename.</p></description>
</function>
<function>

View File

@ -2891,21 +2891,21 @@ const
UserConsts: array[0..3] of String = (
'userpf', 'usercf', 'usersavedgames', 'username');
Consts: array[0..42] of String = (
'src', 'srcexe', 'tmp', 'app', 'win', 'sys', 'sd', 'groupname', 'fonts', 'hwnd',
'src', 'srcexe', 'tmp', 'app', 'win', 'sys', 'sd', 'groupname', 'commonfonts', 'hwnd',
'commonpf', 'commonpf32', 'commonpf64', 'commoncf', 'commoncf32', 'commoncf64',
'autopf', 'autopf32', 'autopf64', 'autocf', 'autocf32', 'autocf64',
'computername', 'dao', 'cmd', 'wizardhwnd', 'sysuserinfoname', 'sysuserinfoorg',
'userinfoname', 'userinfoorg', 'userinfoserial', 'uninstallexe',
'language', 'syswow64', 'sysnative', 'log', 'dotnet11', 'dotnet20', 'dotnet2032',
'dotnet2064', 'dotnet40', 'dotnet4032', 'dotnet4064');
UserShellFolderConsts: array[0..8] of String = (
UserShellFolderConsts: array[0..9] of String = (
'userdesktop', 'userstartmenu', 'userprograms', 'userstartup',
'userappdata', 'userdocs', 'usertemplates', 'userfavorites', 'usersendto');
ShellFolderConsts: array[0..16] of String = (
'userappdata', 'userdocs', 'usertemplates', 'userfavorites', 'usersendto', 'userfonts');
ShellFolderConsts: array[0..17] of String = (
'group', 'commondesktop', 'commonstartmenu', 'commonprograms', 'commonstartup',
'commonappdata', 'commondocs', 'commontemplates', 'localappdata',
'autodesktop', 'autostartmenu', 'autoprograms', 'autostartup',
'autoappdata', 'autodocs', 'autotemplates', 'autofavorites');
'autoappdata', 'autodocs', 'autotemplates', 'autofavorites', 'autofonts');
AllowedConstsNames: array[TAllowedConst] of String = (
'olddata', 'break');
var

View File

@ -2,7 +2,7 @@ unit InstFunc;
{
Inno Setup
Copyright (C) 1997-2019 Jordan Russell
Copyright (C) 1997-2020 Jordan Russell
Portions by Martijn Laan
For conditions of distribution and use, see LICENSE.TXT.
@ -106,7 +106,7 @@ procedure RaiseOleError(const FunctionName: String; const ResultCode: HRESULT);
procedure RefreshEnvironment;
function ReplaceSystemDirWithSysWow64(const Path: String): String;
function ReplaceSystemDirWithSysNative(Path: String; const IsWin64: Boolean): String;
procedure UnregisterFont(const FontName, FontFilename: String);
procedure UnregisterFont(const FontName, FontFilename: String; const PerUserFont: Boolean);
function RestartComputer: Boolean;
procedure RestartReplace(const DisableFsRedir: Boolean; TempFile, DestFile: String);
procedure SplitNewParamStr(const Index: Integer; var AName, AValue: String);
@ -1247,15 +1247,20 @@ begin
DoNonNT;
end;
procedure UnregisterFont(const FontName, FontFilename: String);
procedure UnregisterFont(const FontName, FontFilename: String; const PerUserFont: Boolean);
const
FontsKeys: array[Boolean] of PChar =
(NEWREGSTR_PATH_SETUP + '\Fonts',
'Software\Microsoft\Windows NT\CurrentVersion\Fonts');
var
K: HKEY;
RootKey, K: HKEY;
begin
if RegOpenKeyExView(rvDefault, HKEY_LOCAL_MACHINE, FontsKeys[UsingWinNT],
if PerUserFont then
RootKey := HKEY_CURRENT_USER
else
RootKey := HKEY_LOCAL_MACHINE;
if RegOpenKeyExView(rvDefault, RootKey, FontsKeys[UsingWinNT],
0, KEY_SET_VALUE, K) = ERROR_SUCCESS then begin
RegDeleteValue(K, PChar(FontName));
RegCloseKey(K);

View File

@ -903,35 +903,48 @@ var
procedure ProcessFileEntry(const CurFile: PSetupFileEntry;
const DisableFsRedir: Boolean; ASourceFile, ADestName: String;
const FileLocationFilenames: TStringList; const AExternalSize: Integer64;
var ConfirmOverwriteOverwriteAll, PromptIfOlderOverwriteAll: TOverwriteAll);
var ConfirmOverwriteOverwriteAll, PromptIfOlderOverwriteAll: TOverwriteAll;
var WarnedPerUserFonts: Boolean);
procedure InstallFont(const Filename, FontName: String;
const AddToFontTableNow: Boolean);
const PerUserFont, AddToFontTableNow: Boolean; var WarnedPerUserFonts: Boolean);
const
FontsKeys: array[Boolean] of PChar =
(NEWREGSTR_PATH_SETUP + '\Fonts',
'Software\Microsoft\Windows NT\CurrentVersion\Fonts');
var
K: HKEY;
RootKey, K: HKEY;
begin
{ 64-bit Windows note: The Fonts key is evidently exempt from registry
redirection. When a 32-bit app writes to the Fonts key, it's the main
64-bit key that is modified. (There is actually a Fonts key under
Wow6432Node but it appears it's never used or updated.)
Also: We don't bother with any FS redirection stuff here. I'm not sure
it's safe to disable FS redirection when calling AddFontResource, or
if it would even work. Users should be installing their fonts to the
Fonts directory instead of the System directory anyway. }
if RegOpenKeyExView(rvDefault, HKEY_LOCAL_MACHINE, FontsKeys[IsNT], 0,
KEY_SET_VALUE, K) = ERROR_SUCCESS then begin
if RegSetValueEx(K, PChar(FontName), 0, REG_SZ, PChar(Filename),
(Length(Filename)+1)*SizeOf(Filename[1])) <> ERROR_SUCCESS then
Log('Failed to set value in Fonts registry key.');
RegCloseKey(K);
end
else
Log('Failed to open Fonts registry key.');
if PerUserFont and (WindowsVersion < Cardinal($0A0042EE)) then begin
{ Per-user fonts require Windows 10 Version 1803 (10.0.17134) or newer. }
if not WarnedPerUserFonts then begin
Log('Failed to set value in Fonts registry key: per-user fonts are not supported by this version of Windows.');
WarnedPerUserFonts := True;
end;
end else begin
{ 64-bit Windows note: The Fonts key is evidently exempt from registry
redirection. When a 32-bit app writes to the Fonts key, it's the main
64-bit key that is modified. (There is actually a Fonts key under
Wow6432Node but it appears it's never used or updated.)
Also: We don't bother with any FS redirection stuff here. I'm not sure
it's safe to disable FS redirection when calling AddFontResource, or
if it would even work. Users should be installing their fonts to the
Fonts directory instead of the System directory anyway. }
if PerUserFont then
RootKey := HKEY_CURRENT_USER
else
RootKey := HKEY_LOCAL_MACHINE;
if RegOpenKeyExView(rvDefault, RootKey, FontsKeys[IsNT], 0,
KEY_SET_VALUE, K) = ERROR_SUCCESS then begin
if RegSetValueEx(K, PChar(FontName), 0, REG_SZ, PChar(Filename),
(Length(Filename)+1)*SizeOf(Filename[1])) <> ERROR_SUCCESS then
Log('Failed to set value in Fonts registry key.');
RegCloseKey(K);
end
else
Log('Failed to open Fonts registry key.');
end;
if AddToFontTableNow then begin
repeat
{ Note: AddFontResource doesn't set the thread's last error code }
@ -1083,7 +1096,7 @@ var
LastError: DWORD;
DestF, SourceF: TFile;
Flags: TMakeDirFlags;
Overwrite: Boolean;
Overwrite, PerUserFont: Boolean;
label Retry, Skip;
begin
Log('-- File entry --');
@ -1578,8 +1591,11 @@ var
if CurFile^.InstallFontName <> '' then begin
LastOperation := '';
LogFmt('Registering file as a font ("%s")', [CurFile^.InstallFontName]);
InstallFont(FontFilename, CurFile^.InstallFontName, not ReplaceOnRestart);
PerUserFont := not IsAdminInstallMode;
InstallFont(FontFilename, CurFile^.InstallFontName, PerUserFont, not ReplaceOnRestart, WarnedPerUserFonts);
DeleteFlags := DeleteFlags or utDeleteFile_IsFont;
if PerUserFont then
DeleteFlags := DeleteFlags or utDeleteFile_PerUserFont;
end;
{ There were no errors so add the uninstall log entry, unless the file
@ -1735,7 +1751,8 @@ var
function RecurseExternalCopyFiles(const DisableFsRedir: Boolean;
const SearchBaseDir, SearchSubDir, SearchWildcard: String; const SourceIsWildcard: Boolean;
const CurFile: PSetupFileEntry; const FileLocationFilenames: TStringList;
var ExpectedBytesLeft: Integer64; var ConfirmOverwriteOverwriteAll, PromptIfOlderOverwriteAll: TOverwriteAll): Boolean;
var ExpectedBytesLeft: Integer64; var ConfirmOverwriteOverwriteAll, PromptIfOlderOverwriteAll: TOverwriteAll;
var WarnedPerUserFonts: Boolean): Boolean;
var
SearchFullPath, FileName, SourceFile, DestName: String;
H: THandle;
@ -1775,7 +1792,8 @@ var
Size := ExpectedBytesLeft;
end;
ProcessFileEntry(CurFile, DisableFsRedir, SourceFile, DestName,
FileLocationFilenames, Size, ConfirmOverwriteOverwriteAll, PromptIfOlderOverwriteAll);
FileLocationFilenames, Size, ConfirmOverwriteOverwriteAll, PromptIfOlderOverwriteAll,
WarnedPerUserFonts);
Dec6464(ExpectedBytesLeft, Size);
end;
until not FindNextFile(H, FindData);
@ -1793,7 +1811,8 @@ var
Result := RecurseExternalCopyFiles(DisableFsRedir, SearchBaseDir,
SearchSubDir + FindData.cFileName + '\', SearchWildcard,
SourceIsWildcard, CurFile, FileLocationFileNames,
ExpectedBytesLeft, ConfirmOverwriteOverwriteAll, PromptIfOlderOverwriteAll) or Result;
ExpectedBytesLeft, ConfirmOverwriteOverwriteAll, PromptIfOlderOverwriteAll,
WarnedPerUserFonts) or Result;
until not FindNextFile(H, FindData);
finally
Windows.FindClose(H);
@ -1834,9 +1853,11 @@ var
ProgressBefore, ExpectedBytesLeft: Integer64;
DisableFsRedir, FoundFiles: Boolean;
ConfirmOverwriteOverwriteAll, PromptIfOlderOverwriteAll: TOverwriteAll;
WarnedPerUserFonts: Boolean;
begin
ConfirmOverwriteOverwriteAll := oaUnknown;
PromptIfOlderOverwriteAll := oaUnknown;
WarnedPerUserFonts := False;
FileLocationFilenames := TStringList.Create;
try
@ -1862,7 +1883,7 @@ var
ExternalSize.Hi := 0; { not used... }
ExternalSize.Lo := 0;
ProcessFileEntry(CurFile, DisableFsRedir, '', '', FileLocationFilenames, ExternalSize,
ConfirmOverwriteOverwriteAll, PromptIfOlderOverwriteAll);
ConfirmOverwriteOverwriteAll, PromptIfOlderOverwriteAll, WarnedPerUserFonts);
end
else begin
{ File is an 'external' file }
@ -1880,7 +1901,8 @@ var
FoundFiles := RecurseExternalCopyFiles(DisableFsRedir,
PathExtractPath(SourceWildcard), '', PathExtractName(SourceWildcard),
IsWildcard(SourceWildcard), CurFile, FileLocationFileNames,
ExpectedBytesLeft, ConfirmOverwriteOverwriteAll, PromptIfOlderOverwriteAll);
ExpectedBytesLeft, ConfirmOverwriteOverwriteAll, PromptIfOlderOverwriteAll,
WarnedPerUserFonts);
until FoundFiles or
(foSkipIfSourceDoesntExist in CurFile^.Options) or
AbortRetryIgnoreTaskDialogMsgBox(

View File

@ -1021,10 +1021,10 @@ function ExpandIndividualConst(Cnst: String;
const
FolderConsts: array[Boolean, TShellFolderID] of String =
(('userdesktop', 'userstartmenu', 'userprograms', 'userstartup',
'usersendto', 'fonts', 'userappdata', 'userdocs', 'usertemplates',
'usersendto', 'commonfonts', 'userappdata', 'userdocs', 'usertemplates',
'userfavorites', 'localappdata'),
('commondesktop', 'commonstartmenu', 'commonprograms', 'commonstartup',
'usersendto', 'fonts', 'commonappdata', 'commondocs', 'commontemplates',
'usersendto', 'commonfonts', 'commonappdata', 'commondocs', 'commontemplates',
'commonfavorites' { not accepted anymore by the compiler }, 'localappdata'));
NoUninstallConsts: array[0..6] of String =
('src', 'srcexe', 'userinfoname', 'userinfoorg', 'userinfoserial', 'hwnd',
@ -1116,6 +1116,7 @@ begin
InternalError('Cannot expand "' + OriginalCnst + '" constant on this version of Windows');
end
else if Cnst = 'usersavedgames' then Result := SavedGamesUserDir
else if Cnst = 'userfonts' then Result := ExpandConst('{localappdata}\Microsoft\Windows\Fonts') { supported by Windows 10 Version 1803 and newer. doesn't have a KNOWNFOLDERID. }
else if Cnst = 'dao' then Result := ExpandConst('{cf}\Microsoft Shared\DAO')
else if Cnst = 'cmd' then Result := CmdFilename
else if Cnst = 'computername' then Result := GetComputerNameString

View File

@ -163,7 +163,7 @@ const
'function ModifyPifFile(const Filename: String; const CloseOnExit: Boolean): Boolean;',
'procedure RegisterServer(const Is64Bit: Boolean; const Filename: String; const FailCriticalErrors: Boolean);',
'function UnregisterServer(const Is64Bit: Boolean; const Filename: String; const FailCriticalErrors: Boolean): Boolean;',
'procedure UnregisterFont(const FontName, FontFilename: String);',
'procedure UnregisterFont(const FontName, FontFilename: String; const PerUserFont: Boolean);',
//procedure RestartComputer;
'procedure RestartReplace(const TempFile, DestFile: String);',
//procedure Win32ErrorMsg(const FunctionName: String);

View File

@ -907,7 +907,7 @@ begin
Stack.SetBool(PStart, False);
end;
end else if Proc.Name = 'UNREGISTERFONT' then begin
UnregisterFont(Stack.GetString(PStart), Stack.GetString(PStart-1));
UnregisterFont(Stack.GetString(PStart), Stack.GetString(PStart-1), Stack.GetBool(PStart-2));
end else if Proc.Name = 'RESTARTREPLACE' then begin
RestartReplace(ScriptFuncDisableFsRedir, Stack.GetString(PStart), Stack.GetString(PStart-1));
end else if Proc.Name = 'FORCEDIRECTORIES' then begin

View File

@ -274,7 +274,9 @@ procedure HandleRenamedConstants(var Cnst: String; const RenamedConstantCallback
var
CnstRenamed: String;
begin
if Cnst = 'sendto' then
if Cnst = 'fonts' then
CnstRenamed := 'commonfonts'
else if Cnst = 'sendto' then
CnstRenamed := 'usersendto'
else if Cnst = 'pf' then
CnstRenamed := 'commonpf'

View File

@ -83,6 +83,7 @@ const
utDeleteFile_SharedFileIn64BitKey = 1024;
utDeleteFile_DisableFsRedir = 2048; { also determines whether file was registered as 64-bit }
utDeleteFile_GacInstalled = 4096;
utDeleteFile_PerUserFont = 8192;
utDeleteDirOrFiles_Extra = 1;
utDeleteDirOrFiles_IsDir = 2;
utDeleteDirOrFiles_DeleteFiles = 4;
@ -931,7 +932,7 @@ begin
end;
if CurRec^.ExtraData and utDeleteFile_IsFont <> 0 then begin
LogFmt('Unregistering font: %s', [CurRecData[2]]);
UnregisterFont(CurRecData[2], CurRecData[3]);
UnregisterFont(CurRecData[2], CurRecData[3], CurRec^.ExtraData and utDeleteFile_PerUserFont <> 0);
end;
if CurRec^.ExtraData and utDeleteFile_GacInstalled <> 0 then
DoUninstallAssembly(CurRecData[4]);

View File

@ -29,6 +29,17 @@ For conditions of distribution and use, see <a href="https://jrsoftware.org/file
<p><b>Want to be notified by e-mail of updates?</b> Then <a href="https://jrsoftware.org/ismail.php">click here to subscribe</a> to the Inno Setup announcements mailing list.<br /><b>If you subscribed before October 2019, please resubscribe.</b></p>
<p><a name="6.0.6"></a><span class="ver">6.0.6-dev </span><span class="date">(?)</span></p>
<p><span class="head2">Per-user fonts</span></p>
<p>Per-user fonts are now supported if Setup is running on Windows 10 Version 1803 and later:</p>
<ul>
<li>[Files] section parameter <tt>FontInstall</tt> can now be used in <a href="https://jrsoftware.org/ishelp/index.php?topic=admininstallmode">non administrative installs</a>. Requires Windows 10 Version 1803 or later to successfully install a font.</li>
<li>The <tt>{fonts}</tt> constant has been renamed to <tt>{commonfonts}</tt>. The old name is still supported, but it is recommended to update your scripts to the new names and the compiler will issue a warning if you don't.</tt>
<li>Added new <tt>{userfonts}</tt> constant. Only Windows 10 Version 1803 and later supports <tt>{userfonts}</tt>. Same directory as <tt>{localappdata}\Microsoft\Windows\Fonts</tt>.</li>
<li>Added new <tt>{autofonts}</tt> constant which automatically maps to <tt>{commonfonts}</tt> unless the installation is running in non administrative install mode, in which case it maps to <tt>{userfonts}</tt>. It is recommended to update your scripts to use <tt>{autofonts}</tt> as much as possible to avoid mistakes.</li>
<li>Updated all examples to use <tt>{autofonts}</tt> instead of <tt>{fonts}</tt>.</li>
<li>Pascal Scripting change: The <tt>UnregisterFont</tt> support function now has an extra parameter.</li>
</ul>
<p><span class="head2">Other changes</span></p>
<ul>
<li>Added new [Run] and [UninstallRun] sections flag: <tt>dontlogparameters</tt>. If this flag is specified, the command line parameters for the program will not be included in the log file.</li>
<li>Compiler IDE change: <a href="https://i.imgur.com/wHoJ3FG.png">Improved highlighting</a> for the [CustomMessages] and [Messages] sections.</li>