Skip to content

Add support for more archive types using 7zip #9633

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

Merged
merged 60 commits into from
Aug 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
247bc5a
Add to zip without loading into memory
gave92 Nov 25, 2021
ec319cf
Fix SharpZipLib project
gave92 Nov 25, 2021
2de6443
Removed sharpziplib project
gave92 Nov 28, 2021
c763b3c
Added modified SharpZipLib nuget to project
gave92 Nov 28, 2021
699779a
Fix opening empty archives
gave92 Nov 28, 2021
a9d1e2f
Add 7ZipExtractor
gave92 Nov 28, 2021
0c5b13b
[WIP]
gave92 Nov 29, 2021
fb9fd04
Restored browsing zips
gave92 Nov 29, 2021
a6ff71d
Call uwp LoadPackagedLibrary
gave92 Nov 29, 2021
9976146
Open 7z, zip, rar
gave92 Nov 29, 2021
85f6aaf
Properly dispose streams & detect failed ops
gave92 Nov 29, 2021
15b07ab
Restore extract commands
gave92 Nov 29, 2021
230f3f0
Removed unnecessary enconding detection
gave92 Dec 4, 2021
485c546
[WIP] Add preference to open archives in Files
gave92 Dec 4, 2021
02849e2
Show icons in 7z files
gave92 Dec 4, 2021
5b0a8b7
Load correct size icon and overlay (#7052)
gave92 Dec 4, 2021
6de4468
[TEST] Switch to SevenZipSharp
gave92 Dec 5, 2021
a3b83fb
Avoid crash on password protected archives
gave92 Dec 5, 2021
2ef78e8
Cache file association per extension
gave92 Dec 5, 2021
365c487
[WIP] create file
gave92 Dec 6, 2021
3fa44ad
[WIP] Rename and delete
gave92 Dec 6, 2021
da335d9
[WIP] Add file compression
gave92 Dec 6, 2021
69dca8c
Overwrite file only if compression succeedes
gave92 Dec 7, 2021
2d3283f
Fix InputStreamWithDisposeCallback
gave92 Dec 10, 2021
e099315
Revert changes to language files
gave92 Dec 11, 2021
397acbd
Conditional uwp support
gave92 Dec 11, 2021
9b08324
Updated to new project structure
gave92 Dec 15, 2021
6f170cb
Merge branch 'main' of https://github.com/files-community/Files into …
gave92 Feb 20, 2022
e4f7e5a
Fix build
gave92 Feb 20, 2022
6666353
[TEST] Fix Azure build
gave92 Feb 20, 2022
5385d6d
Update SevenZip.csproj
yaira2 Feb 23, 2022
3ca01c4
Merge branch 'main' into 7zip
yaira2 Feb 23, 2022
218496a
Update Files.sln
yaira2 Feb 23, 2022
552c5be
Revert "Update Files.sln"
yaira2 Feb 23, 2022
276a286
Revert "Merge branch 'main' into 7zip"
yaira2 Feb 23, 2022
4b009cd
Revert "Revert "Merge branch 'main' into 7zip""
yaira2 Feb 23, 2022
46a22f7
Revert
yaira2 Feb 23, 2022
2faa349
Revert "Revert"
yaira2 Feb 23, 2022
ec4224b
Merge branch 'main' of https://github.com/files-community/Files into …
gave92 Apr 3, 2022
2c7e4cf
Fix merge main
gave92 Apr 3, 2022
b5f2ee9
Merge branch 'main' of https://github.com/files-community/Files into …
gave92 Jul 15, 2022
69815e0
Fix merge
gave92 Jul 15, 2022
7cd9afa
Fix merge
gave92 Jul 15, 2022
0afce4e
Revert resw
gave92 Jul 15, 2022
88ad17b
Fix extension check
gave92 Jul 15, 2022
042a5b8
Revert extra changes to SevenZip lib. Remove not working rename/delete
gave92 Jul 16, 2022
2d67d44
Fix folder count
gave92 Jul 16, 2022
84577b6
Switch to nuget package
gave92 Jul 16, 2022
abf02ee
Show folder icons for directory entries
gave92 Jul 16, 2022
46e116c
Revert extra changes
gave92 Jul 16, 2022
62285c5
[WIP]
gave92 Jul 31, 2022
7a70664
[WIP]
gave92 Aug 1, 2022
b426279
Revert extra changes
gave92 Aug 1, 2022
172e6d1
Fix build
gave92 Aug 1, 2022
2b9f39a
Fix library path
gave92 Aug 1, 2022
f04fb64
Fix renaming in archives
gave92 Aug 1, 2022
67f78b1
Enable tar support
gave92 Aug 2, 2022
4d72a1b
Enable appx support
yaira2 Aug 2, 2022
d3fe83d
Add filetype assoc
gave92 Aug 2, 2022
1ee83e2
Added 7zip
yaira2 Aug 4, 2022
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
6 changes: 4 additions & 2 deletions src/Files.FullTrust/MessageHandlers/Win32MessageHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ public async Task ParseArgumentsAsync(PipeStream connection, Dictionary<string,
var fileIconPath = (string)message["filePath"];
var thumbnailSize = (int)(long)message["thumbnailSize"];
var isOverlayOnly = (bool)message["isOverlayOnly"];
var (icon, overlay) = await Win32API.StartSTATask(() => Win32API.GetFileIconAndOverlay(fileIconPath, thumbnailSize, true, isOverlayOnly));
var isFolder = (bool)message["isFolder"];
var (icon, overlay) = await Win32API.StartSTATask(() => Win32API.GetFileIconAndOverlay(fileIconPath, thumbnailSize, isFolder, true, isOverlayOnly));
await Win32API.SendMessageAsync(connection, new ValueSet()
{
{ "Icon", icon },
Expand All @@ -92,7 +93,8 @@ public async Task ParseArgumentsAsync(PipeStream connection, Dictionary<string,
case "GetIconWithoutOverlay":
var fileIconPath2 = (string)message["filePath"];
var thumbnailSize2 = (int)(long)message["thumbnailSize"];
var icon2 = await Win32API.StartSTATask(() => Win32API.GetFileIconAndOverlay(fileIconPath2, thumbnailSize2, false));
var isFolder2 = (bool)message["isFolder"];
var icon2 = await Win32API.StartSTATask(() => Win32API.GetFileIconAndOverlay(fileIconPath2, thumbnailSize2, isFolder2, false));
await Win32API.SendMessageAsync(connection, new ValueSet()
{
{ "Icon", icon2.icon },
Expand Down
12 changes: 9 additions & 3 deletions src/Files.FullTrust/Win32API.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public static string[] CommandLineToArgs(string commandLine)

private static readonly object lockObject = new object();

public static (string icon, string overlay) GetFileIconAndOverlay(string path, int thumbnailSize, bool getOverlay = true, bool onlyGetOverlay = false)
public static (string icon, string overlay) GetFileIconAndOverlay(string path, int thumbnailSize, bool isFolder, bool getOverlay = true, bool onlyGetOverlay = false)
{
string iconStr = null, overlayStr = null;

Expand Down Expand Up @@ -195,8 +195,7 @@ public static (string icon, string overlay) GetFileIconAndOverlay(string path, i
var useFileAttibutes = !onlyGetOverlay && iconStr == null; // Cannot access file, use file attributes
var ret = ShellFolderExtensions.GetStringAsPidl(path, out var pidl) ?
Shell32.SHGetFileInfo(pidl, 0, ref shfi, Shell32.SHFILEINFO.Size, Shell32.SHGFI.SHGFI_PIDL | flags) :
// TODO: pass FileAttributes.Directory for folders (add "isFolder" parameter)
Shell32.SHGetFileInfo(path, 0, ref shfi, Shell32.SHFILEINFO.Size, flags | (useFileAttibutes ? Shell32.SHGFI.SHGFI_USEFILEATTRIBUTES : 0));
Shell32.SHGetFileInfo(path, isFolder ? FileAttributes.Directory : 0, ref shfi, Shell32.SHFILEINFO.Size, flags | (useFileAttibutes ? Shell32.SHGFI.SHGFI_USEFILEATTRIBUTES : 0));
if (ret == IntPtr.Zero)
{
return (iconStr, null);
Expand Down Expand Up @@ -235,6 +234,13 @@ public static (string icon, string overlay) GetFileIconAndOverlay(string path, i
}
}
}
else if (isFolder)
{
// Could not icon, load generic icon
var icons = ExtractSelectedIconsFromDLL(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "imageres.dll"), new[] { 2 }, thumbnailSize);
var generic = icons.SingleOrDefault(x => x.Index == 2);
iconStr = generic?.IconData;
}
else
{
// Could not icon, load generic icon
Expand Down
Binary file added src/Files.Package/7z.dll
Binary file not shown.
Binary file added src/Files.Package/7z64.dll
Binary file not shown.
8 changes: 7 additions & 1 deletion src/Files.Package/Files.Package.wapproj
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@
<ProjectReference Include="..\Files.FullTrust\Files.FullTrust.csproj" />
</ItemGroup>
<ItemGroup>
<Content Include="7z.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="7z64.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Assets\AppTilesDev\BadgeLogo.scale-100.png" />
<Content Include="Assets\AppTilesDev\BadgeLogo.scale-125.png" />
<Content Include="Assets\AppTilesDev\BadgeLogo.scale-150.png" />
Expand Down Expand Up @@ -482,11 +488,11 @@
<Content Include="Assets\AppTilesDev\Wide310x150Logo.scale-150.png" />
<Content Include="Assets\AppTilesDev\Wide310x150Logo.scale-200.png" />
<Content Include="Assets\AppTilesDev\Wide310x150Logo.scale-400.png" />
<None Include="nupkgs\SevenZipSharp.1.0.0.nupkg" />
<Content Include="Package.appinstaller" />
</ItemGroup>
<ItemGroup>
<None Include="nupkgs\microsoft.management.infrastructure.runtime.win.2.0.1.nupkg" />
<None Include="nupkgs\SharpZipLib.1.3.4.nupkg" />
</ItemGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
</Project>
5 changes: 4 additions & 1 deletion src/Files.Package/Package.appxmanifest
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,12 @@
</uap5:Extension>
<Extension Category="windows.updateTask" EntryPoint="BackgroundTasks.UpdateTask" />
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="zip">
<uap:FileTypeAssociation Name="archives">
<uap:SupportedFileTypes>
<uap:FileType>.zip</uap:FileType>
<uap:FileType>.7z</uap:FileType>
<uap:FileType>.rar</uap:FileType>
<uap:FileType>.tar</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
Expand Down
Binary file not shown.
Binary file removed src/Files.Package/nupkgs/SharpZipLib.1.3.4.nupkg
Binary file not shown.
18 changes: 18 additions & 0 deletions src/Files.Shared/Extensions/LinqExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,24 @@ public static class LinqExtensions
return defaultValue;
}

public static async Task<TValue?> GetAsync<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, Func<Task<TValue?>> defaultValueFunc)
{
if (dictionary is null || key is null)
{
return await defaultValueFunc();
}
if (!dictionary.ContainsKey(key))
{
var defaultValue = await defaultValueFunc();
if (defaultValue is TValue value)
{
dictionary.Add(key, value);
}
return defaultValue;
}
return dictionary[key];
}

public static async Task<IEnumerable<T>> WhereAsync<T>(this IEnumerable<T> source, Func<T, Task<bool>> predicate)
{
var results = await Task.WhenAll(source.Select(async x => (x, await predicate(x))));
Expand Down
8 changes: 2 additions & 6 deletions src/Files.Uwp/Files.Uwp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -1594,15 +1594,12 @@
<PackageReference Include="Newtonsoft.Json">
<Version>13.0.1</Version>
</PackageReference>
<PackageReference Include="SharpZipLib">
<Version>1.3.4</Version>
<PackageReference Include="SevenZipSharp">
<Version>1.0.0</Version>
</PackageReference>
<PackageReference Include="SQLitePCLRaw.bundle_green">
<Version>2.1.0</Version>
</PackageReference>
<PackageReference Include="Ude.NetStandard">
<Version>1.2.0</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<AppxManifest Include="..\Files.Package\Package.appxmanifest">
Expand All @@ -1628,7 +1625,6 @@
<Name>Windows Desktop Extensions for the UWP</Name>
</SDKReference>
</ItemGroup>
<ItemGroup />
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '17.0' ">
<VisualStudioVersion>17.0</VisualStudioVersion>
</PropertyGroup>
Expand Down
4 changes: 2 additions & 2 deletions src/Files.Uwp/Filesystem/BaseStorage/BaseStorageFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public static IAsyncOperation<BaseStorageFile> GetFileFromPathAsync(string path)

public async Task<string> ReadTextAsync(int maxLength = -1)
{
using var inputStream = await OpenSequentialReadAsync();
using var inputStream = await OpenReadAsync();
using var dataReader = new DataReader(inputStream);
StringBuilder builder = new();
uint bytesRead, bytesToRead;
Expand All @@ -104,7 +104,7 @@ public async Task<string> ReadTextAsync(int maxLength = -1)
bytesToRead = maxLength < 0 ? 4096 : (uint)Math.Min(maxLength, 4096);
bytesRead = await dataReader.LoadAsync(bytesToRead);
builder.Append(dataReader.ReadString(bytesRead));
} while (bytesRead > 0);
} while (bytesRead > 0 && inputStream.Position < inputStream.Size);
return builder.ToString();
}

Expand Down
8 changes: 8 additions & 0 deletions src/Files.Uwp/Filesystem/BaseStorage/IBaseStorageFolder.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.IO;
using Windows.Foundation;
using Windows.Storage;
using Windows.Storage.FileProperties;
Expand Down Expand Up @@ -38,4 +39,11 @@ public interface IBaseStorageFolder : IStorageItem2, IStorageFolder, IStorageFol
new BaseStorageFileQueryResult CreateFileQueryWithOptions(QueryOptions queryOptions);
new BaseStorageFolderQueryResult CreateFolderQueryWithOptions(QueryOptions queryOptions);
}

public interface ICreateFileWithStream
{
IAsyncOperation<BaseStorageFile> CreateFileAsync(Stream contents, string desiredName);

IAsyncOperation<BaseStorageFile> CreateFileAsync(Stream contents, string desiredName, CreationCollisionOption options);
}
}
7 changes: 4 additions & 3 deletions src/Files.Uwp/Filesystem/Search/FolderSearch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,8 @@ private ListedItem GetListedItemAsync(string itemPath, WIN32_FIND_DATA findData)
{
ListedItem listedItem = null;
var isHidden = ((FileAttributes)findData.dwFileAttributes & FileAttributes.Hidden) == FileAttributes.Hidden;
if (((FileAttributes)findData.dwFileAttributes & FileAttributes.Directory) != FileAttributes.Directory)
var isFolder = ((FileAttributes)findData.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory;
if (!isFolder)
{
string itemFileExtension = null;
string itemType = null;
Expand All @@ -371,7 +372,7 @@ private ListedItem GetListedItemAsync(string itemPath, WIN32_FIND_DATA findData)
Opacity = isHidden ? Constants.UI.DimItemOpacity : 1
};
}
else if (((FileAttributes)findData.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory)
else
{
if (findData.cFileName != "." && findData.cFileName != "..")
{
Expand All @@ -388,7 +389,7 @@ private ListedItem GetListedItemAsync(string itemPath, WIN32_FIND_DATA findData)
}
if (listedItem != null && MaxItemCount > 0) // Only load icon for searchbox suggestions
{
_ = FileThumbnailHelper.LoadIconFromPathAsync(listedItem.ItemPath, ThumbnailSize, ThumbnailMode.ListView)
_ = FileThumbnailHelper.LoadIconFromPathAsync(listedItem.ItemPath, ThumbnailSize, ThumbnailMode.ListView, isFolder)
.ContinueWith((t) =>
{
if (t.IsCompletedSuccessfully && t.Result != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ CancellationToken cancellationToken
}
else
{
if (".zip".Equals(itemFileExtension, StringComparison.OrdinalIgnoreCase) && await ZipStorageFolder.CheckDefaultZipApp(itemPath))
if (ZipStorageFolder.IsZipPath(itemPath) && await ZipStorageFolder.CheckDefaultZipApp(itemPath))
{
return new ZipItem(null)
{
Expand Down
14 changes: 11 additions & 3 deletions src/Files.Uwp/Filesystem/StorageItems/FtpStorageFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,18 @@ public override IAsyncOperation<BaseStorageFile> CopyAsync(IStorageFolder destin
}

BaseStorageFolder destFolder = destinationFolder.AsBaseStorageFolder();
BaseStorageFile file = await destFolder.CreateFileAsync(desiredNewName, option.Convert());

var stream = await file.OpenStreamForWriteAsync();
return await ftpClient.DownloadAsync(stream, FtpPath, token: cancellationToken) ? file : null;
if (destFolder is ICreateFileWithStream cwsf)
{
using var inStream = await ftpClient.OpenReadAsync(FtpPath, cancellationToken);
return await cwsf.CreateFileAsync(inStream, desiredNewName, option.Convert());
}
else
{
BaseStorageFile file = await destFolder.CreateFileAsync(desiredNewName, option.Convert());
using var stream = await file.OpenStreamForWriteAsync();
return await ftpClient.DownloadAsync(stream, FtpPath, token: cancellationToken) ? file : null;
}
});
}

Expand Down
20 changes: 14 additions & 6 deletions src/Files.Uwp/Filesystem/StorageItems/SystemStorageFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,22 @@ public override IAsyncOperation<BaseStorageFile> CopyAsync(IStorageFolder destin
// File created by CreateFileAsync will get immediately deleted on MTP?! (#7206)
return await File.CopyAsync(sysFolder.Folder, desiredNewName, option);
}
var destFile = await destFolder.CreateFileAsync(desiredNewName, option.Convert());
using (var inStream = await this.OpenStreamForReadAsync())
using (var outStream = await destFile.OpenStreamForWriteAsync())
else if (destFolder is ICreateFileWithStream cwsf)
{
await inStream.CopyToAsync(outStream);
await outStream.FlushAsync();
using var inStream = await this.OpenStreamForReadAsync();
return await cwsf.CreateFileAsync(inStream, desiredNewName, option.Convert());
}
else
{
var destFile = await destFolder.CreateFileAsync(desiredNewName, option.Convert());
using (var inStream = await this.OpenStreamForReadAsync())
using (var outStream = await destFile.OpenStreamForWriteAsync())
{
await inStream.CopyToAsync(outStream);
await outStream.FlushAsync();
}
return destFile;
}
return destFile;
}
catch (UnauthorizedAccessException ex) // shortcuts & .url
{
Expand Down
Loading