如何获得Mac当前壁纸完整路径及名称的一个脚本

我写了一个脚本可以获得当前壁纸路径及名称的,但是我晕了,这个脚本是可以获得前一个壁纸和当前壁纸和后一个壁纸的名称的,但是我不想搞了,希望有人可以完善。

此脚本在 macos15.6,macbookair上测试通过。

#!/usr/bin/env swift


import AppKit

import Foundation


// MARK: - 工具函数


func expandTilde(_ path: String) -> String {

if path.hasPrefix("~") { return (path as NSString).expandingTildeInPath }

return path

}


func isDirectory(_ path: String) -> Bool {

var isDir: ObjCBool = false

let exists = FileManager.default.fileExists(atPath: path, isDirectory: &isDir)

return exists && isDir.boolValue

}


func isFile(_ path: String) -> Bool {

var isDir: ObjCBool = false

let exists = FileManager.default.fileExists(atPath: path, isDirectory: &isDir)

return exists && !isDir.boolValue

}


@discardableResult

func runShell(_ command: String) -> (status: Int32, stdout: String, stderr: String) {

let task = Process()

task.executableURL = URL(fileURLWithPath: "/bin/zsh")

task.arguments = ["-lc", command]

let outPipe = Pipe()

let errPipe = Pipe()

task.standardOutput = outPipe

task.standardError = errPipe

do { try task.run() } catch {

return (status: -1, stdout: "", stderr: "执行失败: \(error)")

}

task.waitUntilExit()

let outData = outPipe.fileHandleForReading.readDataToEndOfFile()

let errData = errPipe.fileHandleForReading.readDataToEndOfFile()

let outStr = String(data: outData, encoding: .utf8) ?? ""

let errStr = String(data: errData, encoding: .utf8) ?? ""

return (status: task.terminationStatus, stdout: outStr, stderr: errStr)

}


// 通过 System Events 获取当前桌面图片路径(可能返回目录)

func getSystemEventsDesktopPicture() -> String? {

let source = """

tell application "System Events"

tell current desktop

set wallpaperPath to picture

end tell

end tell

"""

var errorInfo: NSDictionary?

guard let script = NSAppleScript(source: source) else { return nil }

let result = script.executeAndReturnError(&errorInfo)

if errorInfo != nil { return nil }

return result.stringValue

}


// 通过 Finder 获取当前桌面图片的完整信息

func getFinderDesktopPictureInfo() -> (name: String?, path: String?) {

let source = """

tell application "Finder"

try

set theDesktopPic to desktop picture

set theName to displayed name of theDesktopPic

set thePath to POSIX path of theDesktopPic

return {theName, thePath}

on error errMsg

return {"", ""}

end try

end tell

"""

var errorInfo: NSDictionary?

guard let script = NSAppleScript(source: source) else { return (nil, nil) }

let result = script.executeAndReturnError(&errorInfo)

if errorInfo != nil { return (nil, nil) }

let output = result.stringValue ?? ""

let components = output.components(separatedBy: ", ")

let name = components.first?.trimmingCharacters(in: .whitespacesAndNewlines)

let path = components.count > 1 ? components[1].trimmingCharacters(in: .whitespacesAndNewlines) : nil

return (name, path)

}


// 获取目录中最可能是当前壁纸的文件

func getCurrentWallpaperFile(in directory: String) -> String? {

guard let urls = try? FileManager.default.contentsOfDirectory(

at: URL(fileURLWithPath: directory),

includingPropertiesForKeys: [.contentAccessDateKey, .contentModificationDateKey, .creationDateKey, .fileSizeKey],

options: [.skipsHiddenFiles]

) else { return nil }

let imageExts: Set<String> = ["jpg","jpeg","png","heic","tiff","bmp","gif","webp"]

let candidates = urls.filter { !$0.hasDirectoryPath && imageExts.contains($0.pathExtension.lowercased()) }

// 多种策略来找到当前壁纸

var bestCandidate: URL? = nil

var bestScore = -1

for url in candidates {

var score = 0

// 策略1: 最近修改的文件得分更高

if let modDate = try? url.resourceValues(forKeys: [.contentModificationDateKey]).contentModificationDate {

let hoursSinceMod = Date().timeIntervalSince(modDate) / 3600

if hoursSinceMod < 24 { score += 10 } // 24小时内修改

else if hoursSinceMod < 168 { score += 5 } // 一周内修改

}

// 策略2: 文件大小适中的图片(排除过小或过大的文件)

if let fileSize = try? url.resourceValues(forKeys: [.fileSizeKey]).fileSize {

let sizeMB = Double(fileSize) / 1024 / 1024

if sizeMB >= 0.1 && sizeMB <= 10.0 { score += 5 } // 100KB-10MB

else if sizeMB > 10.0 { score += 2 } // 大于10MB

}

// 策略4: 最近创建的文件得分更高

if let createDate = try? url.resourceValues(forKeys: [.creationDateKey]).creationDate {

let hoursSinceCreate = Date().timeIntervalSince(createDate) / 3600

if hoursSinceCreate < 24 { score += 3 }

}

if score > bestScore {

bestScore = score

bestCandidate = url

}

}

return bestCandidate?.path

}


[标题经过版主编辑] 原标题: 如何获得当前壁纸完整路径及名称

MacBook Air, macOS 15.6

发布日期 2025年8月8日 上午3:44

回复
回复量: 2

2025年8月8日 上午3:49 回应 顺滑

字数限制了,接上。

// 简化的 Wallpaper 进程查询(只查询一次)

func findWallpaperViaProcessFiles() -> (current: String?, next: String?) {

print("正在检查Wallpaper进程打开的文件...")

// 只使用一个最有效的查询

let cmd = "lsof | grep Wallpaper | grep -E '\\.(png|heic|jpg|jpeg)' | head -3"

let result = runShell(cmd)

var foundFiles: [String] = []

if !result.stdout.isEmpty {

// 过滤掉空行并打印

let lines = result.stdout.components(separatedBy: "\n").filter { !$0.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty }

for line in lines {

print(line)

}

// 快速解析输出

for line in lines {

// 提取文件路径(通常在行的最后)

let components = line.components(separatedBy: " ")

for component in components {

// 检查是否是图片文件路径

if (component.contains(".png") || component.contains(".heic") || component.contains(".jpg") || component.contains(".jpeg")) {

let path = component.trimmingCharacters(in: .whitespacesAndNewlines)

if FileManager.default.fileExists(atPath: path) {

foundFiles.append(path)

}

}

}

}

}

// 修正逻辑:最后一个文件是当前壁纸,倒数第二个是上一个壁纸

let current = foundFiles.last

let previous = foundFiles.count > 1 ? foundFiles[foundFiles.count - 2] : nil

return (current, previous)

}


// MARK: - 主流程


print("正在获取当前壁纸信息...")


// 1) 尝试通过 Finder 获取完整信息

let finderInfo = getFinderDesktopPictureInfo()

if let finderName = finderInfo.name, let finderPath = finderInfo.path {

print("Finder 返回的壁纸名称: \(finderName)")

print("Finder 返回的路径: \(finderPath)")

let expandedFinderPath = expandTilde(finderPath)

if isFile(expandedFinderPath) {

let filename = URL(fileURLWithPath: expandedFinderPath).lastPathComponent

print("显示器 1 的壁纸: \(filename)")

print("完整路径: \(expandedFinderPath)")

} else if isDirectory(expandedFinderPath) {

// 使用最新访问的图片

if let latestPath = getCurrentWallpaperFile(in: expandedFinderPath) {

let filename = URL(fileURLWithPath: latestPath).lastPathComponent

print("显示器 1 的壁纸: \(filename)")

print("完整路径: \(latestPath)")

if let accessDate = try? URL(fileURLWithPath: latestPath).resourceValues(forKeys: [.contentAccessDateKey]).contentAccessDate {

let formatter = DateFormatter()

formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

print("文件访问时间: \(formatter.string(from: accessDate))")

}

}

}

} else {

print("无法通过 Finder 获取壁纸信息")

// 备用方案:使用 System Events

if let sePath = getSystemEventsDesktopPicture() {

let expandedPath = expandTilde(sePath)

print("System Events 返回的路径: \(expandedPath)")

if isDirectory(expandedPath) {

if let latestPath = getCurrentWallpaperFile(in: expandedPath) {

let filename = URL(fileURLWithPath: latestPath).lastPathComponent

print("显示器 1 的壁纸: \(filename)")

print("完整路径: \(latestPath)")

if let accessDate = try? URL(fileURLWithPath: latestPath).resourceValues(forKeys: [.contentAccessDateKey]).contentAccessDate {

let formatter = DateFormatter()

formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

print("文件访问时间: \(formatter.string(from: accessDate))")

}

} else {

print("显示器 1 的壁纸: 未找到图片文件")

}

} else if isFile(expandedPath) {

let filename = URL(fileURLWithPath: expandedPath).lastPathComponent

print("显示器 1 的壁纸: \(filename)")

print("完整路径: \(expandedPath)")

}

}

}


2025年8月8日 上午3:50 回应 顺滑

字数限制,接上。


// 2) 通过 Wallpaper 进程找到当前壁纸(最有效的方法)

let wallpaperFiles = findWallpaperViaProcessFiles()


if let currentPath = wallpaperFiles.current {

let filename = URL(fileURLWithPath: currentPath).lastPathComponent

print("当前壁纸: \(filename)")

print("完整路径: \(currentPath)")

// 显示文件详细信息

let url = URL(fileURLWithPath: currentPath)

if let accessDate = try? url.resourceValues(forKeys: [.contentAccessDateKey]).contentAccessDate {

let formatter = DateFormatter()

formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

print("访问时间: \(formatter.string(from: accessDate))")

}

if let fileSize = try? url.resourceValues(forKeys: [.fileSizeKey]).fileSize {

let sizeMB = Double(fileSize) / 1024 / 1024

print("文件大小: \(String(format: "%.2f", sizeMB)) MB")

}

// 打开图片

print("正在打开图片...")

let openResult = runShell("open '\(currentPath)'")

if openResult.status == 0 {

print("图片已打开:\(currentPath)")

} else {

print("打开图片失败")

}

// 提供交互选项

print("是否删除这个壁纸文件?(y/n): ", terminator: "")

if let input = readLine()?.lowercased() {

if input == "y" || input == "yes" {

do {

try FileManager.default.removeItem(atPath: currentPath)

print("文件已删除")

} catch {

print("删除文件失败: \(error)")

}

} else {

print("文件保留")

}

}

// 如果有上一个壁纸,也显示

if let previousPath = wallpaperFiles.next {

let previousFilename = URL(fileURLWithPath: previousPath).lastPathComponent

print("上一个壁纸: \(previousFilename)")

print("完整路径: \(previousPath)")

}

}


print("壁纸获取完成。")

这个主题已被系统或社区团队关闭。 你可以为你认为有帮助的任何帖子投票,也可以在社区中搜索其他答案。

如何获得Mac当前壁纸完整路径及名称的一个脚本

欢迎来到 Apple 支持社区
Apple 客户在其产品方面互相帮助的论坛。使用您的 Apple 帐户开始畅游其中吧!!