Skip to content

Fix: Fixed issue where archives didn't open in existing tab #17394

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 23 additions & 18 deletions src/Files.App/Helpers/Win32/Win32Helper.Storage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,19 @@ public static partial class Win32Helper
{
public static async Task<string?> GetFileAssociationAsync(string filename, bool checkDesktopFirst = false)
{
// Find UWP apps
async Task<string?> GetUwpAssoc()
{
var uwpApps = await Launcher.FindFileHandlersAsync(Path.GetExtension(filename));
return uwpApps.Any() ? uwpApps[0].PackageFamilyName : null;
}

// Find desktop apps
string? GetDesktopAssoc()
{
var lpResult = new StringBuilder(2048);
var hResult = Shell32.FindExecutable(filename, null, lpResult);

return hResult.ToInt64() > 32 ? lpResult.ToString() : null;
}

if (checkDesktopFirst)
return GetDesktopAssoc() ?? await GetUwpAssoc();
return GetDesktopFileAssociation(filename) ?? (await GetUwpFileAssociations(filename)).FirstOrDefault();
Copy link
Preview

Copilot AI Aug 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When checkDesktopFirst is true, the UWP associations are still retrieved even if a desktop association is found. Consider using a conditional check to avoid the async call when not needed: var desktop = GetDesktopFileAssociation(filename); return desktop ?? (await GetUwpFileAssociations(filename)).FirstOrDefault();

Suggested change
return GetDesktopFileAssociation(filename) ?? (await GetUwpFileAssociations(filename)).FirstOrDefault();
{
var desktop = GetDesktopFileAssociation(filename);
if (desktop is not null)
return desktop;
return (await GetUwpFileAssociations(filename)).FirstOrDefault();
}

Copilot uses AI. Check for mistakes.


return await GetUwpAssoc() ?? GetDesktopAssoc();
return (await GetUwpFileAssociations(filename)).FirstOrDefault() ?? GetDesktopFileAssociation(filename);
Copy link
Preview

Copilot AI Aug 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The UWP associations are retrieved even when a desktop association might be sufficient. Consider checking if only one association is needed and short-circuit the evaluation to avoid unnecessary async operations.

Suggested change
return (await GetUwpFileAssociations(filename)).FirstOrDefault() ?? GetDesktopFileAssociation(filename);
var desktopAssociation = GetDesktopFileAssociation(filename);
return desktopAssociation ?? (await GetUwpFileAssociations(filename)).FirstOrDefault();

Copilot uses AI. Check for mistakes.

}

public static async Task<IEnumerable<string>> GetAllFileAssociationsAsync(string filename)
{
var uwpApps = await GetUwpFileAssociations(filename);
var desktopApp = GetDesktopFileAssociation(filename);
return desktopApp is not null
? uwpApps.Append(desktopApp)
: uwpApps;
}

public static string ExtractStringFromDLL(string file, int number)
Expand Down Expand Up @@ -1073,5 +1066,17 @@ public static bool GetWin32FindDataForPath(string targetPath, out Win32PInvoke.W

return false;
}
private static async Task<IEnumerable<string>> GetUwpFileAssociations(string filename)
{
var uwpApps = await Launcher.FindFileHandlersAsync(Path.GetExtension(filename));
return uwpApps.Select(x => x.PackageFamilyName);
}

private static string? GetDesktopFileAssociation(string filename)
{
var lpResult = new StringBuilder(2048);
var hResult = Shell32.FindExecutable(filename, null, lpResult);
return hResult.ToInt64() > 32 ? lpResult.ToString() : null;
}
}
}
13 changes: 5 additions & 8 deletions src/Files.App/Utils/Storage/StorageItems/ZipStorageFolder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,11 @@ public static async Task<bool> CheckDefaultZipApp(string filePath)
{
Func<Task<bool>> queryFileAssoc = async () =>
{
var assoc = await Win32Helper.GetFileAssociationAsync(filePath);
if (assoc is not null)
{
return assoc == Package.Current.Id.FamilyName
|| assoc.EndsWith("Files.App\\Files.exe", StringComparison.OrdinalIgnoreCase)
|| assoc.Equals(IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "explorer.exe"), StringComparison.OrdinalIgnoreCase);
}
return true;
var associations = await Win32Helper.GetAllFileAssociationsAsync(filePath);
return associations.Any(assoc =>
assoc == Package.Current.Id.FamilyName
|| assoc.EndsWith("Files.App\\Files.exe", StringComparison.OrdinalIgnoreCase)
|| assoc.Equals(IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "explorer.exe"), StringComparison.OrdinalIgnoreCase));
};
var ext = IO.Path.GetExtension(filePath)?.ToLowerInvariant();
return await defaultAppDict.GetAsync(ext, queryFileAssoc);
Expand Down
Loading