Add fonts as a regular user in Windows

Recently one of my teachers asked me to create a program that will let standard users on his computers install fonts for their artistic needs. Sounds simple enough.. right? The OS at hand was Windows 7 Enterprise. I had an idea in mind to edit the registry or add a Windows policy that will let me do such a thing, so I created a batch script. The first thing I needed to do was get admin rights. Hmm….

Admin Access In DOS

Thanks to Eneerge @ https://sites.google.com/site/eneerge/scripts/batchgotadmin, I was able to implement a simple vbs script that will execute my whole batch script as an administrator. It looks something like this..

:RequestAdminElevation FilePath %* || goto:eof
setlocal ENABLEDELAYEDEXPANSION & set "_FilePath=%~1"
if NOT EXIST "!_FilePath!" (echo/Read RequestAdminElevation usage information)
set "_FN=_%~ns1" & echo/%TEMP%| findstr /C:"(" >nul && (echo/ERROR: %%TEMP%% path can not contain parenthesis &pause &endlocal &fc;: 2>nul & goto:eof)
set _FN=%_FN:(=%
set _vbspath="%temp:~%\%_FN:)=%.vbs" & set "_batpath=%temp:~%\%_FN:)=%.bat"
fltmc >nul 2>&1 || goto :_getElevation
(if exist %_vbspath% ( del %_vbspath% )) & (if exist %_batpath% ( del %_batpath% ))
endlocal & CD /D "%~dp1" & ver >nul & goto:eof
:_getElevation
echo/Requesting elevation...
echo/Set UAC = CreateObject^("Shell.Application"^) > %_vbspath% || (echo/&echo/Unable to create %_vbspath% & endlocal &md; 2>nul &goto:eof)
echo/UAC.ShellExecute "%_batpath%", "", "", "runas", 1 >> %_vbspath% & echo/wscript.Quit(1)>> %_vbspath%
echo/@%* > "%_batpath%" || (echo/&echo/Unable to create %_batpath% & endlocal &md; 2>nul &goto:eof)
echo/@if %%errorlevel%%==9009 (echo/^&echo/Admin user could not read the batch file. If running from a mapped drive or UNC path, check if Admin user can read it.)^&echo/^& @if %%errorlevel%% NEQ 0 pause >> "%_batpath%"
%_vbspath% && (echo/&echo/Failed to run VBscript %_vbspath% &endlocal &md; 2>nul & goto:eof)
echo/&echo/Elevation was requested on a new CMD window &endlocal &fc;: 2>nul & goto:eof

This huge script is put at the bottom or invoked using call and then putting call :RequestAdminElevation "%~dpfs0" %* || goto:eof anywhere before your admin-requiring code begins.

Giving Users group full control

To allow regular users (conveniently named Users in Windows) to add fonts, the Users group in Windows just has to own the fonts folder in everyway possible. I accomplished this with a set of commands that require admin:

attrib -r -s C:\Windows\Fonts 
takeown /f C:\Windows\Fonts /r /d n
cacls C:\Windows\Fonts /e /t /g Users:C
cacls C:\Windows\System32\FNTCACHE.DAT /e /t /g Users:C

But this alone was not enough. There was one more step. The registry itself “owns” the Fonts folder in Windows, so you have to give the Users group permissions there too. Batch alone cannot do this.

SetACL.exe

With the help of a tool called SetACL, I was able to add this line SetACL.exe -on "hklm\Software\Microsoft\Windows NT\CurrentVersion\Fonts" -ot reg -actn ace -ace "n:Users;p:full" to give the Users group full permissions over the registry key that handles Fonts. A reboot later.. and anyone could easily add their own awesome fonts!

Download

You can see my full tool here on GitHub: Adminless-Fonts, or download yourself the latest release of it here: Latest Release