问题
For an app that has been around for many years, and which has stored the classic Alias records in files, I like to recreate Alias files pointing to the same file now, without having to resolve the Alias first (because the destination may be unavailable at that moment).
Supposedly this should accomplish this:
CFDataRef aliasRecord = ... ; // contains the Alias Record data, see below for an example
CFURLRef url = ... ; // initialized with a file URL
CFDataRef bmData = CFURLCreateBookmarkDataFromAliasRecord (NULL, aliasRecord);
CFError error;
bool ok = CFURLWriteBookmarkDataToFile (bmData, url, 0, &error);
However, the write function fails, and the error says "The file couldn’t be saved."
If I instead create bookmark data using CreateBookmarkData
, the write succeeds.
How do I make this work? I'd try writing an old style Alias file with the data in the resource fork if that wasn't so utterly deprecated.
Here's an example alias record I'd have in the aliasRecord object - I can resolve this using the classic Alias Manager FSResolveAlias
function, so I know that it is indeed valid.
00 00 00 00 01 12 00 02 00 01 06 54 54 73 4D 42
50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 CC 31 2F 12 48 2B 00 00 01 A5
F3 9B 03 74 6D 70 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 01 AC 1C 67 D1 FE B7 D0 00 00 00 00 00 00
00 00 FF FF FF FF 00 00 09 20 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 07 70 72 69 76 61 74
65 00 00 10 00 08 00 00 CC 31 12 F2 00 00 00 11
00 08 00 00 D1 FE 9B B0 00 00 00 01 00 04 01 A5
F3 9B 00 02 00 13 54 54 73 4D 42 50 3A 70 72 69
76 61 74 65 3A 00 74 6D 70 00 00 0E 00 08 00 03
00 74 00 6D 00 70 00 0F 00 0E 00 06 00 54 00 54
00 73 00 4D 00 42 00 50 00 12 00 0B 70 72 69 76
61 74 65 2F 74 6D 70 00 00 13 00 01 2F 00 FF FF
00 00
回答1:
CFURLCreateBookmarkDataFromAliasRecord()
doesn't create the bookmark data with the kCFURLBookmarkCreationSuitableForBookmarkFile
option required by CFURLWriteBookmarkDataToFile()
.
CFURLCreateBookmarkDataFromAliasRecord()
was intended as a way to convert alias records stored a program's own data files to bookmarks with no I/O.
Before CFURLWriteBookmarkDataToFile()
, Finder Alias files (bookmark files) were created by the Finder. Those files contained an Alias resource (containing known properties that could be obtained from the Alias resource with FSCopyAliasInfo()
) and icon resources. Apple needed the bookmark data in the files written by CFURLWriteBookmarkDataToFile()
to provide the same properties. The kCFURLBookmarkCreationSuitableForBookmarkFile
option enforces that requirement.
If you have an AliasHandle
and want to create a new-style Alias file with bookmark data, you'll need to:
(1) resolve the AliasHandle
to an FSRef
, create a CFURLRef
from the FSRef
, and then create the bookmark data using the kCFURLBookmarkCreationSuitableForBookmarkFile
option,
or
(2) you'll need to resolve the bookmark data created with CFURLCreateBookmarkDataFromAliasRecord()
, and then create a new bookmark data using the kCFURLBookmarkCreationSuitableForBookmarkFile
option.
However, you've indicated you'd like to handle this without resolving the AliasHandle
, so the only solution is to create an old-style Finder Alias file. Although I know you already know how to accomplish that, it's described at How do I create a Finder alias within an application?.
The first time a user resolves/opens that old-style Alias file with the Finder, the Finder will detect the Alias file needs to be updated (i.e., CFURLCreateByResolvingBookmarkData()
will return with isStale == true
) and the Finder will create a new bookmark to the Alias file's target and re-write the Alias file. CFURLCreateBookmarkDataFromFile()
will continue to support old-style Alias files as long as possible for backwards compatibility.
来源:https://stackoverflow.com/questions/37309635/generate-a-bookmark-file-from-a-classic-mac-alias-record