.weblocファイルの作成
-
02-07-2019 - |
質問
プログラムを作成しています(Mac OS Xの場合、Objective-Cを使用)。プログラムで多数の.weblocファイルを作成する必要があります。
.weblocファイルは、SafariのロケーションバーからフォルダーにURLをドラッグアンドドロップした後に作成される単なるファイルです。
一般的に言えば、Webの特定の場所を指すファイルシステムにアイテムを作成するアプローチが必要です。私が理解しているように、Mac OS Xでは.weblocファイルを使用する必要があります。
では、有効なURLとタイトルを含む.weblocファイルを作成することは可能ですか?
解決
あまり知られていませんが、weblocs用の単純なplistベースのファイル形式もあります。
weblocファイルを作成するとき、他の3人のポスターで説明されているリソースメソッドを使用して保存する必要はありません 。シンプルなplistを書くこともできます:
?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ベースのフォーマットを使用する-それははるかに簡単です。
他のヒント
.webloc
ファイル(より一般的には、インターネットロケーションファイル)は、その定義がMac OS 8.xにまで遡る形式で書き込まれます。これはリソースベースであり、テキストや画像などのドラッグされたオブジェクトからファイルを作成するときに取得するクリッピング形式から派生しています。
書き込まれるリソースは、URLを格納する 'url'
256および 'TEXT'
256です。オプションで、URLに関連付けられたテキストを含む 'urln' 256 。 'drag'
128は、他の2つ(または3つ)のリソースを指します。
NTWeblocFile、 Cocoatechオープンソースフレームワーク CocoaTechFoundation(BSDライセンス)の一部は、これらの書き込みをサポートしていますObjective-Cのファイル。 URLとは別にタイトルを指定する場合は、URL以外の何かを 'urln'
リソースに書き込むようにクラスを変更する必要があります。
Mac OS X 10.3以降では、URLはファイルのデータフォークのプロパティリストにも書き込まれます(書き込まれる場合もあります)。これがどのように機能するかについては、他の回答を参照してください...
.webloc
ファイルのデータフォークには何もありません。代わりに、リソースフォークのリソースとして参照するURLを保存します。これは、コマンドラインで DeRez(1)ツール
ここでは、この質問のためにSafariアドレスバーからドラッグした .webloc
ファイルで実行しました。
% DeRez "Desktop/Crafting .webloc file - Stack Overflow.webloc"
data 'drag' (128, "Crafting .webloc file -#1701953") {
<*>quot;0000 0001 0000 0000 0000 0000 0000 0003" /* ................ */
<*>quot;5445 5854 0000 0100 0000 0000 0000 0000" /* TEXT............ */
<*>quot;7572 6C20 0000 0100 0000 0000 0000 0000" /* url ............ */
<*>quot;7572 6C6E 0000 0100 0000 0000 0000 0000" /* urln............ */
};
data 'url ' (256, "Crafting .webloc file -#1701953") {
<*>quot;6874 7470 3A2F 2F73 7461 636B 6F76 6572" /* http://stackover */
<*>quot;666C 6F77 2E63 6F6D 2F71 7565 7374 696F" /* flow.com/questio */
<*>quot;6E73 2F31 3436 3537 352F 6372 6166 7469" /* ns/146575/crafti */
<*>quot;6E67 2D77 6562 6C6F 632D 6669 6C65" /* ng-webloc-file */
};
data 'TEXT' (256, "Crafting .webloc file -#1701953") {
<*>quot;6874 7470 3A2F 2F73 7461 636B 6F76 6572" /* http://stackover */
<*>quot;666C 6F77 2E63 6F6D 2F71 7565 7374 696F" /* flow.com/questio */
<*>quot;6E73 2F31 3436 3537 352F 6372 6166 7469" /* ns/146575/crafti */
<*>quot;6E67 2D77 6562 6C6F 632D 6669 6C65" /* ng-webloc-file */
};
data 'urln' (256, "Crafting .webloc file -#1701953") {
<*>quot;4372 6166 7469 6E67 202E 7765 626C 6F63" /* Crafting .webloc */
<*>quot;2066 696C 6520 2D20 5374 6163 6B20 4F76" /* file - Stack Ov */
<*>quot;6572 666C 6F77" /* erflow */
};
おそらくそこにある必要がある唯一のリソースはID 256の 'url'
および 'TEXT'
リソースであり、それらはおそらくリソース名を必要としませんどちらか。 'urln'
リソースは、URLが指すドキュメントのタイトルも含めたい場合に便利です。 'drag'
リソースは、これがクリッピングファイルであることをシステムに通知しますが、このファイルがこの時代に存在する必要があるかどうかはわかりません。
リソースとファイルのリソースフォークを操作するには、リソースマネージャー&#8212;を使用します。元のMacに戻るCarbonの基礎部分の1つ。ただし、ネイサンデイのNDResourceFork 。
「ウェブショートカット」を作成する別の方法既にここに記載されている .url
ファイルです。
内容は次のようになります(plist xmlベースよりもずっと単純です):
[InternetShortcut]
URL=http://www.apple.com/
ファイルには3行あり、最後の行は空です。
リソースフォークベースのバイナリ形式を使用します。
有効な回避策:
- ユーザーにアプリケーション(NSURLPboardType)からFinderにURLをドラッグしてもらいます。 Finderがweblocを作成します。
- Windows Webショートカット(.URLファイル)を作成します。これらはINIに似たデータフォークベースの形式であり、インターネット上のどこかに文書化する必要があります。 OSはweblocをサポートするため、それらをサポートします。
Google Chromeの仕組み: WriteURLToNewWebLocFileResourceFork
これは、サードパーティのライブラリを必要とせずに、基本的なタスクを実行します。 (警告:最小限のエラーチェック。)
// data for 'drag' resource (it's 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);
}
}
}
}
}
}