How Do I Compress (Zip) Multiple Files AND Retain Resources/Attributes?

Continuing the discussion from How Do I Create Zip File in AppleScript and Retain Finder Tags?:

Thanks to @ShaneStanley, I learned how to compress ONE file, or ONE folder, and retain resources/attributes. However, I also have a need to compress multiple files, not in the same folder.

For example, I do a Finder Spotlight Search across my entire Mac, and I select a few files in different folders. I want to create a zip file of this selection. It is easy enough via AppleScript to get a list of the paths of these files, but how do I compress them into one zip file?

After considerable research, here is what I have found:

  1. ditto wll retain resources, but has no provision for the source to be a list of files.
  2. zip easily handles a list of files, but does not retain resources.

So,
How Do I Compress (Zip) Multiple Files AND Retain Resources/Attributes?

TIA.

I’d imagine you need to create a temporary folder, make hard links to your files in it, compress the folder, then delete it.

Thanks, Shane.
Can a hard link be created using ASObjC, or must I resort to a shell script:

How To Create A Hard Link
You can create a hard link using the following syntax:

ln path/to/file /path/to/hard/link

I checked Everyday AppleScriptObjC, Third Edition, but didn’t find any references.

Sure. You need to make URLs of the source and destination, and then:

	set theFileManager to NSFileManager's |defaultManager|()
	set {theResult, theError} to theFileManager's linkItemAtURL:originalURL toURL:theLinkURL |error|:(specifier)
	if not (theResult as boolean) then error (theError's |localizedDescription|() as text)

If you get my FileManagerLib library from:

https://www.macosxautomation.com/applescript/apps/Script_Libs.html

it’s all wrapped in handler form, with checking that the volume supports hard links.

Thanks, Shane, that works well.

Here’s my complete test script based on your script:

How To Use

  1. Select File or Folder in Finder
  2. Trigger this script
  3. Choose Destination Folder for Hard Link
  4. Hard Link is Created at chosen folder, and revealed in Finder.
(*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
Create Finder Item Hard Link via ASObjC
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DATE:    2018-03-28
AUTHOR: JMichaelTX (heavy lifting by ShaneStanley)
REF:
  • How Do I Compress (Zip) Multiple Files AND Retain Resources/Attributes?
    • Late Night Software Ltd., 
  • http://forum.latenightsw.com/t/how-do-i-compress-zip-multiple-files-and-retain-resources-attributes/1217/4?u=jmichaeltx

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*)
use AppleScript version "2.5" -- El Capitan (10.11) or later
use framework "Foundation"
use framework "AppKit" -- this may not be required
use scripting additions

tell application "Finder"
  set sourceFItem to item 1 of (get selection as alias list)
  set linkFolder to choose folder with prompt "Choose Folder for Hard Link"
  set linkPath to (POSIX path of linkFolder) & (name of sourceFItem)
  set sourcePath to POSIX path of sourceFItem
end tell

set linkFile to (POSIX file linkPath)

set nsSourceURL to current application's class "NSURL"'s fileURLWithPath:sourcePath
set nsLinkURL to current application's class "NSURL"'s fileURLWithPath:linkPath

--- From Shane ---
set theFileManager to current application's NSFileManager's |defaultManager|()
set {theResult, theError} to theFileManager's linkItemAtURL:nsSourceURL toURL:nsLinkURL |error|:(reference)
------------------

--- Mod Shane's Error Return ---

if (theResult as boolean) then
  --- SUCCESS:  Hard Link Was Created ---
  
  set scriptResults to "OK" & linefeed & "Hard Link Created:" & linefeed & linkPath
  tell application "Finder" to reveal linkFile
  set msgStr to scriptResults
  set msgTitleStr to (name of me)
  display notification msgStr with title msgTitleStr sound name "Tink.aiff"
else
  --- ERROR:  Unable to Create Hard Link ---
  
  set scriptResults to "[ERROR]" & linefeed & (theError's |localizedDescription|() as text)
  tell application "Finder"
    display dialog scriptResults with title (name of me) buttons {"Cancel"} default button "Cancel" with icon stop
  end tell
end if


return scriptResults