matthewjberger / scoop-nerd-fonts

A scoop bucket for installing nerd fonts
The Unlicense
353 stars 34 forks source link

Allow font installation for non-admin user #161

Closed jonz94 closed 2 years ago

jonz94 commented 2 years ago

Attempt to resolve #10

PS. I write some scripts to automatically patch all the manifests, so if anything of this PR needs to be changed, it's a piece of cake ✌️

- Usage: - Make sure `busybox` and `node` commands are available: `scoop install busybox-lean nodejs` - execute `0-main.ps1` on the project root: `.\0-main.ps1` `0-main.ps1` ```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 } ``` `1-remove-remaining-close-bracket-of-is-admin-check.mjs` ```javascript 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'); } ``` `2-patch.mjs` ```javascript 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"', "New-Item $fontInstallDir -ItemType Directory -ErrorAction SilentlyContinue | Out-Null", `Get-ChildItem ${getChildItemArguments} | ForEach-Object {`, ' $value = if ($isFontInstallationForAllUsers) { $_.Name } else { "$fontInstallDir\\$($_.Name)" }', ` New-ItemProperty -Path $registryKey -Name $_.Name.Replace($_.Extension, ' (${fontType})') -Value $value -Force | Out-Null`, " Copy-Item $_.FullName -Destination $fontInstallDir", "}", ]; 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"); ``` - The patch scripts can also be found on my local branch [archived/patch-scripts-which-allow-font-installation-for-non-admin-user](https://github.com/jonz94/scoop-nerd-fonts/tree/archived/patch-scripts-which-allow-font-installation-for-non-admin-user)
issaclin32 commented 2 years ago

Thank you so much for providing the improvement. The script works fine for me. Let's wait for @matthewjberger 's opinion and checks.

matthewjberger commented 2 years ago

LGTM, this is amazing!

jonz94 commented 2 years ago

Hi @matthewjberger,

Is everything okay or any suggestions?

Just double-check before merge this PR, because this PR is a huge update XD

matthewjberger commented 2 years ago

@jonz94 It looks great. :) After checking it over I didn't see any noticeable issues with the script's logic, and the logic is reused across manifests so that adds to the PR's size but not its complexity!! No worries of course if something breaks though, because we can always revert if necessary. The scripts work properly for me locally, so I don't anticipate there being any issues. I appreciate you and @issaclin32 very much for helping me maintain and improve this repo!

jonz94 commented 2 years ago

@matthewjberger, I appreciate that you create this project in the first place. Save me so much time to install/upgrade my favorite fonts. Now, I even more appreciate to be able to being a part of it! 😊