Skip to content

Commit

Permalink
Browse zip archives & other things (#5885)
Browse files Browse the repository at this point in the history
  • Loading branch information
gave92 authored Aug 22, 2021
1 parent 97d178e commit db2aa56
Show file tree
Hide file tree
Showing 79 changed files with 4,050 additions and 852 deletions.
40 changes: 32 additions & 8 deletions Files.Launcher/MessageHandlers/FileOperationsHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,30 @@ private async Task ParseFileOperationAsync(NamedPipeServerStream connection, Dic
{
switch (message.Get("fileop", ""))
{
case "GetFileHandle":
{
var filePath = (string)message["filepath"];
var readWrite = (bool)message["readwrite"];
using var hFile = Kernel32.CreateFile(filePath, Kernel32.FileAccess.GENERIC_READ | (readWrite ? Kernel32.FileAccess.GENERIC_WRITE : 0), FileShare.ReadWrite, null, FileMode.Open, FileFlagsAndAttributes.FILE_ATTRIBUTE_NORMAL);
if (hFile.IsInvalid)
{
await Win32API.SendMessageAsync(connection, new ValueSet() { { "Success", false } }, message.Get("RequestID", (string)null));
return;
}
var processId = (int)(long)message["processid"];
using var uwpProces = System.Diagnostics.Process.GetProcessById(processId);
if (!Kernel32.DuplicateHandle(Kernel32.GetCurrentProcess(), hFile.DangerousGetHandle(), uwpProces.Handle, out var targetHandle, 0, false, Kernel32.DUPLICATE_HANDLE_OPTIONS.DUPLICATE_SAME_ACCESS))
{
await Win32API.SendMessageAsync(connection, new ValueSet() { { "Success", false } }, message.Get("RequestID", (string)null));
return;
}
await Win32API.SendMessageAsync(connection, new ValueSet() {
{ "Success", true },
{ "Handle", targetHandle.ToInt64() }
}, message.Get("RequestID", (string)null));
}
break;

case "Clipboard":
await Win32API.StartSTATask(() =>
{
Expand Down Expand Up @@ -158,7 +182,7 @@ await Win32API.StartSTATask(() =>
shellOperationResult.Items.Add(new ShellOperationItemResult()
{
Succeeded = e.Result.Succeeded,
Source = e.SourceItem.FileSystemPath,
Source = e.SourceItem.FileSystemPath ?? e.SourceItem.ParsingName,
Destination = e.DestItem?.FileSystemPath,
HRresult = (int)e.Result
});
Expand Down Expand Up @@ -224,7 +248,7 @@ await Win32API.StartSTATask(() =>
shellOperationResult.Items.Add(new ShellOperationItemResult()
{
Succeeded = e.Result.Succeeded,
Source = e.SourceItem.FileSystemPath,
Source = e.SourceItem.FileSystemPath ?? e.SourceItem.ParsingName,
Destination = !string.IsNullOrEmpty(e.Name) ? Path.Combine(Path.GetDirectoryName(e.SourceItem.FileSystemPath), e.Name) : null,
HRresult = (int)e.Result
});
Expand Down Expand Up @@ -288,8 +312,8 @@ await Win32API.StartSTATask(() =>
shellOperationResult.Items.Add(new ShellOperationItemResult()
{
Succeeded = e.Result.Succeeded,
Source = e.SourceItem.FileSystemPath,
Destination = e.DestFolder != null && !string.IsNullOrEmpty(e.Name) ? Path.Combine(e.DestFolder.FileSystemPath, e.Name) : null,
Source = e.SourceItem.FileSystemPath ?? e.SourceItem.ParsingName,
Destination = e.DestFolder?.FileSystemPath != null && !string.IsNullOrEmpty(e.Name) ? Path.Combine(e.DestFolder.FileSystemPath, e.Name) : null,
HRresult = (int)e.Result
});
};
Expand Down Expand Up @@ -363,8 +387,8 @@ await Win32API.StartSTATask(() =>
shellOperationResult.Items.Add(new ShellOperationItemResult()
{
Succeeded = e.Result.Succeeded,
Source = e.SourceItem.FileSystemPath,
Destination = e.DestFolder != null && !string.IsNullOrEmpty(e.Name) ? Path.Combine(e.DestFolder.FileSystemPath, e.Name) : null,
Source = e.SourceItem.FileSystemPath ?? e.SourceItem.ParsingName,
Destination = e.DestFolder?.FileSystemPath != null && !string.IsNullOrEmpty(e.Name) ? Path.Combine(e.DestFolder.FileSystemPath, e.Name) : null,
HRresult = (int)e.Result
});
};
Expand Down Expand Up @@ -566,8 +590,8 @@ private void UpdateFileTageDb(object sender, ShellFileOperations.ShellFileOpEven
{
"delete" => e.DestItem?.FileSystemPath,
"rename" => (!string.IsNullOrEmpty(e.Name) ? Path.Combine(Path.GetDirectoryName(e.SourceItem.FileSystemPath), e.Name) : null),
"copy" => (e.DestFolder != null && !string.IsNullOrEmpty(e.Name) ? Path.Combine(e.DestFolder.FileSystemPath, e.Name) : null),
_ => (e.DestFolder != null && !string.IsNullOrEmpty(e.Name) ? Path.Combine(e.DestFolder.FileSystemPath, e.Name) : null)
"copy" => (e.DestFolder?.FileSystemPath != null && !string.IsNullOrEmpty(e.Name) ? Path.Combine(e.DestFolder.FileSystemPath, e.Name) : null),
_ => (e.DestFolder?.FileSystemPath != null && !string.IsNullOrEmpty(e.Name) ? Path.Combine(e.DestFolder.FileSystemPath, e.Name) : null)
};
if (destination == null)
{
Expand Down
3 changes: 1 addition & 2 deletions Files.Launcher/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Files.Common;
using FilesFullTrust.Helpers;
using FilesFullTrust.MessageHandlers;
using Newtonsoft.Json;
using System;
Expand Down Expand Up @@ -235,7 +234,7 @@ private static async Task ParseArgumentsAsync(Dictionary<string, object> message
{
await Win32API.SendMessageAsync(connection, new ValueSet() { { "Success", -1 } }, message.Get("RequestID", (string)null));
}
break;
break;

default:
foreach (var mh in messageHandlers)
Expand Down
7 changes: 7 additions & 0 deletions Files.Package/Package.appxmanifest
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@
</uap5:AppExecutionAlias>
</uap5:Extension>
<Extension Category="windows.updateTask" EntryPoint="BackgroundTasks.UpdateTask" />
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="zip">
<uap:SupportedFileTypes>
<uap:FileType>.zip</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
</Extensions>
</Application>
</Applications>
Expand Down
88 changes: 59 additions & 29 deletions Files/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,32 +129,16 @@ private void OnLeavingBackground(object sender, LeavingBackgroundEventArgs e)
protected override async void OnLaunched(LaunchActivatedEventArgs e)
{
await logWriter.InitializeAsync("debug.log");
Logger.Info($"App launched. Prelaunch: {e.PrelaunchActivated}");

//start tracking app usage
SystemInformation.Instance.TrackAppUse(e);

Logger.Info("App launched");

bool canEnablePrelaunch = ApiInformation.IsMethodPresent("Windows.ApplicationModel.Core.CoreApplication", "EnablePrelaunch");

await EnsureSettingsAndConfigurationAreBootstrapped();

// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (!(Window.Current.Content is Frame rootFrame))
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
rootFrame.CacheSize = 1;
rootFrame.NavigationFailed += OnNavigationFailed;

if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}

// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
var rootFrame = EnsureWindowIsInitialized();

if (e.PrelaunchActivated == false)
{
Expand Down Expand Up @@ -184,6 +168,60 @@ protected override async void OnLaunched(LaunchActivatedEventArgs e)
}
}

protected override async void OnFileActivated(FileActivatedEventArgs e)
{
await logWriter.InitializeAsync("debug.log");
Logger.Info("App activated by file");

//start tracking app usage
SystemInformation.Instance.TrackAppUse(e);

await EnsureSettingsAndConfigurationAreBootstrapped();

var rootFrame = EnsureWindowIsInitialized();

var index = 0;
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame.Navigate(typeof(MainPage), e.Files.First().Path, new SuppressNavigationTransitionInfo());
index = 1;
}
for (; index < e.Files.Count; index++)
{
await MainPageViewModel.AddNewTabByPathAsync(typeof(PaneHolderPage), e.Files[index].Path);
}

// Ensure the current window is active
Window.Current.Activate();
Window.Current.CoreWindow.Activated += CoreWindow_Activated;
}

private Frame EnsureWindowIsInitialized()
{
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (!(Window.Current.Content is Frame rootFrame))
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
rootFrame.CacheSize = 1;
rootFrame.NavigationFailed += OnNavigationFailed;

//if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
//{
// //TODO: Load state from previously suspended application
//}

// Place the frame in the current Window
Window.Current.Content = rootFrame;
}

return rootFrame;
}

private void CoreWindow_Activated(CoreWindow sender, WindowActivatedEventArgs args)
{
if (args.WindowActivationState == CoreWindowActivationState.CodeActivated ||
Expand All @@ -201,20 +239,12 @@ private void CoreWindow_Activated(CoreWindow sender, WindowActivatedEventArgs ar
protected override async void OnActivated(IActivatedEventArgs args)
{
await logWriter.InitializeAsync("debug.log");

Logger.Info("App activated");
Logger.Info($"App activated by {args.Kind.ToString()}");

await EnsureSettingsAndConfigurationAreBootstrapped();

// Window management
if (!(Window.Current.Content is Frame rootFrame))
{
rootFrame = new Frame();
rootFrame.CacheSize = 1;
Window.Current.Content = rootFrame;
}
var rootFrame = EnsureWindowIsInitialized();

var currentView = SystemNavigationManager.GetForCurrentView();
switch (args.Kind)
{
case ActivationKind.Protocol:
Expand Down
28 changes: 23 additions & 5 deletions Files/BaseLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ protected override async void OnNavigatedTo(NavigationEventArgs eventArgs)
ParentShellPageInstance.InstanceViewModel.IsPageTypeRecycleBin = workingDir.StartsWith(App.AppSettings.RecycleBinPath);
ParentShellPageInstance.InstanceViewModel.IsPageTypeMtpDevice = workingDir.StartsWith("\\\\?\\");
ParentShellPageInstance.InstanceViewModel.IsPageTypeFtp = FtpHelpers.IsFtpPath(workingDir);
ParentShellPageInstance.InstanceViewModel.IsPageTypeZipFolder = ZipStorageFolder.IsZipPath(workingDir);
ParentShellPageInstance.InstanceViewModel.IsPageTypeSearchResults = false;
ParentShellPageInstance.NavToolbarViewModel.PathControlDisplayText = navigationArguments.NavPathParam;
if (!navigationArguments.IsLayoutSwitch)
Expand All @@ -453,6 +454,7 @@ protected override async void OnNavigatedTo(NavigationEventArgs eventArgs)
ParentShellPageInstance.InstanceViewModel.IsPageTypeRecycleBin = false;
ParentShellPageInstance.InstanceViewModel.IsPageTypeFtp = false;
ParentShellPageInstance.InstanceViewModel.IsPageTypeMtpDevice = false;
ParentShellPageInstance.InstanceViewModel.IsPageTypeZipFolder = false;
ParentShellPageInstance.InstanceViewModel.IsPageTypeSearchResults = true;
if (!navigationArguments.IsLayoutSwitch)
{
Expand Down Expand Up @@ -588,7 +590,10 @@ public async void BaseContextFlyout_Opening(object sender, object e)
return;
}

AddShellItemsToMenu(shellMenuItems, BaseContextMenuFlyout, shiftPressed);
if (!InstanceViewModel.IsPageTypeZipFolder)
{
AddShellItemsToMenu(shellMenuItems, BaseContextMenuFlyout, shiftPressed);
}
}
}
catch (Exception error)
Expand Down Expand Up @@ -619,7 +624,7 @@ private async Task LoadMenuItemsAsync()
secondaryElements.OfType<FrameworkElement>().ForEach(i => i.MinWidth = 250); // Set menu min width
secondaryElements.ForEach(i => ItemContextMenuFlyout.SecondaryCommands.Add(i));

if (AppSettings.AreFileTagsEnabled && !InstanceViewModel.IsPageTypeSearchResults && !InstanceViewModel.IsPageTypeRecycleBin && !InstanceViewModel.IsPageTypeFtp)
if (AppSettings.AreFileTagsEnabled && !InstanceViewModel.IsPageTypeSearchResults && !InstanceViewModel.IsPageTypeRecycleBin && !InstanceViewModel.IsPageTypeFtp && !InstanceViewModel.IsPageTypeZipFolder)
{
AddFileTagsItemToMenu(ItemContextMenuFlyout);
}
Expand All @@ -630,7 +635,10 @@ private async Task LoadMenuItemsAsync()
return;
}

AddShellItemsToMenu(shellMenuItems, ItemContextMenuFlyout, shiftPressed);
if (!InstanceViewModel.IsPageTypeZipFolder)
{
AddShellItemsToMenu(shellMenuItems, ItemContextMenuFlyout, shiftPressed);
}
}

private void AddFileTagsItemToMenu(Microsoft.UI.Xaml.Controls.CommandBarFlyout contextMenu)
Expand Down Expand Up @@ -771,10 +779,14 @@ protected async void FileList_DragItemsStarting(object sender, DragItemsStarting
{
if (item.PrimaryItemAttribute == StorageItemTypes.File)
{
selectedStorageItems.Add(await new FtpStorageFile(ParentShellPageInstance.FilesystemViewModel, ftpItem).ToStorageFileAsync());
selectedStorageItems.Add(await new FtpStorageFile(ftpItem).ToStorageFileAsync());
}
else if (item.PrimaryItemAttribute == StorageItemTypes.Folder)
{
selectedStorageItems.Add(new FtpStorageFolder(ftpItem));
}
}
else if (item.PrimaryItemAttribute == StorageItemTypes.File)
else if (item.PrimaryItemAttribute == StorageItemTypes.File || item is ZipItem)
{
result = await ParentShellPageInstance.FilesystemViewModel.GetFileFromPathAsync(item.ItemPath)
.OnSuccess(t => selectedStorageItems.Add(t));
Expand Down Expand Up @@ -907,6 +919,12 @@ protected async void Item_DragOver(object sender, DragEventArgs e)
e.DragUIOverride.Caption = string.Format("MoveToFolderCaptionText".GetLocalized(), item.ItemName);
e.AcceptedOperation = DataPackageOperation.Move;
}
else if (draggedItems.Any(x => x.Item is ZipStorageFile || x.Item is ZipStorageFolder)
|| ZipStorageFolder.IsZipPath(item.ItemPath))
{
e.DragUIOverride.Caption = string.Format("CopyToFolderCaptionText".GetLocalized(), item.ItemName);
e.AcceptedOperation = DataPackageOperation.Copy;
}
else if (draggedItems.AreItemsInSameDrive(item.ItemPath))
{
e.DragUIOverride.Caption = string.Format("MoveToFolderCaptionText".GetLocalized(), item.ItemName);
Expand Down
4 changes: 2 additions & 2 deletions Files/DataModels/FilesystemItemsOperationDataModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public async Task<List<FilesystemOperationItemViewModel>> ToItems(Action updateP
// Add conflicting items first
foreach (var item in ConflictingItems)
{
var iconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(item.SourcePath, 64u);
var iconData = await FileThumbnailHelper.LoadIconFromPathAsync(item.SourcePath, 64u, Windows.Storage.FileProperties.ThumbnailMode.ListView);

items.Add(new FilesystemOperationItemViewModel(updatePrimaryButtonEnabled, optionGenerateNewName, optionReplaceExisting, optionSkip)
{
Expand All @@ -84,7 +84,7 @@ public async Task<List<FilesystemOperationItemViewModel>> ToItems(Action updateP
// Then add non-conflicting items
foreach (var item in nonConflictingItems)
{
var iconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(item.SourcePath, 64u);
var iconData = await FileThumbnailHelper.LoadIconFromPathAsync(item.SourcePath, 64u, Windows.Storage.FileProperties.ThumbnailMode.ListView);

items.Add(new FilesystemOperationItemViewModel(updatePrimaryButtonEnabled, optionGenerateNewName, optionReplaceExisting, optionSkip)
{
Expand Down
Loading

0 comments on commit db2aa56

Please sign in to comment.