簡體   English   中英

Powershell 安裝字體系列的腳本

[英]Powershell script to install font family

下面是我從 zip 文件安裝 Monserrat fonts 的腳本。 我不知道如何檢查是否已安裝字體。 安裝后,我可以打開文件夾 C:\Windows\Fonts\Montserrat,我會看到所有這些文件夾。 當我第二次運行腳本時,無法識別該文件夾的存在。 我的錯誤在哪里?

$Source = "Montserrat.zip"
$FontsFolder = "FontMontserrat"
Expand-Archive $Source -DestinationPath $FontsFolder
$FONTS = 0x14
$CopyOptions = 4 + 16;
$objShell = New-Object -ComObject Shell.Application
$objFolder = $objShell.Namespace($FONTS)
$allFonts = dir $FontsFolder
foreach($File in $allFonts)
{
    If((Test-Path "C:\Windows\Fonts\Montserrat") -eq $True)
    {
        echo "Font $File already installed"
    }
    Else
    {
        echo "Installing $File"
        $CopyFlag = [String]::Format("{0:x}", $CopyOptions);
        $objFolder.CopyHere($File.fullname,$CopyFlag)
    }
}

最后我的腳本:

$Source = "Montserrat.zip"
$FontsFolder = "FontMontserrat"
Expand-Archive $Source -DestinationPath $FontsFolder -Force
$FONTS = 0x14
$CopyOptions = 4 + 16;
$objShell = New-Object -ComObject Shell.Application
$objFolder = $objShell.Namespace($FONTS)
$allFonts = dir $FontsFolder
foreach($font in Get-ChildItem -Path $fontsFolder -File)
{
    $dest = "C:\Windows\Fonts\$font"
    If(Test-Path -Path $dest)
    {
        echo "Font $font already installed"
    }
    Else
    {
        echo "Installing $font"
        $CopyFlag = [String]::Format("{0:x}", $CopyOptions);
        $objFolder.CopyHere($font.fullname,$CopyFlag)
    }
}

我正在通過以下 cmd 運行此腳本:

set batchPath=%~dp0
powershell.exe -noexit -file "%batchPath%InstMontserrat.ps1"

我不必以管理員身份運行它,但用戶具有管理員權限。

根據我假設 Windows 10 的評論更正您的腳本:

# well-known SID for admin group
if ('S-1-5-32-544' -notin [System.Security.Principal.WindowsIdentity]::GetCurrent().Groups) {
    throw 'Script must run as admin!'
}

$source = 'Montserrat.zip'
$fontsFolder = 'FontMontserrat'

Expand-Archive -Path $source -DestinationPath $fontsFolder

foreach ($font in Get-ChildItem -Path $fontsFolder -File) {
    $dest = "C:\Windows\Fonts\$font"
    if (Test-Path -Path $dest) {
        "Font $font already installed."
    }
    else {
        $font | Copy-Item -Destination $dest
    }
}

如果您不想在操作系統級別安裝字體,而只是讓它可供程序使用直到重新啟動,您可能需要使用以下腳本:

  • 如果無法注冊/取消注冊字體,將失敗/拋出。
  • 廣播 WM_FONTCHANGE 通知所有 windows fonts 已經改變
  • 不需要管理員權限
  • 不在Windows安裝fonts,只讓當前session所有程序可用,直到重啟
  • 具有用於調試的詳細模式
  • 不適用於字體文件夾

用法:

register-fonts.ps1 [-v] [-unregister <PATH>[,<PATH>...]] [-register  <PATH>[,<PATH>...]] # Register and unregister at same time
register-fonts.ps1 [-v] -unregister <PATH>
register-fonts.ps1 [-v] -register <PATH>
register-fonts.ps1 [-v] <PATH> # Will register font path
Param (
  [Parameter(Mandatory=$False)]
  [String[]]$register,

  [Parameter(Mandatory=$False)]
  [String[]]$unregister
)

# Stop script if command fails https://stackoverflow.com/questions/9948517/how-to-stop-a-powershell-script-on-the-first-error
$ErrorActionPreference = "Stop"

add-type -name Session -namespace "" -member @"
[DllImport("gdi32.dll")]
public static extern bool AddFontResource(string filePath);
[DllImport("gdi32.dll")]
public static extern bool RemoveFontResource(string filePath);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool PostMessage(IntPtr hWnd, int Msg, int wParam = 0, int lParam = 0);
"@

$broadcast = $False;
Foreach ($unregisterFontPath in $unregister) {
  Write-Verbose "Unregistering font $unregisterFontPath"
  # https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-removefontresourcea
  $success = [Session]::RemoveFontResource($unregisterFontPath)
  if (!$success) {
    Throw "Cannot unregister font $unregisterFontPath"
  }
  $broadcast = $True
}

Foreach ($registerFontPath in $register) {
  Write-Verbose "Registering font $registerFontPath"
  # https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-addfontresourcea
  $success = [Session]::AddFontResource($registerFontPath)
  if (!$success) {
    Throw "Cannot register font $registerFontPath"
  }
  $broadcast = $True
}

if ($broadcast) {
  # HWND_BROADCAST https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-postmessagea
  $HWND_BROADCAST = New-Object IntPtr 0xffff
  # WM_FONTCHANGE https://learn.microsoft.com/en-us/windows/win32/gdi/wm-fontchange
  $WM_FONTCHANGE  = 0x1D

  Write-Verbose "Broadcasting font change"
  # Broadcast will let other programs know that fonts were changed https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-postmessagea
  $success = [Session]::PostMessage($HWND_BROADCAST, $WM_FONTCHANGE)
  if (!$success) {
    Throw "Cannot broadcase font change"
  }
}

該腳本的靈感來自這個要點https://gist.github.com/Jaykul/d53a16ce5e7d50b13530acb4f98aaabd

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM