You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何使用AppleScript复制多文件后无法粘贴至第三方应用?如何实现与Finder一致的粘贴效果?

How to Replicate Finder's File Copy-Paste Behavior in AppleScript/Swift for Third-Party Apps

I’ve run into this exact issue before—when you only write NSURL objects to the pasteboard, many third-party apps fail to recognize the content because they rely on the older (but still widely used) file path string format that Finder includes alongside URLs. Let’s fix your AppleScript first, then cover the Swift equivalent.

The Root Cause

Finder doesn’t just put file URLs on the pasteboard when you copy files. It adds multiple data types to support both modern and legacy apps:

  • public.file-url: The array of NSURL objects (what your original code uses)
  • NSFilenamesPboardType: An array of POSIX file paths as strings (many third-party apps depend on this)

Your current code only writes NSURL objects, which is why Finder works (it handles both types) but other apps don’t.

Fixed AppleScript Code

Here’s the updated script that matches Finder’s behavior perfectly:

#!/usr/bin/osascript
use framework "Appkit"
use scripting additions
use Finder : application "Finder"
property this : a reference to current application
property NSFileManager : a reference to NSFileManager of this
property NSMutableArray : a reference to NSMutableArray of this
property NSPasteboard : a reference to NSPasteboard of this
property NSString : a reference to NSString of this
property NSURL : a reference to NSURL of this
property pb : missing value

on run input
	if input's class = script then set input to ¬
		Finder's selection as alias list
	init()
	clearClipboard()
	addToClipboard(input)
end run

to init()
	set pb to NSPasteboard's generalPasteboard()
end init

to clearClipboard()
	if pb = missing value then init()
	pb's clearContents()
end clearClipboard

to addToClipboard(fs)
	local fs
	set fURLs to NSMutableArray's array()
	set fPaths to NSMutableArray's array()
	set FileManager to NSFileManager's defaultManager()
	
	repeat with f in fs
		-- Get standardized POSIX path directly from the alias
		set fPOSIX to POSIX path of f
		set fp to (NSString's stringWithString:fPOSIX)'s stringByStandardizingPath()
		
		if (FileManager's fileExistsAtPath:fp) then
			-- Add URL for modern apps
			(fURLs's addObject:(NSURL's fileURLWithPath:fp))
			-- Add POSIX path string for legacy/third-party apps
			(fPaths's addObject:fp)
		end if
	end repeat
	
	if pb = missing value then init()
	
	-- Explicitly declare supported pasteboard types
	pb's clearContents()
	pb's declareTypes:[current application's NSFilenamesPboardType, current application's NSPasteboardTypeFileURL] owner:(missing value)
	
	-- Write both data types to match Finder's behavior
	pb's setPropertyList:fPaths forType:(current application's NSFilenamesPboardType)
	pb's writeObjects:fURLs
end addToClipboard

Key Changes Explained

  • Added fPaths array: Stores standardized POSIX paths as strings to support the legacy NSFilenamesPboardType
  • Explicit type declaration: Tells the pasteboard exactly what data types we’re providing, which helps apps recognize the content immediately
  • Dual data writing: We first add the string paths (for older apps) then the URL objects (for modern ones)—this mirrors how Finder populates the pasteboard
  • Simplified path handling: Removed the do shell script "realpath" call since POSIX path of alias combined with stringByStandardizingPath() is more reliable in AppleScript

Swift Equivalent

If you prefer a Swift solution, the logic is identical—you just need to populate both data types on NSPasteboard:

import AppKit

func copyFilesToPasteboard(urls: [URL]) {
    let pasteboard = NSPasteboard.general
    pasteboard.clearContents()
    
    // Convert URLs to POSIX path strings for legacy support
    let filePaths = urls.map { $0.path }
    
    // Declare all supported pasteboard types
    let supportedTypes: [NSPasteboard.PasteboardType] = [.fileURL, NSFilenamesPboardType]
    guard pasteboard.declareTypes(supportedTypes, owner: nil) else { return }
    
    // Write both data types to the pasteboard
    pasteboard.setPropertyList(filePaths, forType: NSFilenamesPboardType)
    pasteboard.writeObjects(urls as [NSPasteboardWriting])
}

// Example usage:
// let targetFiles = [URL(fileURLWithPath: "/Users/you/Documents/File1.txt"), URL(fileURLWithPath: "/Users/you/Documents/File2.jpg")]
// copyFilesToPasteboard(urls: targetFiles)

This Swift code will behave exactly like Finder’s copy operation, ensuring third-party apps recognize and accept the pasted files without issues.

内容的提问来源于stack exchange,提问作者Zheng Xiaodong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 00:27:40