打开应用程序作为重复文件
Posted
技术标签:
【中文标题】打开应用程序作为重复文件【英文标题】:Open file with app as duplicate 【发布时间】:2018-06-12 19:54:55 【问题描述】:我的想法是我有一个需要打开的文件模板,但它应该表现得好像只打开了文件的内容而不是文件本身。
用户的不同之处应该是,他需要选择一个位置来保存文件,而不是仅仅覆盖打开的文件。
在预览应用中可以看到类似的行为。复制功能时,预览将在新窗口中打开相同的文件。保存文件后,用户需要指定保存位置。
据我所知NSWorkspace
不支持开箱即用的这种行为。有人知道解决方法吗?我会很感激的!
编辑
在我的情况下,我不知道用户在完成文件后要将文件保存到哪里。目前我只是将文件复制到用户主目录中的隐藏文件夹,然后打开副本,以免覆盖原始文件。
产生的行为是: - 用户看不到文件所在的位置 - 保存并关闭应用程序后,用户将无法再找到该文件。
解决方法:我想现在我会在打开它之前询问用户她想将它保存在哪里,这对我来说似乎有点多余,因为它很可能是她不想要的保存它。希望我能尽快找到更好的解决方案。
【问题讨论】:
您想在自己的应用中打开这样一个新文档吗?还是在其他应用程序中?是否会在您的应用中启动打开操作?或其他?值得一提的是,该操作系统内置了对您所描述的内容的支持。在 Finder 中查看文件的“获取信息”窗口中的“文具垫”复选框。 @KenThomases 我的应用程序正在调用 NSWorkspace.shared.openFile(..) 并带有一个 url 和一个适当的应用程序来打开该 url。所以你的答案正是我需要的。我很困惑,经过十多年的编程和使用 macOS,我从来没有注意到也没有读过这个文具垫功能。 :D 这是经典 Mac OS 时代的一项古老功能。我没有找到任何用于将文件标记为文具本的现代 API。据推测,仍然可以使用文件管理器 API 在文件的 Finder 标志中设置相关位。此外,您知道,当文具便笺簿文件打开时,系统所做的所有事情就是制作一个副本并打开该副本。你也可以这样做。请注意,应用程序不需要用户在保存时指定位置,因为应用程序已经将文档与现有文件(自动副本)相关联。 起初这听起来很有希望,但它确实不像我最初预期的那样工作。我已经在复制文件,所以@KenThomases 是对的,没有太大区别。然而值得注意的是,固定垫标志仅影响用户与文件的直接交互,例如通过 Finder。但是当调用 NSWorkspace 打开文件时,该标志将被忽略。所以这不是我的问题的解决方案,但仍然 - 通过 Apple Script 设置标志在这里描述:apple.stackexchange.com/questions/39490/… 您是否尝试在特定的已知应用程序中打开新文档?也许它可以编写脚本或提供您可以调用的服务。 【参考方案1】:您可以通过向目标应用发送“开放内容”('ocon'
/kAEOpenContents
) Apple 事件来实现此目的。最简单的方法可能是使用Scripting Bridge。
使用 Scripting Bridge 的常规方法要求您提前知道要定位哪个应用程序,并从其脚本接口定义生成一个 Objective-C 标头。但是,您应该能够“原始”地使用它。例如,像这样:
SBApplication *app = [SBApplication applicationWith...:...]; // there are method to take a PID, a bundle ID, or a URL
[app activate];
NSAppleEventDescriptor *desc = [NSAppleEventDescriptor descriptorWithString:@"foobar"];
[app sendEvent:kCoreEventClass id:kAEOpenContents parameters:keyDirectObject, desc, nil];
NSAppleEventDescriptor
对象是内容负载,在本例中为字符串“foobar”。您可以使用其他方法来创建不同类型的有效负载。如果您使用通用的并且需要描述符类型,您可以查看 /System/Library/Frameworks/CoreServices.framework/Frameworks/AE.framework/Headers 中的标题(例如 AEDataModel.h 或 AERegistry.h)。
【讨论】:
在您的帮助下,我能够打开应用程序。对此感激不尽。胸围仍然 - 该示例当然不会导致打开正确的内容。不幸的是,我已经为此工作了几个小时,但我无法弄清楚如何打开文件的内容。据我了解,我需要一个 typeAlias 描述符。但我的尝试都没有奏效。[[NSAppleEventDescriptor descriptorWithFileURL:urls[0]] coerceToDescriptorType:typeAlias];
, [[ScriptingBridgeHelper descriptorWithBookmarkDataForFileURL:urls[0]] coerceToDescriptorType:typeAlias];
如另一个关于堆栈溢出的问题中所述。
文件内容的类型是什么?是图像吗?文本?我认为您想将文件的内容读入数据对象并使用适当类型的+descriptorWithDescriptorType:data:
。例如,对于 PNG 图像数据,这可能需要转换为 TIFF 数据并使用 typeTIFF
。您能否确认,如果您将您希望文件内容具有的数据类型从某个编辑器/查看器应用程序拖到您希望定位的应用程序的图标上,该应用程序会打开一个包含这些内容的新文档?
您也可以使用NSHFSTypeOfFile()
或使用文件属性字典fileHFSTypeCode
获取类型。以上是关于打开应用程序作为重复文件的主要内容,如果未能解决你的问题,请参考以下文章
使用 tkinter 打开其他 Python 3 文件 [重复]