トレーニング
モジュール
.NET アプリでファイルとディレクトリを操作する - Training
.NET、C#、System.IO を使用して、ディレクトリ、パス、ファイル、ファイル システムを操作する方法について説明します。
このブラウザーはサポートされなくなりました。
Microsoft Edge にアップグレードすると、最新の機能、セキュリティ更新プログラム、およびテクニカル サポートを利用できます。
「フォルダーの ID の取得」セクションでは、項目識別子リスト (PIDL) への名前空間オブジェクトのポインターを取得するための 2 つの方法について説明しました。 1 つの明白な質問として、PIDL を取得したら、何を行うことができるかというものがあります。 それに関連する質問として、どちらのアプローチも機能していない場合、またはアプリケーションに適していない場合はどうかというのもあります。 この 2 つの質問に対する答えは、名前空間がどのように実装されているかを詳しく見る必要があります。 キーは IShellFolder インターフェイスです。
このドキュメントの前半では、名前空間フォルダーはオブジェクトと呼ばれてました。 その時点で、この用語は緩やかな意味で使用されていましたが、実際には厳密な意味でも当てはまります。 すべての名前空間フォルダーは、コンポーネント オブジェクト モデル (COM) オブジェクトによって表されます。 各フォルダー オブジェクトには、さまざまなタスクに使用できるインターフェイスが多数公開されています。 オプションの一部のインターフェイスは、すべてのフォルダーで公開されない場合があります。 ただし、すべてのフォルダーで基本的なインターフェイスである IShellFolder を公開する必要があります。
フォルダー オブジェクトを使用する最初の手順は、その IShellFolder インターフェイスへのポインターを取得することです。 IShellFolder は、オブジェクトの他のインターフェイスへのアクセスを提供するだけでなく、多くの一般的なタスクを処理するメソッドのグループを公開しています。そのうちのいくつかについては、このセクションで説明します。
名前空間オブジェクトの IShellFolder インターフェイスへのポインターを取得するには、最初に SHGetDesktopFolder を呼び出す必要があります。 この関数は、名前空間ルート (デスクトップ) の IShellFolder インターフェイスへのポインターを返します。 デスクトップの IShellFolder インターフェイスを用意したら、さまざまな方法で作業を進められます。
たとえば、SHGetFolderLocation を呼び出すことによって、目的のフォルダーの PIDL が既にある場合は、デスクトップの IShellFolder::BindToObject メソッドを呼び出して IShellFolder インターフェイスを取得できます。 ファイル システム オブジェクトのパスがある場合は、まずデスクトップの IShellFolder::P arseDisplayName メソッドを呼び出して PIDL を取得してから、IShellFolder::BindToObject を呼び出す必要があります。 どちらの方法も適用できない場合は、他の IShellFolder メソッドを使用して名前空間を移動できます。 詳細については、「名前空間の移動」を参照してください。
通常、フォルダーに対して行う最初の操作は、フォルダーに含まれている内容を調べることです。 最初に、フォルダーの IShellFolder::EnumObjects メソッドを呼び出す必要があります。 フォルダーは標準の OLE 列挙オブジェクトを作成し、その IEnumIDList インターフェイスを返します。 このインターフェイスは、フォルダーの内容を列挙するために使用できる 4 つの標準メソッド (Clone、Next、Reset、Skip) を公開します。
フォルダーの内容を列挙する基本的な手順は次のとおりです。
注意
完全な PIDL と相対的な PIDL のどちらを使用しているかを追跡することが重要です。 一部の関数とメソッドはどちらかを受け入れますが、関数とメソッドによってはどちらか一方しか受け入れないものもあります。
残りの 3 つの IEnumIDList メソッド (Reset、Skip、Clone) は、フォルダーの列挙を繰り返す必要がある場合に便利です。 これにより列挙をリセットしたり、1 つ以上のオブジェクトをスキップしたり、列挙オブジェクトのコピーを作成してその状態を保持したりできます。
フォルダーに含まれるすべての PIDL を列挙すると、それらがどのようなオブジェクトを表しているかを確認できます。 IShellFolder インターフェイスには便利なメソッドが多数用意されており、ここではそのうちの 2 つについて説明します。 その他の IShellFolder メソッドとその他のシェル フォルダー インターフェイスについては、後で説明します。
最も便利なプロパティの一つは、オブジェクトの表示名です。 オブジェクトの表示名を取得するには、その PIDL を IShellFolder::GetDisplayNameOf に渡します。 オブジェクトは名前空間内の親フォルダーより下の任意の場所に配置できますが、その PIDL はフォルダーに対して相対的である必要があります。
IShellFolder::GetDisplayNameOf は、表示名を STRRET 構造体の一部として返します。 STRRET 構造体から表示名を抽出するのは少し難しい場合があるため、シェルには、StrRetToStr と StrRetToBuf という 2 つの関数が提供されています。 どちらの関数も STRRET 構造体を受け取り、表示名を通常の文字列として返します。 両社の違いは、文字列の割り当て方法のみです。
オブジェクトは、表示名に加えて、フォルダーかどうか、移動可能かどうかなど、さまざまな属性を持つことができます。 オブジェクトの属性を取得するには、その PIDL を IShellFolder::GetAttributesOf に渡します。 属性の完全なリストは非常に大きいため、詳細についてはリファレンスを参照してください。 GetAttributesOf に渡す PIDL は単一レベルである必要があることに注意してください。 特に、 IShellFolder::GetAttributesOf は IEnumIDList::Nextによって返される PIDL を受け入れます。 PIDL の配列を渡すことができ、GetAttributesOf は、配列内のすべてのオブジェクトに共通する属性を返します。
オブジェクトの完全修飾パスまたは PIDL がある場合、SHGetFileInfo は、多くの目的に十分なオブジェクトに関する情報を簡単に取得する方法を提供します。 SHGetFileInfo は完全修飾パスまたは PIDL を受け取り、次のようなオブジェクトに関するさまざまな情報を返します。
フォルダーにサブフォルダーが含まれているかどうかを確認するには、IShellFolder::GetAttributesOf を呼び出して、SFGAO_FOLDER フラグが設定されているかどうかを確認することで判断できます。 オブジェクトがフォルダーの場合は、そのオブジェクトにバインドすることで、その IShellFolder インターフェイスへのポインターが提供されます。
サブフォルダーにバインドするには、親フォルダーの IShellFolder::BindToObject メソッドを呼び出します。 このメソッドは、サブフォルダーの PIDL を受け取り、その IShellFolder インターフェイスへのポインターを返します。 このポインターを取得したら、IShellFolder メソッドを使用してサブフォルダーの内容を列挙したり、そのプロパティを決定したりできます。
オブジェクトの PIDL がある場合は、親フォルダーによって公開されているインターフェイスの 1 つに対するハンドルが必要な場合があります。 たとえば、IShellFolder::GetDisplayNameOf を使用して PIDL に関連付けられている表示名を決定する場合は、まずオブジェクトの親の IShellFolder インターフェイスを取得する必要があります。 これは、前のセクションで説明した手法で取得できます。 しかし、シェル関数 SHBindToParent を使用することで、より簡単に取得できます。 この関数は、オブジェクトの完全修飾 PIDL を受け取り、親フォルダー上の指定されたインターフェイス ポインターを返します。 必要に応じて、IShellFolder::GetAttributesOf などのメソッドで使用する項目の単一レベルの PIDL も返します。
次のサンプル コンソール アプリケーションは、System の特殊フォルダーの PIDL を取得し、その表示名を返します。
#include <shlobj.h>
#include <shlwapi.h>
#include <iostream.h>
#include <objbase.h>
int main()
{
IShellFolder *psfParent = NULL;
LPITEMIDLIST pidlSystem = NULL;
LPCITEMIDLIST pidlRelative = NULL;
STRRET strDispName;
TCHAR szDisplayName[MAX_PATH];
HRESULT hr;
hr = SHGetFolderLocation(NULL, CSIDL_SYSTEM, NULL, NULL, &pidlSystem);
hr = SHBindToParent(pidlSystem, IID_IShellFolder, (void **) &psfParent, &pidlRelative);
if(SUCCEEDED(hr))
{
hr = psfParent->GetDisplayNameOf(pidlRelative, SHGDN_NORMAL, &strDispName);
hr = StrRetToBuf(&strDispName, pidlSystem, szDisplayName, sizeof(szDisplayName));
cout << "SHGDN_NORMAL - " <<szDisplayName << '\n';
}
psfParent->Release();
CoTaskMemFree(pidlSystem);
return 0;
}
アプリケーションはまず、SHGetFolderLocation を使用してSystem のフォルダーの PIDL を取得します。 次に、SHBindToParent を呼び出し、親フォルダーの IShellFolder インターフェイスへのポインターと、System のフォルダーの PIDL を返します。 次に、親フォルダーの IShellFolder::GetDisplayNameOf メソッドを使用して、System のフォルダーの表示名を取得します。 GetDisplayNameOf は STRRET 構造体を返すため、StrRetToBuf を使用して表示名を通常の文字列に変換します。 表示名を表示すると、インターフェイス ポインターが解放され、システム PIDL が解放されます。 SHBindToParent によって返される相対 PIDL を解放しないでください。
トレーニング
モジュール
.NET アプリでファイルとディレクトリを操作する - Training
.NET、C#、System.IO を使用して、ディレクトリ、パス、ファイル、ファイル システムを操作する方法について説明します。
ドキュメント
IShellFolder (shobjidl_core.h) - Win32 apps
すべてのシェル名前空間フォルダー オブジェクトによって公開され、そのメソッドはフォルダーの管理に使用されます。
SHParseDisplayName 関数 (shlobj_core.h) - Win32 apps
Shell 名前空間オブジェクトの表示名を項目識別子リストに変換し、オブジェクトの属性を返します。 この関数は、文字列を項目識別子リスト (PIDL) へのポインターに変換するために推奨される方法です。
ITEMIDLIST (shtypes.h) - Win32 apps
アイテム識別子の一覧を格納します。