Skip to content

Instantly share code, notes, and snippets.

@jonz94
Last active October 24, 2021 00:04
Show Gist options
  • Save jonz94/a8d37c2abdb911c0a30511053ccbc4b3 to your computer and use it in GitHub Desktop.
Save jonz94/a8d37c2abdb911c0a30511053ccbc4b3 to your computer and use it in GitHub Desktop.
Patch https://github.com/matthewjberger/scoop-nerd-fonts manifests to allow font installation for non-admin user

Tools

  • git (scoop install git)
  • busybox for sed command (scoop install busybox)
  • nodejs version 14 (scoop bucket add versions; scoop install nodejs14)

Setup

  • Clone the project via git
git clone https://github.com/matthewjberger/scoop-nerd-fonts
  • cd into the project
cd scoop-nerd-fonts
  • Download 1-remove-remaining-close-bracket-of-is-admin-check.mjs & 2-patch.mjs

Patch Script

  • 0-main.ps1
Get-ChildItem bucket | ForEach-Object {
    # remove all `"depends": "sudo",` part
    busybox sed -i "/depends/ d" $_.FullName

    # remove all `"",` part
    busybox sed -i '/\ \"\",$/ d' $_.FullName

    # replace all `-filter` to `-Filter`
    busybox sed -i "s/-filter/-Filter/g" $_.FullName

    # replace all `-Filter 'sarasa` to `-Filter '`
    busybox sed -i "s/-Filter 'sarasa/-Filter '/g" $_.FullName

    # replace all `\"$dir\"` to `$dir`
    busybox sed -i 's/\\\\\"\$dir\\\\\"/$dir/g' $_.FullName

    # remove all `is_admin check`
    busybox sed -i "/is_admin/ d; /Administrator\ rights\ are\ required\ to\ install/ d; /exit\ 1/ d" $_.FullName
    node "1-remove-remaining-close-bracket-of-is-admin-check.mjs" $_.FullName

    # patch
    node "2-patch.mjs" $_.FullName
}
import { resolve } from 'path';
import { readFile, writeFile } from 'fs/promises';
if (process.argv.length < 3) {
process.exit();
}
const filename = resolve(process.argv[2]);
const content = await readFile(filename, 'utf8');
const jsonObject = JSON.parse(content);
let hasModified = false;
if (jsonObject.installer.script[0] === '}') {
jsonObject.installer.script.shift();
hasModified = true;
}
if (jsonObject.uninstaller.script[0] === '}') {
jsonObject.uninstaller.script.shift();
hasModified = true;
}
if (hasModified) {
await writeFile(filename, JSON.stringify(jsonObject, null, 4) + '\n');
}
if (jsonObject.uninstaller.script[0] === "}") {
jsonObject.uninstaller.script.shift();
hasModified = true;
}
if (hasModified) {
await writeFile(filename, JSON.stringify(jsonObject, null, 4) + "\n");
}
import { resolve } from 'path';
import { readFile, writeFile } from 'fs/promises';
if (process.argv.length < 3) {
process.exit();
}
const filename = resolve(process.argv[2]);
const content = await readFile(filename, 'utf8');
const jsonObject = JSON.parse(content);
const originInstallerScript = jsonObject.installer.script;
let customInstallerSteps = [];
let indexOfMainInstallerFirstStep = 0;
let indexOfEditRegistryStep = 1;
if (originInstallerScript.length !== 4) {
indexOfEditRegistryStep = jsonObject.installer.script.findIndex((element) =>
element.includes('New-ItemProperty')
);
indexOfMainInstallerFirstStep = indexOfEditRegistryStep - 1;
customInstallerSteps = originInstallerScript.slice(
0,
indexOfMainInstallerFirstStep
);
}
const mainInstallerFirstStep =
originInstallerScript[indexOfMainInstallerFirstStep];
const getChildItemArguments = mainInstallerFirstStep
.substring('Get-ChildItem '.length)
.substring(
0,
mainInstallerFirstStep.substring('Get-ChildItem '.length).length -
' | ForEach-Object {'.length
);
const fontType = originInstallerScript[indexOfEditRegistryStep].includes(
'OpenType'
)
? 'OpenType'
: 'TrueType';
const patchedInstallerScript = [
...customInstallerSteps,
'$currentBuildNumber = [int] (Get-ItemProperty "HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion").CurrentBuildNumber',
'$windows1809BuildNumber = 17763',
'$isPerUserFontInstallationSupported = $currentBuildNumber -ge $windows1809BuildNumber',
'$isFontInstallationForAllUsers = $global -or !$isPerUserFontInstallationSupported',
'if ($isFontInstallationForAllUsers -and !(is_admin)) {',
' error "Administrator rights are required to install $app."',
' exit 1',
'}',
'$fontInstallDir = if ($isFontInstallationForAllUsers) { "$env:windir\\Fonts" } else { "$env:LOCALAPPDATA\\Microsoft\\Windows\\Fonts" }',
'$registryRoot = if ($isFontInstallationForAllUsers) { "HKLM" } else { "HKCU" }',
'$registryKey = "${registryRoot}:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"',
'if (!$isFontInstallationForAllUsers) {',
' New-Item $fontInstallDir -ItemType Directory -ErrorAction SilentlyContinue | Out-Null',
'}',
`Get-ChildItem ${getChildItemArguments} | ForEach-Object {`,
' Copy-Item $_.FullName -Destination $fontInstallDir',
' Get-ChildItem $fontInstallDir -Filter $_.Name | ForEach-Object {',
' $value = if ($isFontInstallationForAllUsers) { $_.Name } else { $_.FullName }',
` New-ItemProperty -Path $registryKey -Name $_.Name.Replace($_.Extension, ' (${fontType})') -Value $value -Force | Out-Null`,
' }',
'}',
];
jsonObject.installer.script = patchedInstallerScript;
const originUninstallerScript = jsonObject.uninstaller.script;
const originUninstallMessage = originUninstallerScript[4];
const patchedUninstallerScript = [
'$currentBuildNumber = [int] (Get-ItemProperty "HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion").CurrentBuildNumber',
'$windows1809BuildNumber = 17763',
'$isPerUserFontInstallationSupported = $currentBuildNumber -ge $windows1809BuildNumber',
'$isFontInstallationForAllUsers = $global -or !$isPerUserFontInstallationSupported',
'if ($isFontInstallationForAllUsers -and !(is_admin)) {',
' error "Administrator rights are required to uninstall $app."',
' exit 1',
'}',
'$fontInstallDir = if ($isFontInstallationForAllUsers) { "$env:windir\\Fonts" } else { "$env:LOCALAPPDATA\\Microsoft\\Windows\\Fonts" }',
'$registryRoot = if ($isFontInstallationForAllUsers) { "HKLM" } else { "HKCU" }',
'$registryKey = "${registryRoot}:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"',
`Get-ChildItem ${getChildItemArguments} | ForEach-Object {`,
` Remove-ItemProperty -Path $registryKey -Name $_.Name.Replace($_.Extension, ' (${fontType})') -Force -ErrorAction SilentlyContinue`,
' Remove-Item "$fontInstallDir\\$($_.Name)" -Force -ErrorAction SilentlyContinue',
'}',
originUninstallMessage,
];
jsonObject.uninstaller.script = patchedUninstallerScript;
await writeFile(filename, JSON.stringify(jsonObject, null, 4) + '\n');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment