Создание файла .webloc
Я пишу программу (для Mac OS X, используя Objective-C), и мне нужно создавать программные файлы .webloc программно.
Файл .webloc - это просто файл, созданный после перетаскивания URL-адреса из панели местоположений Safari в папку.
Вообще говоря, мне нужен подход для создания элементов в файловой системе, которые указывают на какое-то место в Интернете. Насколько я понимаю, для Mac OS X следует использовать файлы .webloc.
Итак, возможно ли создать файл .webloc с допустимым URL-адресом и некоторым заголовком для него?
Ответы
Ответ 1
Он малоизвестен, но существует также простой формат файла, основанный на списках для веб-блоков.
При создании файлов webloc вам НЕ НУЖНО сохранять их, используя метод ресурсов, описанный в трех других постерах. Вы также можете написать простой список:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>URL</key>
<string>http://apple.com</string>
</dict>
</plist>
Бинарный формат ресурсов по-прежнему активно используется, и если вы хотите прочитать файл plist - убедитесь, что вам нужно прочитать оба формата файлов. Но при записи файла - используйте формат на основе plist - это намного проще.
Ответ 2
Файл A .webloc
не имеет ничего в своей вилке данных; вместо этого он сохраняет URL-адрес, который он называет ресурсом в своей ресурсной вилке. Это можно увидеть в командной строке с помощью DeRez (1) tool
Здесь я запустил его в файле .webloc
, который я вытащил из своей адресной строки Safari для этого вопроса:
% DeRez "Desktop/Crafting .webloc file - Stack Overflow.webloc"
data 'drag' (128, "Crafting .webloc file -#1701953") {
$"0000 0001 0000 0000 0000 0000 0000 0003" /* ................ */
$"5445 5854 0000 0100 0000 0000 0000 0000" /* TEXT............ */
$"7572 6C20 0000 0100 0000 0000 0000 0000" /* url ............ */
$"7572 6C6E 0000 0100 0000 0000 0000 0000" /* urln............ */
};
data 'url ' (256, "Crafting .webloc file -#1701953") {
$"6874 7470 3A2F 2F73 7461 636B 6F76 6572" /* http://stackover */
$"666C 6F77 2E63 6F6D 2F71 7565 7374 696F" /* flow.com/questio */
$"6E73 2F31 3436 3537 352F 6372 6166 7469" /* ns/146575/crafti */
$"6E67 2D77 6562 6C6F 632D 6669 6C65" /* ng-webloc-file */
};
data 'TEXT' (256, "Crafting .webloc file -#1701953") {
$"6874 7470 3A2F 2F73 7461 636B 6F76 6572" /* http://stackover */
$"666C 6F77 2E63 6F6D 2F71 7565 7374 696F" /* flow.com/questio */
$"6E73 2F31 3436 3537 352F 6372 6166 7469" /* ns/146575/crafti */
$"6E67 2D77 6562 6C6F 632D 6669 6C65" /* ng-webloc-file */
};
data 'urln' (256, "Crafting .webloc file -#1701953") {
$"4372 6166 7469 6E67 202E 7765 626C 6F63" /* Crafting .webloc */
$"2066 696C 6520 2D20 5374 6163 6B20 4F76" /* file - Stack Ov */
$"6572 666C 6F77" /* erflow */
};
Единственными ресурсами, которые, вероятно, должны быть там, являются ресурсы 'url '
и 'TEXT'
ID 256, и, возможно, им также не нужны имена ресурсов. Ресурс 'urln'
может оказаться полезным, если вы хотите включить заголовок документа, на который указывает URL. Ресурс 'drag'
сообщает системе, что это файл отсечения, но я не уверен, что он должен быть там в этот день и в возрасте.
Чтобы работать с ресурсами и вилкой ресурса файла, вы используете диспетчер ресурсов - один из основных элементов Carbon, который возвращается к исходному Mac. Тем не менее, существует несколько оболочек Cocoa для диспетчера ресурсов, таких как Nathan Day NDResourceFork.
Ответ 3
.webloc
файлы (в общем, файлы местоположения в Интернете) записываются в формате, определение которого восходит к Mac OS 8.x. Он основан на ресурсах, полученный из формата отсечения, который вы получаете при создании файла из перетаскиваемых объектов, таких как текст или изображения.
Написанные ресурсы 'url '
256 и 'TEXT'
256, которые хранят URL-адрес и необязательно "urln" 256, содержащие текст, связанный с URL-адресом. 'drag'
128 указывает на остальные два (или три) ресурса.
NTWeblocFile, часть Cocoatech Open Source framework CocoaTechFoundation (лицензия BSD) поддерживает записи этих файлов с Objective-C. Если вы хотите указать заголовок отдельно для URL-адреса, вам нужно будет изменить класс, чтобы он записывал что-то, кроме URL-адреса, в ресурс 'urln'
.
В Mac OS X 10.3 и более поздних версиях URL-адрес также записывается (также может быть записано) в список свойств в вилке данных файла. См. Другой ответ, как это работает...
Ответ 4
Еще один способ сделать "веб-ярлык" - это .url
файл, упомянутый здесь уже.
Содержимое похоже (намного проще, чем на основе plist xml):
[InternetShortcut]
URL=http://www.apple.com/
Обратите внимание, что файл имеет 3 строки, последняя строка пуста.
Дополнительная информация о формате .url
Ответ 5
Он использует двоичный формат на основе fork.
Возможные временные решения:
- Попросите пользователя перетащить URL из вашего приложения (NSURLPboardType) в Finder. Finder создаст для вас веб-сайт.
- Создайте ярлык Windows Web (файл .URL). Они имеют INI-подобный формат данных на основе данных и должны быть документированы где-то в Интернете; ОС поддерживает их, так как поддерживает weblocs.
Ответ 6
Вот как это делает Google Chrome: WriteURLToNewWebLocFileResourceFork
Ответ 7
Это основная задача, без каких-либо сторонних библиотек. (Будьте осторожны: минимальная проверка ошибок.)
// data for 'drag' resource (it always the same)
#define DRAG_DATA_LENGTH 64
static const unsigned char _dragData[DRAG_DATA_LENGTH]={
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x75, 0x72, 0x6C, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x75, 0x72, 0x6C, 0x6E, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static void _addData(NSData *data, ResType type, short resId, ResFileRefNum refNum)
{
Handle handle;
if (PtrToHand([data bytes], &handle, [data length])==noErr) {
ResFileRefNum previousRefNum=CurResFile();
UseResFile(refNum);
HLock(handle);
AddResource(handle, type, resId, "\p");
HUnlock(handle);
UseResFile(previousRefNum);
}
}
void WeblocCreateFile(NSString *location, NSString *name, NSURL *fileUrl)
{
NSString *contents=[NSString stringWithFormat:
@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
@"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
@"<plist version=\"1.0\">\n"
@"<dict>\n"
@"<key>URL</key>\n"
@"<string>%@</string>\n"
@"</dict>\n"
@"</plist>\n", location];
if ([[contents dataUsingEncoding:NSUTF8StringEncoding] writeToURL:fileUrl options:NSDataWritingAtomic error:nil])
{
// split into parent and filename parts
NSString *parentPath=[[fileUrl URLByDeletingLastPathComponent] path];
NSString *fileName=[fileUrl lastPathComponent];
FSRef parentRef;
if(FSPathMakeRef((const UInt8 *)[parentPath fileSystemRepresentation], &parentRef, NULL)==noErr)
{
unichar fileNameBuffer[[fileName length]];
[fileName getCharacters:fileNameBuffer];
FSCreateResFile(&parentRef, [fileName length], fileNameBuffer, 0, NULL, NULL, NULL);
if (ResError()==noErr)
{
FSRef fileRef;
if(FSPathMakeRef((const UInt8 *)[[fileUrl path] fileSystemRepresentation], &fileRef, NULL)==noErr)
{
ResFileRefNum resFileReference = FSOpenResFile(&fileRef, fsWrPerm);
if (resFileReference>0 && ResError()==noErr)
{
_addData([NSData dataWithBytes:_dragData length:DRAG_DATA_LENGTH], 'drag', 128, resFileReference);
_addData([location dataUsingEncoding:NSUTF8StringEncoding], 'url ', 256, resFileReference);
_addData([location dataUsingEncoding:NSUTF8StringEncoding], 'TEXT', 256, resFileReference);
_addData([name dataUsingEncoding:NSUTF8StringEncoding], 'urln', 256, resFileReference);
CloseResFile(resFileReference);
}
}
}
}
}
}