Skip to content

Commit d51fecc

Browse files
authored
Fix: Fixed crash that could occur when installing a lot of font files (#14024)
1 parent be7bb07 commit d51fecc

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

src/Files.App/Actions/Content/Install/InstallFontAction.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ public InstallFontAction()
3333

3434
public Task ExecuteAsync()
3535
{
36-
return Task.WhenAll(context.SelectedItems.Select(x => Win32API.InstallFont(x.ItemPath, false)));
36+
var paths = context.SelectedItems.Select(item => item.ItemPath).ToArray();
37+
return Win32API.InstallFontsAsync(paths, false);
3738
}
3839

3940
public void Context_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)

src/Files.App/Utils/Shell/Win32API.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,36 @@ public static Task InstallFont(string fontFilePath, bool forAllUsers)
835835
return RunPowershellCommandAsync($"-command \"Copy-Item '{fontFilePath}' '{fontDirectory}'; New-ItemProperty -Name '{Path.GetFileNameWithoutExtension(fontFilePath)}' -Path '{registryKey}' -PropertyType string -Value '{destinationPath}'\"", forAllUsers);
836836
}
837837

838+
public static async Task InstallFontsAsync(string[] fontFilePaths, bool forAllUsers)
839+
{
840+
string fontDirectory = forAllUsers
841+
? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "Fonts")
842+
: Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Microsoft", "Windows", "Fonts");
843+
844+
string registryKey = forAllUsers
845+
? "HKLM:\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"
846+
: "HKCU:\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
847+
848+
var psCommand = new StringBuilder("-command \"");
849+
850+
foreach (string fontFilePath in fontFilePaths)
851+
{
852+
var destinationPath = Path.Combine(fontDirectory, Path.GetFileName(fontFilePath));
853+
var appendCommand = $"Copy-Item '{fontFilePath}' '{fontDirectory}'; New-ItemProperty -Name '{Path.GetFileNameWithoutExtension(fontFilePath)}' -Path '{registryKey}' -PropertyType string -Value '{destinationPath}';";
854+
855+
if (psCommand.Length + appendCommand.Length > 32766)
856+
{
857+
// The command is too long to run at once, so run the command once up to this point.
858+
await RunPowershellCommandAsync(psCommand.Append("\"").ToString(), forAllUsers);
859+
psCommand.Clear().Append("-command \"");
860+
}
861+
862+
psCommand.Append(appendCommand);
863+
}
864+
865+
await RunPowershellCommandAsync(psCommand.Append("\"").ToString(), forAllUsers);
866+
}
867+
838868
private static Process CreatePowershellProcess(string command, bool runAsAdmin)
839869
{
840870
Process process = new();

0 commit comments

Comments
 (0)