AndiTails

Add-Font.ps1 by Microsoft. Adds all fonts in a folder to system.

Aug 19th, 2020 (edited)
4,568
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #******************************************************************************
  2. # File:     Add-Font.ps1
  3. # Date:     08/28/2013
  4. # Version:  1.0.1
  5. #
  6. # Purpose:  PowerShell script to install Windows fonts.
  7. #
  8. # Usage:    Add-Font -help | -path "<Font file or folder path>"
  9. #
  10. # Copyright (C) 2010 Microsoft Corporation
  11. #
  12. #
  13. # Revisions:
  14. # ----------
  15. # 1.0.0   09/22/2010   Created script.
  16. # 1.0.1   08/28/2013   Fixed help text.  Added quotes around paths in messages.
  17. #
  18. #******************************************************************************
  19.  
  20. #requires -Version 2.0
  21.  
  22. #*******************************************************************
  23. # Declare Parameters
  24. #*******************************************************************
  25. param(
  26.     [string] $path = "",
  27.     [switch] $help = $false
  28. )
  29.  
  30.  
  31. #*******************************************************************
  32. # Declare Global Variables and Constants
  33. #*******************************************************************
  34.  
  35. # Define constants
  36. set-variable CSIDL_FONTS 0x14 -option constant
  37.  
  38. # Create hashtable containing valid font file extensions and text to append to Registry entry name.
  39. $hashFontFileTypes = @{}
  40. $hashFontFileTypes.Add(".fon", "")
  41. $hashFontFileTypes.Add(".fnt", "")
  42. $hashFontFileTypes.Add(".ttf", " (TrueType)")
  43. $hashFontFileTypes.Add(".ttc", " (TrueType)")
  44. $hashFontFileTypes.Add(".otf", " (OpenType)")
  45. # Type 1 fonts require handling multiple resource files.
  46. # Not supported in this script
  47. #$hashFontFileTypes.Add(".mmm", "")
  48. #$hashFontFileTypes.Add(".pbf", "")
  49. #$hashFontFileTypes.Add(".pfm", "")
  50.  
  51. # Initialize variables
  52. $invocation = (Get-Variable MyInvocation -Scope 0).Value
  53. $scriptPath = Split-Path $Invocation.MyCommand.Path
  54. $fontRegistryPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts"
  55.  
  56.  
  57. #*******************************************************************
  58. #  Load C# code
  59. #*******************************************************************
  60. $fontCSharpCode = @'
  61. using System;
  62. using System.Collections.Generic;
  63. using System.Text;
  64. using System.IO;
  65. using System.Runtime.InteropServices;
  66.  
  67. namespace FontResource
  68. {
  69.    public class AddRemoveFonts
  70.    {
  71.        private static IntPtr HWND_BROADCAST = new IntPtr(0xffff);
  72.        private static IntPtr HWND_TOP = new IntPtr(0);
  73.        private static IntPtr HWND_BOTTOM = new IntPtr(1);
  74.        private static IntPtr HWND_TOPMOST = new IntPtr(-1);
  75.        private static IntPtr HWND_NOTOPMOST = new IntPtr(-2);
  76.        private static IntPtr HWND_MESSAGE = new IntPtr(-3);
  77.  
  78.        [DllImport("gdi32.dll")]
  79.        static extern int AddFontResource(string lpFilename);
  80.  
  81.        [DllImport("gdi32.dll")]
  82.        static extern int RemoveFontResource(string lpFileName);
  83.  
  84.        [DllImport("user32.dll",CharSet=CharSet.Auto)]
  85.        private static extern int SendMessage(IntPtr hWnd, WM wMsg, IntPtr wParam, IntPtr lParam);
  86.  
  87.        [return: MarshalAs(UnmanagedType.Bool)]
  88.        [DllImport("user32.dll", SetLastError = true)]
  89.        private static extern bool PostMessage(IntPtr hWnd, WM Msg, IntPtr wParam, IntPtr lParam);
  90.  
  91.        public static int AddFont(string fontFilePath) {
  92.            FileInfo fontFile = new FileInfo(fontFilePath);
  93.            if (!fontFile.Exists)
  94.            {
  95.                return 0;
  96.            }
  97.            try
  98.            {
  99.                int retVal = AddFontResource(fontFilePath);
  100.  
  101.                //This version of SendMessage is a blocking call until all windows respond.
  102.                //long result = SendMessage(HWND_BROADCAST, WM.FONTCHANGE, IntPtr.Zero, IntPtr.Zero);
  103.  
  104.                //Alternatively PostMessage instead of SendMessage to prevent application hang
  105.                bool posted = PostMessage(HWND_BROADCAST, WM.FONTCHANGE, IntPtr.Zero, IntPtr.Zero);
  106.  
  107.                return retVal;
  108.            }
  109.            catch
  110.            {
  111.                return 0;
  112.            }
  113.        }
  114.  
  115.        public static int RemoveFont(string fontFileName) {
  116.            //FileInfo fontFile = new FileInfo(fontFileName);
  117.            //if (!fontFile.Exists)
  118.            //{
  119.            //    return false;
  120.            //}
  121.            try
  122.            {
  123.                int retVal = RemoveFontResource(fontFileName);
  124.  
  125.                //This version of SendMessage is a blocking call until all windows respond.
  126.                //long result = SendMessage(HWND_BROADCAST, WM.FONTCHANGE, IntPtr.Zero, IntPtr.Zero);
  127.  
  128.                //Alternatively PostMessage instead of SendMessage to prevent application hang
  129.                bool posted = PostMessage(HWND_BROADCAST, WM.FONTCHANGE, IntPtr.Zero, IntPtr.Zero);
  130.  
  131.                return retVal;
  132.            }
  133.            catch
  134.            {
  135.                return 0;
  136.            }
  137.        }
  138.  
  139.        public enum WM : uint
  140.        {
  141.            NULL = 0x0000,
  142.            CREATE = 0x0001,
  143.            DESTROY = 0x0002,
  144.            MOVE = 0x0003,
  145.            SIZE = 0x0005,
  146.            ACTIVATE = 0x0006,
  147.            SETFOCUS = 0x0007,
  148.            KILLFOCUS = 0x0008,
  149.            ENABLE = 0x000A,
  150.            SETREDRAW = 0x000B,
  151.            SETTEXT = 0x000C,
  152.            GETTEXT = 0x000D,
  153.            GETTEXTLENGTH = 0x000E,
  154.            PAINT = 0x000F,
  155.            CLOSE = 0x0010,
  156.            QUERYENDSESSION = 0x0011,
  157.            QUERYOPEN = 0x0013,
  158.            ENDSESSION = 0x0016,
  159.            QUIT = 0x0012,
  160.            ERASEBKGND = 0x0014,
  161.            SYSCOLORCHANGE = 0x0015,
  162.            SHOWWINDOW = 0x0018,
  163.            WININICHANGE = 0x001A,
  164.            SETTINGCHANGE = WM.WININICHANGE,
  165.            DEVMODECHANGE = 0x001B,
  166.            ACTIVATEAPP = 0x001C,
  167.            FONTCHANGE = 0x001D,
  168.            TIMECHANGE = 0x001E,
  169.            CANCELMODE = 0x001F,
  170.            SETCURSOR = 0x0020,
  171.            MOUSEACTIVATE = 0x0021,
  172.            CHILDACTIVATE = 0x0022,
  173.            QUEUESYNC = 0x0023,
  174.            GETMINMAXINFO = 0x0024,
  175.            PAINTICON = 0x0026,
  176.            ICONERASEBKGND = 0x0027,
  177.            NEXTDLGCTL = 0x0028,
  178.            SPOOLERSTATUS = 0x002A,
  179.            DRAWITEM = 0x002B,
  180.            MEASUREITEM = 0x002C,
  181.            DELETEITEM = 0x002D,
  182.            VKEYTOITEM = 0x002E,
  183.            CHARTOITEM = 0x002F,
  184.            SETFONT = 0x0030,
  185.            GETFONT = 0x0031,
  186.            SETHOTKEY = 0x0032,
  187.            GETHOTKEY = 0x0033,
  188.            QUERYDRAGICON = 0x0037,
  189.            COMPAREITEM = 0x0039,
  190.            GETOBJECT = 0x003D,
  191.            COMPACTING = 0x0041,
  192.            COMMNOTIFY = 0x0044,
  193.            WINDOWPOSCHANGING = 0x0046,
  194.            WINDOWPOSCHANGED = 0x0047,
  195.            POWER = 0x0048,
  196.            COPYDATA = 0x004A,
  197.            CANCELJOURNAL = 0x004B,
  198.            NOTIFY = 0x004E,
  199.            INPUTLANGCHANGEREQUEST = 0x0050,
  200.            INPUTLANGCHANGE = 0x0051,
  201.            TCARD = 0x0052,
  202.            HELP = 0x0053,
  203.            USERCHANGED = 0x0054,
  204.            NOTIFYFORMAT = 0x0055,
  205.            CONTEXTMENU = 0x007B,
  206.            STYLECHANGING = 0x007C,
  207.            STYLECHANGED = 0x007D,
  208.            DISPLAYCHANGE = 0x007E,
  209.            GETICON = 0x007F,
  210.            SETICON = 0x0080,
  211.            NCCREATE = 0x0081,
  212.            NCDESTROY = 0x0082,
  213.            NCCALCSIZE = 0x0083,
  214.            NCHITTEST = 0x0084,
  215.            NCPAINT = 0x0085,
  216.            NCACTIVATE = 0x0086,
  217.            GETDLGCODE = 0x0087,
  218.            SYNCPAINT = 0x0088,
  219.            NCMOUSEMOVE = 0x00A0,
  220.            NCLBUTTONDOWN = 0x00A1,
  221.            NCLBUTTONUP = 0x00A2,
  222.            NCLBUTTONDBLCLK = 0x00A3,
  223.            NCRBUTTONDOWN = 0x00A4,
  224.            NCRBUTTONUP = 0x00A5,
  225.            NCRBUTTONDBLCLK = 0x00A6,
  226.            NCMBUTTONDOWN = 0x00A7,
  227.            NCMBUTTONUP = 0x00A8,
  228.            NCMBUTTONDBLCLK = 0x00A9,
  229.            NCXBUTTONDOWN = 0x00AB,
  230.            NCXBUTTONUP = 0x00AC,
  231.            NCXBUTTONDBLCLK = 0x00AD,
  232.            INPUT_DEVICE_CHANGE = 0x00FE,
  233.            INPUT = 0x00FF,
  234.            KEYFIRST = 0x0100,
  235.            KEYDOWN = 0x0100,
  236.            KEYUP = 0x0101,
  237.            CHAR = 0x0102,
  238.            DEADCHAR = 0x0103,
  239.            SYSKEYDOWN = 0x0104,
  240.            SYSKEYUP = 0x0105,
  241.            SYSCHAR = 0x0106,
  242.            SYSDEADCHAR = 0x0107,
  243.            UNICHAR = 0x0109,
  244.            KEYLAST = 0x0109,
  245.            IME_STARTCOMPOSITION = 0x010D,
  246.            IME_ENDCOMPOSITION = 0x010E,
  247.            IME_COMPOSITION = 0x010F,
  248.            IME_KEYLAST = 0x010F,
  249.            INITDIALOG = 0x0110,
  250.            COMMAND = 0x0111,
  251.            SYSCOMMAND = 0x0112,
  252.            TIMER = 0x0113,
  253.            HSCROLL = 0x0114,
  254.            VSCROLL = 0x0115,
  255.            INITMENU = 0x0116,
  256.            INITMENUPOPUP = 0x0117,
  257.            MENUSELECT = 0x011F,
  258.            MENUCHAR = 0x0120,
  259.            ENTERIDLE = 0x0121,
  260.            MENURBUTTONUP = 0x0122,
  261.            MENUDRAG = 0x0123,
  262.            MENUGETOBJECT = 0x0124,
  263.            UNINITMENUPOPUP = 0x0125,
  264.            MENUCOMMAND = 0x0126,
  265.            CHANGEUISTATE = 0x0127,
  266.            UPDATEUISTATE = 0x0128,
  267.            QUERYUISTATE = 0x0129,
  268.            CTLCOLORMSGBOX = 0x0132,
  269.            CTLCOLOREDIT = 0x0133,
  270.            CTLCOLORLISTBOX = 0x0134,
  271.            CTLCOLORBTN = 0x0135,
  272.            CTLCOLORDLG = 0x0136,
  273.            CTLCOLORSCROLLBAR = 0x0137,
  274.            CTLCOLORSTATIC = 0x0138,
  275.            MOUSEFIRST = 0x0200,
  276.            MOUSEMOVE = 0x0200,
  277.            LBUTTONDOWN = 0x0201,
  278.            LBUTTONUP = 0x0202,
  279.            LBUTTONDBLCLK = 0x0203,
  280.            RBUTTONDOWN = 0x0204,
  281.            RBUTTONUP = 0x0205,
  282.            RBUTTONDBLCLK = 0x0206,
  283.            MBUTTONDOWN = 0x0207,
  284.            MBUTTONUP = 0x0208,
  285.            MBUTTONDBLCLK = 0x0209,
  286.            MOUSEWHEEL = 0x020A,
  287.            XBUTTONDOWN = 0x020B,
  288.            XBUTTONUP = 0x020C,
  289.            XBUTTONDBLCLK = 0x020D,
  290.            MOUSEHWHEEL = 0x020E,
  291.            MOUSELAST = 0x020E,
  292.            PARENTNOTIFY = 0x0210,
  293.            ENTERMENULOOP = 0x0211,
  294.            EXITMENULOOP = 0x0212,
  295.            NEXTMENU = 0x0213,
  296.            SIZING = 0x0214,
  297.            CAPTURECHANGED = 0x0215,
  298.            MOVING = 0x0216,
  299.            POWERBROADCAST = 0x0218,
  300.            DEVICECHANGE = 0x0219,
  301.            MDICREATE = 0x0220,
  302.            MDIDESTROY = 0x0221,
  303.            MDIACTIVATE = 0x0222,
  304.            MDIRESTORE = 0x0223,
  305.            MDINEXT = 0x0224,
  306.            MDIMAXIMIZE = 0x0225,
  307.            MDITILE = 0x0226,
  308.            MDICASCADE = 0x0227,
  309.            MDIICONARRANGE = 0x0228,
  310.            MDIGETACTIVE = 0x0229,
  311.            MDISETMENU = 0x0230,
  312.            ENTERSIZEMOVE = 0x0231,
  313.            EXITSIZEMOVE = 0x0232,
  314.            DROPFILES = 0x0233,
  315.            MDIREFRESHMENU = 0x0234,
  316.            IME_SETCONTEXT = 0x0281,
  317.            IME_NOTIFY = 0x0282,
  318.            IME_CONTROL = 0x0283,
  319.            IME_COMPOSITIONFULL = 0x0284,
  320.            IME_SELECT = 0x0285,
  321.            IME_CHAR = 0x0286,
  322.            IME_REQUEST = 0x0288,
  323.            IME_KEYDOWN = 0x0290,
  324.            IME_KEYUP = 0x0291,
  325.            MOUSEHOVER = 0x02A1,
  326.            MOUSELEAVE = 0x02A3,
  327.            NCMOUSEHOVER = 0x02A0,
  328.            NCMOUSELEAVE = 0x02A2,
  329.            WTSSESSION_CHANGE = 0x02B1,
  330.            TABLET_FIRST = 0x02c0,
  331.            TABLET_LAST = 0x02df,
  332.            CUT = 0x0300,
  333.            COPY = 0x0301,
  334.            PASTE = 0x0302,
  335.            CLEAR = 0x0303,
  336.            UNDO = 0x0304,
  337.            RENDERFORMAT = 0x0305,
  338.            RENDERALLFORMATS = 0x0306,
  339.            DESTROYCLIPBOARD = 0x0307,
  340.            DRAWCLIPBOARD = 0x0308,
  341.            PAINTCLIPBOARD = 0x0309,
  342.            VSCROLLCLIPBOARD = 0x030A,
  343.            SIZECLIPBOARD = 0x030B,
  344.            ASKCBFORMATNAME = 0x030C,
  345.            CHANGECBCHAIN = 0x030D,
  346.            HSCROLLCLIPBOARD = 0x030E,
  347.            QUERYNEWPALETTE = 0x030F,
  348.            PALETTEISCHANGING = 0x0310,
  349.            PALETTECHANGED = 0x0311,
  350.            HOTKEY = 0x0312,
  351.            PRINT = 0x0317,
  352.            PRINTCLIENT = 0x0318,
  353.            APPCOMMAND = 0x0319,
  354.            THEMECHANGED = 0x031A,
  355.            CLIPBOARDUPDATE = 0x031D,
  356.            DWMCOMPOSITIONCHANGED = 0x031E,
  357.            DWMNCRENDERINGCHANGED = 0x031F,
  358.            DWMCOLORIZATIONCOLORCHANGED = 0x0320,
  359.            DWMWINDOWMAXIMIZEDCHANGE = 0x0321,
  360.            GETTITLEBARINFOEX = 0x033F,
  361.            HANDHELDFIRST = 0x0358,
  362.            HANDHELDLAST = 0x035F,
  363.            AFXFIRST = 0x0360,
  364.            AFXLAST = 0x037F,
  365.            PENWINFIRST = 0x0380,
  366.            PENWINLAST = 0x038F,
  367.            APP = 0x8000,
  368.            USER = 0x0400,
  369.            CPL_LAUNCH = USER+0x1000,
  370.            CPL_LAUNCHED = USER+0x1001,
  371.            SYSTIMER = 0x118
  372.        }
  373.  
  374.    }
  375. }
  376. '@
  377. Add-Type $fontCSharpCode
  378.  
  379.  
  380. #*******************************************************************
  381. # Declare Functions
  382. #*******************************************************************
  383.  
  384. #*******************************************************************
  385. # Function Get-SpecialFolder()
  386. #
  387. # Purpose:  Convert a CSIDL string to a folder parh string
  388. #
  389. # Input:    $id    CSIDL folder identifier string
  390. #
  391. # Returns:  Folder path
  392. #
  393. #*******************************************************************
  394. function Get-SpecialFolder($id)
  395. {
  396.     $shell = New-Object –COM "Shell.Application"
  397.     $folder = $shell.NameSpace($id)
  398.     $specialFolder = $folder.Self.Path
  399.     $specialFolder
  400. }
  401.  
  402.  
  403. #*******************************************************************
  404. # Function Add-SingleFont()
  405. #
  406. # Purpose:  Install a font file
  407. #
  408. # Input:    $file    Font file path
  409. #
  410. # Returns:  0 - success, 1 - failure
  411. #
  412. #*******************************************************************
  413. function Add-SingleFont($filePath)
  414. {
  415.     try
  416.     {
  417.         [string]$filePath = (resolve-path $filePath).path
  418.         [string]$fileDir  = split-path $filePath
  419.         [string]$fileName = split-path $filePath -leaf
  420.         [string]$fileExt = (Get-Item $filePath).extension
  421.         [string]$fileBaseName = $fileName -replace($fileExt ,"")
  422.  
  423.         $shell = new-object -com shell.application
  424.         $myFolder = $shell.Namespace($fileDir)
  425.         $fileobj = $myFolder.Items().Item($fileName)
  426.         $fontName = $myFolder.GetDetailsOf($fileobj,21)
  427.  
  428.         if ($fontName -eq "") { $fontName = $fileBaseName }
  429.  
  430.         copy-item $filePath -destination $fontsFolderPath
  431.  
  432.         $fontFinalPath = Join-Path $fontsFolderPath $fileName
  433.         $retVal = [FontResource.AddRemoveFonts]::AddFont($fontFinalPath)
  434.  
  435.         if ($retVal -eq 0) {
  436.             Write-Host "Font `'$($filePath)`'`' installation failed"
  437.             Write-Host ""
  438.             1
  439.         }
  440.         else
  441.         {
  442.             Write-Host "Font `'$($filePath)`' installed successfully"
  443.             Write-Host ""
  444.             Set-ItemProperty -path "$($fontRegistryPath)" -name "$($fontName)$($hashFontFileTypes.item($fileExt))" -value "$($fileName)" -type STRING
  445.             0
  446.         }
  447.         ""
  448.     }
  449.     catch
  450.     {
  451.         Write-Host "An error occured installing `'$($filePath)`'"
  452.         Write-Host ""
  453.         Write-Host "$($error[0].ToString())"
  454.         Write-Host ""
  455.         $error.clear()
  456.         1
  457.     }
  458. }
  459.  
  460.  
  461. #*******************************************************************
  462. # Function Show-Usage()
  463. #
  464. # Purpose:   Shows the correct usage to the user.
  465. #
  466. # Input:     None
  467. #
  468. # Output:    Help messages are displayed on screen.
  469. #
  470. #*******************************************************************
  471. function Show-Usage()
  472. {
  473. $usage = @'
  474. Add-Font.ps1
  475. This script is used to install Windows fonts.
  476.  
  477. Usage:
  478. Add-Font.ps1 -help | -path "<Font file or folder path>"
  479.  
  480. Parameters:
  481.  
  482.    -help
  483.     Displays usage information.
  484.  
  485.    -path
  486.     May be either the path to a font file to install or the path to a folder
  487.     containing font files to install.  Valid file types are .fon, .fnt,
  488.     .ttf,.ttc, .otf, .mmm, .pbf, and .pfm
  489.  
  490. Examples:
  491.    Add-Font.ps1
  492.    Add-Font.ps1 -path "C:\Custom Fonts\MyFont.ttf"
  493.    Add-Font.ps1 -path "C:\Custom Fonts"
  494. '@
  495.  
  496. $usage
  497. }
  498.  
  499.  
  500. #*******************************************************************
  501. # Function Process-Arguments()
  502. #
  503. # Purpose: To validate parameters and their values
  504. #
  505. # Input:   All parameters
  506. #
  507. # Output:  Exit script if parameters are invalid
  508. #
  509. #*******************************************************************
  510. function Process-Arguments()
  511. {
  512.     ## Write-host 'Processing Arguments'
  513.  
  514.     if ($unnamedArgs.Length -gt 0)
  515.     {
  516.         write-host "The following arguments are not defined:"
  517.         $unnamedArgs
  518.     }
  519.  
  520.     if ($help -eq $true)
  521.     {
  522.         Show-Usage
  523.         break
  524.     }
  525.  
  526.     if ((Test-Path $path -PathType Leaf) -eq $true)
  527.     {
  528.         If ($hashFontFileTypes.ContainsKey((Get-Item $path).Extension))
  529.         {
  530.             $retVal = Add-SingleFont $path
  531.             if ($retVal -ne 0)
  532.             {
  533.                 exit 1
  534.             }
  535.             else
  536.             {
  537.                 exit 0
  538.             }
  539.         }
  540.         else
  541.         {
  542.             "`'$($path)`' not a valid font file type"
  543.             ""
  544.             exit 1
  545.         }
  546.     }
  547.     elseif ((Test-Path $path -PathType Container) -eq $true)
  548.     {
  549.         $bErrorOccured = $false
  550.         foreach($file in (Get-Childitem $path))
  551.         {
  552.  
  553.             if ($hashFontFileTypes.ContainsKey($file.Extension))
  554.             {
  555.                 $retVal = Add-SingleFont (Join-Path $path $file.Name)
  556.                 if ($retVal -ne 0)
  557.                 {
  558.                     $bErrorOccured = $true
  559.                 }
  560.             }
  561.             else
  562.             {
  563.                 "`'$(Join-Path $path $file.Name)`' not a valid font file type"
  564.                 ""
  565.             }
  566.         }
  567.  
  568.         If ($bErrorOccured -eq $true)
  569.         {
  570.             exit 1
  571.         }
  572.         else
  573.         {
  574.             exit 0
  575.         }
  576.     }
  577.     else
  578.     {
  579.         "`'$($path)`' not found"
  580.         ""
  581.         exit 1
  582.     }
  583. }
  584.  
  585.  
  586. #*******************************************************************
  587. # Main Script
  588. #*******************************************************************
  589.  
  590. $fontsFolderPath = Get-SpecialFolder($CSIDL_FONTS)
  591. Process-Arguments
  592.  
  593.  
Add Comment
Please, Sign In to add comment