NanaZip icon indicating copy to clipboard operation
NanaZip copied to clipboard

Implement fast drag drop support.

Open dinhngtu opened this issue 1 year ago • 11 comments

fixes #13, fixes #353, fixes #371, fixes #475, fixes #575

Provides fast drag-to-extract support for NanaZip FM. If the feature is enabled, dragging from the main window creates a directory with the name {<COPYHOOK_GUID>}.<HWND>. Directories with this name are intercepted by an external copy hook shell extension NanaZip.Extras.ShellExtension, which sends back a WM_COPYDATA message containing the destination drop path. Upon reception of WM_COPYDATA, NanaZip extracts selected files into the destination directory.

Additionally, add NanaZip.LegacyShellExtension with the old IContextMenu extension, but only for drag-drop handling.

Todo list:

  • [x] Decide on a shell extension distribution method for NanaZip.Extras. (via separate MSI)
  • [x] Integrate shell extensions into the project.
  • [x] Convert shell extension registration to SelfReg
  • [ ] Find a fallback extraction method when shell extension is not present.
  • [x] Build script integration?

Feedback is welcome.

dinhngtu avatar Oct 20 '24 15:10 dinhngtu

I'm sorry for replying late because I'm busy on other coding things.

For NanaZip.Modern, it may be simpler for integrating the shell extension than the NanaZip.Classic. But I need to refresh the NanaZip.ShellExtension implementation first before I merge this PR.

I prefer the solution without shell extensions because I don't want to make shell extension for NanaZip.Classic because it's designed for portable app scenarios.

Kenji Mouri

MouriNaruto avatar Nov 02 '24 03:11 MouriNaruto

When trying to integrate copy hook into NanaZip.Modern, I ran into the issue that packaged shell extensions cannot run outside of package due to conditional ACEs (https://github.com/M2Team/NanaZip/issues/353#issuecomment-1868580641). That's why at the moment I've kept the extension external instead of building it into NanaZip.ShellExtension.

dinhngtu avatar Nov 02 '24 23:11 dinhngtu

when?

Eldenroot avatar Dec 03 '24 22:12 Eldenroot

why don't we name the classic portable then

DevX-Cipher avatar Feb 04 '25 07:02 DevX-Cipher

I've resurrected the legacy right click drag-drop shell extension and added my copy hook extension to that project. The two extensions are accompanied by a "NanaZip Legacy Shell Extensions" MSI installer package, which can be installed per-user or per-machine. I'll appreciate your comments in integrating these new projects to the rest of NanaZip.

dinhngtu avatar Feb 16 '25 19:02 dinhngtu

In general, I need to rewrite the current NanaZip Shell Extension implementation before merging your patch because I hope to have a simplified shell extension implementation first.

Also, I'm nervous about making decisions for that.

  • I hope NanaZip can be installed via Microsoft Store without explicit elevation operations. It (having a MSI installer) makes me feel guilty for friends who use NanaZip because NanaZip is a packaged application that helps them to have a cleaner system environment.
  • I really really really don't want to waste your efforts because it also makes me feel guilty. I don't want to make my contributors feel disappointed, especially you have helped me a lot, you are one of friends (I hope we are friends) who encourage me continue to maintain NanaZip.
  • I'm also worried that some people will ask me to make a full-featured legacy installer and/or legacy external plugin support after I accept your idea, which is something I actually don't want to happen because it will break my design goal.

So, I need to have some time to consider.

Kenji Mouri

MouriNaruto avatar Feb 16 '25 22:02 MouriNaruto

Thanks for your comment. I couldn't think of a good way to implement these shell extensions, as Microsoft has so far provided zero support for legacy shell extension points on packaged apps. So MSI was chosen as a way to keep the "badness" optional and outside of the MSIX package.

  • I hope NanaZip can be installed via Microsoft Store without explicit elevation operations. It (having a MSI installer) makes me feel guilty for friends who use NanaZip because NanaZip is a packaged application that helps them to have a cleaner system environment.

The MSI package can be installed per-user (without elevation) or per-machine. It also shouldn't leave any trace on uninstallation. (File Explorer currently doesn't restart properly when uninstalling the package, which is another issue...)

  • I really really really don't want to waste your efforts because it also makes me feel guilty. I don't want to make my contributors feel disappointed, especially you have helped me a lot, you are one of friends (I hope we are friends) who encourage me continue to maintain NanaZip.

There's no need to worry, I wrote this patch firstly for my own needs since it has functionalities I needed, so I don't mind maintaining my patch out of the main branch for the moment.

  • I'm also worried that some people will ask me to make a full-featured legacy installer and/or legacy external plugin support after I accept your idea, which is something I actually don't want to happen because it will break my design goal.

I hope there's no concern with that, as it does not integrate with NanaZip in any way besides calling its executable (and using some NanaZip code). Granted, the integration is far from ideal, as it calls NanaZipG via the somewhat ugly CALL_7Z_GUI_BY_NAME mechanism.

For the fast drag-drop functionality, I didn't look deeply into it but WinSCP has an implementation that's not dependent on copy hook handlers, which is doable on NanaZip.Modern. My guess is it's implemented by monitoring filesystem changes (although this has its own caveats). I'm not going to go after this route but it would be an interesting topic for someone else to look into.

dinhngtu avatar Feb 16 '25 22:02 dinhngtu

Granted, the integration is far from ideal, as it calls NanaZipG via the somewhat ugly CALL_7Z_GUI_BY_NAME mechanism.

In the current stage, the context menu implementation is based in the same way, but with more abstraction. This is why I want to rewrite the context menu implementation first. I hope it will provide you with a better way to implement your idea. (Of course, I do that because I want to simplify the implementation, and try to provide the legacy drag-and-drop context menu for 22000 or later.)

The MSI package can be installed per-user (without elevation) or per-machine. It also shouldn't leave any trace on uninstallation. (File Explorer currently doesn't restart properly when uninstalling the package, which is another issue...)

Actually, I hope to use the command line regsvr32 or reg command or something manual installation document which put in the Document folder of the source code tree instead. (I think I will package your implementation and provide the extra package in the releases page if I have merged your implementation) It will be good for NanaZip Classic's design scenarios. (WinPE, WinRE, Server Core, and Wine, which may not have the ability to use MSI installation) Also, I hope the end user will know this operation may left something after uninstallation explicitly.

So, I decided to merge your PR. But I need to rewrite the context menu implementation first because I hope we can have a simple implementation for that. (But I hope provide the manually registration document instead of MSI installer package.)

Kenji Mouri

MouriNaruto avatar Feb 16 '25 22:02 MouriNaruto

Never mind. I made another test with desktop9:FileExplorerClassicDragDropContextMenuHandler and it worked fine. (Previously it didn't work on my computer and I had no idea why)

This means NanaZip can now include the drag-drop extension directly inside its MSIX (the copy hook extension unfortunately still isn't supported). However, it means that the extensions will need to be split into two: a "legacy" IContextMenu DLL project, and an "extra" ICopyHook DLL + installer package. I'll try to make the split while waiting for your context menu extension rewrite.

dinhngtu avatar Feb 20 '25 09:02 dinhngtu

Rebased on top of latest, integrated into NanaZip.ExtensionPackage.

dinhngtu avatar Apr 13 '25 13:04 dinhngtu

Changes:

  • Ported to NanaZip.ModernExperience
  • Got rid of WIL usage in fastdrag extension entry point
  • Update to InnoSetup 6.4.3

dinhngtu avatar May 11 '25 07:05 dinhngtu

  • Ported to separate NanaZip.Extension project.
  • Reformatted to follow code style guide.

dinhngtu avatar Aug 30 '25 06:08 dinhngtu