シェル リンク
シェル リンク は、シェルの名前空間内の別のオブジェクトにアクセスするために使用される情報 、つまり Windows エクスプローラーから表示される任意のオブジェクトを含むデータ オブジェクトです。 シェル リンクを介してアクセスできるオブジェクトの種類には、ファイル、フォルダー、ディスク ドライブ、プリンターがあります。 シェル リンクを使用すると、ユーザーまたはアプリケーションは名前空間内のどこからでもオブジェクトにアクセスできます。 ユーザーまたはアプリケーションは、オブジェクトの現在の名前と場所を知る必要はありません。
- シェル リンクの について
- シェル リンクの使用 の
- ファイル へのショートカットとフォルダー ショートカットの作成
- ショートカット の解決の
- 非ファイル オブジェクト へのショートカットの作成
シェル リンクについて
ユーザーは、オブジェクトのショートカット メニューから [ショートカットの作成] コマンド 選択して、シェル リンクを作成します。 オブジェクトのアイコンと、アイコンの左下隅に表示される小さな矢印 (システム定義のリンク オーバーレイ アイコン) を組み合わせることにより、シェル リンクのアイコンが自動的に作成されます。 アイコンを含むシェル リンクはショートカットと呼ばれます。ただし、シェル のリンクとショートカットという用語は、多くの場合、同じ意味で使用されます。 通常、ユーザーはショートカットを作成して、サブフォルダーまたは他のコンピューター上の共有フォルダーに格納されているオブジェクトにすばやくアクセスできます。 たとえば、ユーザーは、サブフォルダーにある Microsoft Word 文書へのショートカットを作成し、ショートカット アイコンをデスクトップに配置できます。 その後、ユーザーはショートカット アイコンをダブルクリックしてドキュメントを開くことができます。 ショートカットの作成後にドキュメントを移動または名前変更すると、ユーザーが次回ショートカットを選択したときに、ショートカットの更新が試行されます。
アプリケーションでは、シェルのリンクとショートカットを作成して使用することもできます。 たとえば、ワープロ アプリケーションでは、最近使用したドキュメントの一覧を実装するためのシェル リンクを作成できます。 アプリケーションは、IShellLink インターフェイスを使用してシェル リンク オブジェクトを作成することによってシェル リンクを作成します。 アプリケーションは、IPersistFile または IPersistStreamインターフェイス使用して、オブジェクトをファイルまたはストリームに格納します。
手記
IShellLink を使用して URL へのリンクを作成することはできません。
この概要では、IShellLinkインターフェイスについて説明し、それを使用して Microsoft Win32 ベースのアプリケーション内からシェル リンクを作成および解決する方法について説明します。 シェル リンクの設計は OLE コンポーネント オブジェクト モデル (COM) に基づいているため、この概要を読む前に COM と OLE プログラミングの基本的な概念を理解しておく必要があります。
リンクの解決
ユーザーがオブジェクトへのショートカットを作成し、オブジェクトの名前または場所が後で変更された場合、次回ユーザーが選択したショートカットを自動的に更新または解決する手順が実行されます。 ただし、アプリケーションがシェル リンクを作成してストリームに格納した場合、システムはリンクの解決を自動的に試行しません。 アプリケーションは、IShellLink::Resolve メソッドを呼び出してリンクを解決する必要があります。
シェル リンクが作成されると、リンクに関する情報が保存されます。 自動的に、または IShellLink::Resolve 呼び出しを使用してリンクを解決する場合、システムは最初にシェル リンクの識別子リストへのポインターを使用して、シェル リンクに関連付けられているパスを取得します。 識別子リストの詳細については、「項目識別子と識別子リストの」を参照してください。 システムは、そのパス内の関連オブジェクトを検索し、オブジェクトが見つかるとリンクを解決します。 オブジェクトが見つからない場合は、Distributed Link Tracking および Object Identifiers (DLT) サービス (使用可能な場合) を呼び出してオブジェクトを見つけます。 DLT サービスが使用できない場合、またはオブジェクトが見つからない場合、システムは同じディレクトリ内で、同じファイルの作成時刻と属性が異なるオブジェクトを検索します。 この種類の検索では、名前が変更されたオブジェクトへのリンクが解決されます。
それでもオブジェクトが見つからない場合は、ディレクトリ、デスクトップ、およびローカル ボリュームが検索され、ディレクトリ ツリーで同じ名前または作成時のオブジェクトが再帰的に検索されます。 それでも一致するものが見つからない場合は、ユーザーに場所の入力を求めるダイアログ ボックスが表示されます。 アプリケーションは、IShellLink::Resolveの呼び出しで SLR_NO_UI 値指定することで、ダイアログ ボックスを抑制できます。
コンポーネント オブジェクト ライブラリの初期化
アプリケーションは、ショートカットを作成して解決する前に、CoInitialize 関数を呼び出してコンポーネント オブジェクト ライブラリを初期化する必要があります。 CoInitialize を する各呼び出しには、CoUninitialize 関数への対応する呼び出しが必要です。この関数は、アプリケーションが終了するときに呼び出す必要があります。 CoUninitialize の呼び出しにより、保留中のすべてのメッセージを受信するまでアプリケーションは終了しません。
Location-Independent 名
システムは、共有フォルダーに格納されているオブジェクトへのシェル リンクの場所に依存しない名前を提供します。 オブジェクトがローカルに格納されている場合、システムはオブジェクトのローカル パスとファイル名を提供します。 オブジェクトがリモートに格納されている場合、システムはオブジェクトの汎用名前付け規則 (UNC) ネットワーク リソース名を提供します。 システムは場所に依存しない名前を提供するため、シェル リンクは、他のコンピューターに転送できるファイルの汎用名として機能できます。
ファイルのリンク
ユーザーがオブジェクトのショートカット メニューから ショートカットの作成 コマンドを選択してオブジェクトへのショートカットを作成すると、Windows は、オブジェクトにアクセスするために必要な情報をリンク ファイル (.lnk ファイル名拡張子を持つバイナリ ファイル) に格納します。 リンク ファイルには、次の情報が含まれています。
- ショートカットによって参照されるオブジェクトの場所 (パス) (対応するオブジェクトと呼ばれます)。
- 対応するオブジェクトの作業ディレクトリ。
- IContextMenu::InvokeCommand メソッドがショートカット用にアクティブ化されたときに、システムが対応するオブジェクトに渡す引数の一覧。
- 対応するオブジェクトの初期状態の表示を設定するために使用される show コマンド。 これは、ShowWindowで説明されているSW_値の 1 つです。
- ショートカットのアイコンの場所 (パスとインデックス)。
- ショートカットの説明文字列。
- ショートカットのキーボード ショートカット。
リンク ファイルを削除しても、対応するオブジェクトは影響を受けません。
別のショートカットへのショートカットを作成すると、新しいリンク ファイルを作成するのではなく、リンク ファイルがコピーされます。 この場合、ショートカットは互いに独立しません。
アプリケーションでは、ファイル名拡張子をショートカット ファイルの種類として登録できます。 ファイルにショートカット ファイルの種類として登録されているファイル名拡張子がある場合、システムは自動的にシステム定義のリンク オーバーレイ アイコン (小さい矢印) をファイルのアイコンに追加します。 ファイル名拡張子をショートカット ファイルの種類として登録するには、次の例に示すように、ファイル名拡張子のレジストリの説明に IsShortcut 値を追加する必要があります。 オーバーレイ アイコンを有効にするには、シェルを再起動する必要があることに注意してください。 IsShortcut にはデータ値がありません。
HKEY_CLASSES_ROOT
.xyz
(Default) = XYZApp
XYZApp
IsShortcut
ショートカット名
シェル リンク アイコンの下に表示される文字列であるショートカットの名前は、実際にはショートカット自体のファイル名です。 ユーザーは、説明文字列を選択して新しい文字列を入力することで編集できます。
名前空間内のショートカットの場所
ショートカットは、デスクトップまたはシェルの名前空間の任意の場所に存在できます。 同様に、ショートカットに関連付けられているオブジェクトは、シェルの名前空間の任意の場所に存在することもできます。 アプリケーションでは、IShellLink::SetPath メソッドを使用して、関連付けられたオブジェクトのパスとファイル名を設定し、IShellLink::GetPath メソッドを使用して、オブジェクトの現在のパスとファイル名を取得できます。
ショートカット作業ディレクトリ
作業ディレクトリは、ユーザーが特定のディレクトリを識別しない場合に、ショートカットの対応するオブジェクトがファイルを読み込んだり格納したりするディレクトリです。 リンク ファイルには、対応するオブジェクトの作業ディレクトリの名前が含まれています。 アプリケーションは、IShellLink::SetWorkingDirectory メソッドを使用して対応するオブジェクトの作業ディレクトリの名前を設定でき、IShellLink::GetWorkingDirectory メソッドを使用して、対応するオブジェクトの現在の作業ディレクトリの名前を取得できます。
ショートカット コマンド ライン引数
リンク ファイルには、ユーザーがリンクを選択したときにシェルが対応するオブジェクトに渡すコマンド ライン引数が含まれています。 アプリケーションでは、IShellLink::SetArguments メソッドを使用して、ショートカットのコマンド ライン引数を設定できます。 リンカーやコンパイラなどの対応するアプリケーションが特殊なフラグを引数として受け取る場合は、コマンド ライン引数を設定すると便利です。 アプリケーションは、IShellLink::GetArguments メソッドを使用して、ショートカットからコマンド ライン引数を取得できます。
ショートカット表示コマンド
ユーザーがショートカットをダブルクリックすると、対応するオブジェクトに関連付けられているアプリケーションが起動され、ショートカットで指定された show コマンドに基づいてアプリケーションの初期状態が設定されます。 show コマンドには、ShowWindow 関数の説明に含まれる任意のSW_値を指定できます。 アプリケーションでは、IShellLink::SetShowCmd メソッドを使用してショートカットの show コマンドを設定し、IShellLink::GetShowCmd メソッドを使用して現在の show コマンドを取得できます。
ショートカット アイコン
他のシェル オブジェクトと同様に、ショートカットにはアイコンがあります。 ユーザーは、ショートカットのアイコンをダブルクリックして、ショートカットに関連付けられているオブジェクトにアクセスします。 ショートカットのアイコンを作成すると、対応するオブジェクトのビットマップが使用され、システム定義のリンク オーバーレイ アイコン (小さい矢印) が左下隅に追加されます。 アプリケーションは、IShellLink::SetIconLocation メソッドを使用して、ショートカットのアイコンの場所 (パスとインデックス) を設定できます。 アプリケーションは、IShellLink::GetIconLocation メソッドを使用して、この場所を取得できます。
ショートカットの説明
ショートカットには説明がありますが、ユーザーには表示されません。 アプリケーションでは、説明を使用して任意のテキスト情報を格納できます。 説明は、IShellLink::SetDescription メソッドを使用して設定し、IShellLink::GetDescription メソッドを使用して取得します。
ショートカット キーボード ショートカット
ショートカット オブジェクトには、キーボード ショートカットを関連付けることができます。 キーボード ショートカットを使用すると、ユーザーはキーの組み合わせを押してショートカットをアクティブ化できます。 アプリケーションでは、IShellLink::SetHotkey メソッドを使用してショートカットのキーボード ショートカットを設定し、IShellLink::GetHotkey メソッドを使用して現在のキーボード ショートカットを取得できます。
アイテム識別子と識別子リスト
シェルは、シェルの名前空間内のオブジェクト識別子を使用します。 シェルに表示されるすべてのオブジェクト (ファイル、ディレクトリ、サーバー、ワークグループなど) には、親フォルダー内のオブジェクト間で一意の識別子があります。 これらの識別子は項目識別子と呼ばれ、shtypes.h ヘッダー ファイルで定義されているデータ型SHITEMID を持ちます。 項目識別子は、フォルダー内のオブジェクトを識別する情報を含む可変長バイト ストリームです。 アイテム識別子の作成者のみが、識別子の内容と形式を認識します。 シェルが使用する項目識別子の唯一の部分は、識別子のサイズを指定する最初の 2 バイトです。
各親フォルダーには、独自の親フォルダー内でそれを識別する独自の項目識別子があります。 したがって、すべてのシェル オブジェクトは、項目識別子のリストによって一意に識別できます。 親フォルダーには、含まれる項目の識別子の一覧が保持されます。 リストには、データ型ITEMIDLIST があります。 項目識別子リストはシェルによって割り当てられ、IShellFolderなどのシェル インターフェイス間で渡すことができます。 アイテム識別子リスト内の各識別子は、親フォルダーのコンテキスト内でのみ意味を持つ点に注意してください。
アプリケーションは、IShellLink::SetIDList メソッドを使用して、ショートカットの項目識別子リストを設定できます。 このメソッドは、プリンターやディスク ドライブなど、ファイルではないオブジェクトへのショートカットを設定する場合に便利です。 アプリケーションは、IShellLink::GetIDList メソッドを使用して、ショートカットの項目識別子リストを取得できます。
シェル リンクの使用
このセクションには、Win32 ベースのアプリケーション内からショートカットを作成して解決する方法を示す例が含まれています。 このセクションでは、Win32、C++、および OLE COM プログラミングについて理解していることを前提としています。
ファイルへのショートカットとフォルダー ショートカットの作成
次の例の CreateLink サンプル関数は、ショートカットを作成します。 パラメーターには、リンク先のファイル名へのポインター、作成するショートカットの名前へのポインター、リンクの説明へのポインターが含まれます。 説明は、"ファイル名へのショートカット" という文字列で構成されます。ここで、ファイル名 は、リンク先のファイルの名前です。
CreateLink サンプル関数を使用してフォルダー ショートカットを作成するには、CLSID_ShellLinkではなく、CLSID_FolderShortcutを使用して CoCreateInstance呼び出します (CLSID_FolderShortcutは IShellLink をサポートしています)。 その他のコードはすべて同じままです。
CreateLink は CoCreateInstance 関数を呼び出すので、CoInitialize 関数が既に呼び出されていることを前提としています。 CreateLink では、IPersistFile インターフェイスを使用してショートカットを保存し、IShellLink インターフェイスを使用してファイル名と説明を格納します。
// CreateLink - Uses the Shell's IShellLink and IPersistFile interfaces
// to create and store a shortcut to the specified object.
//
// Returns the result of calling the member functions of the interfaces.
//
// Parameters:
// lpszPathObj - Address of a buffer that contains the path of the object,
// including the file name.
// lpszPathLink - Address of a buffer that contains the path where the
// Shell link is to be stored, including the file name.
// lpszDesc - Address of a buffer that contains a description of the
// Shell link, stored in the Comment field of the link
// properties.
#include "stdafx.h"
#include "windows.h"
#include "winnls.h"
#include "shobjidl.h"
#include "objbase.h"
#include "objidl.h"
#include "shlguid.h"
HRESULT CreateLink(LPCWSTR lpszPathObj, LPCSTR lpszPathLink, LPCWSTR lpszDesc)
{
HRESULT hres;
IShellLink* psl;
// Get a pointer to the IShellLink interface. It is assumed that CoInitialize
// has already been called.
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);
if (SUCCEEDED(hres))
{
IPersistFile* ppf;
// Set the path to the shortcut target and add the description.
psl->SetPath(lpszPathObj);
psl->SetDescription(lpszDesc);
// Query IShellLink for the IPersistFile interface, used for saving the
// shortcut in persistent storage.
hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);
if (SUCCEEDED(hres))
{
WCHAR wsz[MAX_PATH];
// Ensure that the string is Unicode.
MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH);
// Add code here to check return value from MultiByteWideChar
// for success.
// Save the link by calling IPersistFile::Save.
hres = ppf->Save(wsz, TRUE);
ppf->Release();
}
psl->Release();
}
return hres;
ショートカットの解決
アプリケーションは、以前に作成されたショートカットにアクセスして操作する必要がある場合があります。 この操作は、ショートカットの解決と呼ばれます。
次の例のアプリケーション定義 ResolveIt 関数は、ショートカットを解決します。 そのパラメーターには、ウィンドウ ハンドル、ショートカットのパスへのポインター、およびオブジェクトへの新しいパスを受け取るバッファーのアドレスが含まれます。 ウィンドウ ハンドルは、シェルが表示する必要があるメッセージ ボックスの親ウィンドウを識別します。 たとえば、リンクが共有されていないメディア上にある場合、ネットワークの問題が発生した場合、ユーザーがフロッピー ディスクを挿入する必要がある場合などに、シェルでメッセージ ボックスを表示できます。
ResolveIt 関数は、CoCreateInstance 関数を呼び出し、CoInitialize 関数が既に呼び出されていることを前提としています。 ResolveIt は、IPersistFileインターフェイスを使用してリンク情報を格納する必要があることに注意してください。 IPersistFile は、IShellLink オブジェクトによって実装されます。 パス情報を取得する前にリンク情報を読み込む必要があります。この例の後半で示します。 リンク情報を読み込めなかった場合、IShellLink::GetPath と IShellLink::GetDescription メンバー関数の呼び出しが失敗します。
// ResolveIt - Uses the Shell's IShellLink and IPersistFile interfaces
// to retrieve the path and description from an existing shortcut.
//
// Returns the result of calling the member functions of the interfaces.
//
// Parameters:
// hwnd - A handle to the parent window. The Shell uses this window to
// display a dialog box if it needs to prompt the user for more
// information while resolving the link.
// lpszLinkFile - Address of a buffer that contains the path of the link,
// including the file name.
// lpszPath - Address of a buffer that receives the path of the link
target, including the file name.
// lpszDesc - Address of a buffer that receives the description of the
// Shell link, stored in the Comment field of the link
// properties.
#include "stdafx.h"
#include "windows.h"
#include "shobjidl.h"
#include "shlguid.h"
#include "strsafe.h"
HRESULT ResolveIt(HWND hwnd, LPCSTR lpszLinkFile, LPWSTR lpszPath, int iPathBufferSize)
{
HRESULT hres;
IShellLink* psl;
WCHAR szGotPath[MAX_PATH];
WCHAR szDescription[MAX_PATH];
WIN32_FIND_DATA wfd;
*lpszPath = 0; // Assume failure
// Get a pointer to the IShellLink interface. It is assumed that CoInitialize
// has already been called.
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);
if (SUCCEEDED(hres))
{
IPersistFile* ppf;
// Get a pointer to the IPersistFile interface.
hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
if (SUCCEEDED(hres))
{
WCHAR wsz[MAX_PATH];
// Ensure that the string is Unicode.
MultiByteToWideChar(CP_ACP, 0, lpszLinkFile, -1, wsz, MAX_PATH);
// Add code here to check return value from MultiByteWideChar
// for success.
// Load the shortcut.
hres = ppf->Load(wsz, STGM_READ);
if (SUCCEEDED(hres))
{
// Resolve the link.
hres = psl->Resolve(hwnd, 0);
if (SUCCEEDED(hres))
{
// Get the path to the link target.
hres = psl->GetPath(szGotPath, MAX_PATH, (WIN32_FIND_DATA*)&wfd, SLGP_SHORTPATH);
if (SUCCEEDED(hres))
{
// Get the description of the target.
hres = psl->GetDescription(szDescription, MAX_PATH);
if (SUCCEEDED(hres))
{
hres = StringCbCopy(lpszPath, iPathBufferSize, szGotPath);
if (SUCCEEDED(hres))
{
// Handle success
}
else
{
// Handle the error
}
}
}
}
}
// Release the pointer to the IPersistFile interface.
ppf->Release();
}
// Release the pointer to the IShellLink interface.
psl->Release();
}
return hres;
}
Nonfile オブジェクトへのショートカットの作成
プリンターなどのファイル以外のオブジェクトへのショートカットを作成することは、ファイルへのパスを設定するのではなく、識別子リストをプリンターに設定する必要がある点を除き、ファイルへのショートカットを作成するのと似ています。 識別子リストを設定するには、識別子リストのアドレスを指定して、IShellLink::SetIDList メソッドを呼び出します。
シェルの名前空間内の各オブジェクトには項目識別子があります。 シェルは、多くの場合、項目識別子を任意の数の項目識別子で構成される null で終わるリストに連結します。 アイテム識別子の詳細については、「アイテム識別子と識別子リストの」を参照してください。
一般に、プリンターなどのファイル名を持たない項目へのショートカットを設定する必要がある場合は、既にオブジェクトの IShellFolder インターフェイスへのポインターがあります。 IShellFolder を使用して名前空間拡張機能を作成します。
IShellFolderのクラス識別子を取得したら、CoCreateInstance 関数を呼び出して、インターフェイスのアドレスを取得できます。 その後、インターフェイスを呼び出してフォルダー内のオブジェクトを列挙し、検索するオブジェクトの項目識別子のアドレスを取得できます。 最後に、IShellLink::SetIDList メンバー関数の呼び出しでアドレスを使用して、オブジェクトへのショートカットを作成できます。