執筆者: エディフィストラーニング株式会社 矢嶋 聡

動作確認環境: Visual Studio 2010 (Visual C++ 2010 Express も可能)


ここでは、Windows 7 上でデータ集合を管理する新しい仕組みである「ライブラリ」に対して、Windows Shell API を用いて、特定の名前のライブラリを削除する方法を示します。

ライブラリを削除することは、実質的に Library Description File (拡張子 ".library-ms" のファイル) を削除することですから、このファイルのパスさえ分かれば、単に DeleteFile 関数で削除することができます。しかし、一般的に Library Description File はユーザーごとの既知のフォルダー (Known Folder) に保存されていることが多いために、予め物理的なパスを決め打ちすることは困難です。この理由から、以下のサンプル コードでは、既知のフォルダーのパスを取得し、ライブラリのファイル パスを求めたうえで、そのファイルを削除する方法を示しています。

なお、このサンプル コードでは、COM 関連の API を使用しているので、COM に関する基礎知識が必要です。

Note:
プログラム コードを利用したライブラリの作成方法は、次の逆引きを参照してください。

以下の例 1 は、「書庫」という名前のライブラリを削除するコードです。

例 1.

C++
#include "stdafx.h" 
 
#include "shlobj.h"  // SHGetKnownFolderItemなど ←[1] 
#include "propkey.h" // PKEY_ParsingPath ←[2] 
 
int _tmain(int argc, _TCHAR* argv[]) 
{ 
    LPCWSTR pszLibraryName = L"書庫"//←[3] 
 
    HRESULT hr; 
    hr = ::CoInitialize(NULL);  //←[4] 
 
    WCHAR szLibraryFile[MAX_PATH];    //←[5] 
    ::swprintf_s(szLibraryFile, MAX_PATH, L"%s%s",  
                 pszLibraryName, L".library-ms"); 
 
    IShellItem2 *pLibraryItem;        //←[6] 
    hr = ::SHCreateItemInKnownFolder(                           //←[7] 
            FOLDERID_UsersLibraries, 0, (PCWSTR)szLibraryFile,  //←[8] 
            IID_IShellItem2, (void**)&pLibraryItem);            //←[9] 
    if(hr == S_OK) 
    { 
        LPWSTR pszLibraryFullPath; 
        hr = pLibraryItem->GetString(PKEY_ParsingPath, &pszLibraryFullPath);  //←[10] 
        if(hr == S_OK) 
        { 
            BOOL result; 
            result = ::DeleteFileW(pszLibraryFullPath);  //←[11] 
            ::CoTaskMemFree((LPVOID)pszLibraryFullPath); //←[12] 
        } 
 
        pLibraryItem->Release(); //←[13] 
    } 
 
    ::CoUninitialize(); //←[14] 
 
    return 0} 
 
 
 

Note: サンプル コードの検証環境
このサンプル コードの動作を検証する場合、Visual Studio 2010 (Visual C++ 2010 Express) で「Win32 コンソール アプリケーション」プロジェクトを既定構成のまま新規作成したのち、例 1 のように main 関数に対して、修正や追加を行ってください。また、ここでは簡単にするため、プロジェクトの既定である Unicode 文字セットを使用しており、すべての文字列データは Unicode 文字列で統一しました。

そして、「書庫」ライブラリがライブラリ用の既知のフォルダーに作成されてるいことが必要です。前述の「 [逆引き] 特定の Shell ライブラリを作成する」では、既知のフォルダーへのライブラリの作成方法が記載されています。あるいは、エクスプローラー上の左ペインのツリーで、「ライブラリ」ノードを右クリックして、ショートカット メニューからライブラリを新規作成した場合も、既知のフォルダーに作成できます。

例 1 において、ライブラリを作成するうえで必要な入力情報は、[3] のライブラリの名前です。

今回のコードで固有に必要となるヘッダーは、Shell 関連の定義を含む [1] のヘッダーのほか、Shell Item オブジェクト (IShellItem2 オブジェクト) のフル パスのプロパティを取得するために、そのプロパティの識別子 (PKEY_ParsingPath) が必要なために、[2] のヘッダーもインクルードします。また、Windows Shell のライブラリ関連の API は COM ベースなので、利用する際には [4] や [14] のように、COM の初期化と後処理が必要です。

既に説明したように、ライブラリを削除することは、Library Description File (拡張子 ".library-ms") を削除すればよいので、既知のフォルダーに保存されたライブラリのフル パスを求める必要があります。

そのために、最初に [5] の文字列 szLibraryFile では、その次行の swprintf_s 関数を用いて、「書庫.library-ms」という拡張子付きのファイル名を作成しています。

このファイル「書庫.library-ms」のフル パスを調べる方法の 1 つとしては、このファイルの Shell Item オブジェクトを作成し、そのプロパティを参照する方法があります。

そこで [6] では、この Shell Item オブジェクトを参照するためのインターフェイス ポインター (IShellItem2) を用意したのち、[7] では SHCreateItemInKnownFolder 関数を呼び出して、Shell Item オブジェクトを作成しています。

この SHCreateItemInKnownFolder 関数の引数には、Shell Item オブジェクトとして作成したいファイルが保管されたフォルダーと、そのファイル名を指定します。引数としてフォルダーを指定する際には、既知のフォルダーの識別子を指定する必要があり、[8] の FOLDERID_UsersLibraries がライブラリの既知のフォルダーを表す識別子です。そして、[8] の szLibraryFile がファイル名「書庫.library-ms」です。このライブラリ ファイル「書庫.library-ms」の Shell Item オブジェクトが作成されると、[9] で引数に渡されたポインター pLibraryItem を用いて、Shell Item オブジェクト (IShellItem2 オブジェクト) が参照できるようになります。

次に [10] では、この Shell Item オブジェクトの ParsingPath プロパティを調べて、このファイルのフル パスを pszLibraryFullPath が指し示す領域に取得しています。あとは、取得したフル パスを使用して、[11] のように DeleteFile 関数を呼び出せば、「書庫.library-ms」は削除されます。

なお、この pszLibraryFullPath が指し示す領域は、COM タスク メモリ アロケーターによって確保されたものなので、[12] の CoTaskMemFree 関数を用いて解放しています。また [13] では、Shell Item オブジェクトの Release メソッドを呼び出して、オブジェクトを解放しています。

これを実行すると、予め用意された「書庫」ライブラリは削除され、エクスプローラー上から表示されなくなります。


Code Recipe Visual C++ デベロッパー センター

ページのトップへ