你可以通過 http://cfx.codeplex.com/Release/ProjectReleases.aspx下載到Windows 7 Shell Library相關的sample。其中包含C++、C#、VB.NET對Shell Library操作的範例程式碼:CppWin7ShellLibrary, C#Win7ShellLibrary, VBWin7ShellLibrary。
為了協助使用者更加有效地對硬碟上的檔案進行管理,Windows 7中引入了新的檔案管理方式:庫(Library)。庫自然演化自以往作業系統中My Documents 檔案夾這個概念。有了庫,我們就可以將多個相關的檔案夾組織到同一個庫下,從而更快更便捷地管理和搜尋資料。
建立Windows Shell Library
Windows 7提供了SHCreateLibrary API用來建立一個Shell Library:
C++ CreateShellLibrary
/**//*!
* Create a new shell library under the user's Libraries folder. If a library
* with the same name already exists, the new one overrides the existing one.
*
* \param pwszLibraryName
* The name of the shell library to be created.
*/
BOOL CreateShellLibrary(LPWSTR pwszLibraryName)
{
/**//////////////////////////////////////////////////////////////////////////
// Create the shell library COM object.
//
IShellLibrary* pShellLib = NULL;
HRESULT hr = SHCreateLibrary(IID_PPV_ARGS(&pShellLib));
if (FAILED(hr))
{
_tprintf(_T("SHCreateLibrary failed to create the shell library ") \
_T("COM object w/err 0x%08lx\n"), hr);
return FALSE;
}
/**/////////////////////////////////////////////////////////////////////////
// Save the new library under the user's Libraries folder.
//
IShellItem* pSavedTo = NULL;
hr = pShellLib->SaveInKnownFolder(FOLDERID_UsersLibraries,
pwszLibraryName, LSF_OVERRIDEEXISTING, &pSavedTo);
if (FAILED(hr))
{
_tprintf(_T("IShellLibrary::SaveInKnownFolder failed to save the ") \
_T("library w/err 0x%08lx\n"), hr);
return FALSE;
}
/**//////////////////////////////////////////////////////////////////////////
// Clean up.
//
if (pShellLib != NULL)
pShellLib->Release();
if (pSavedTo != NULL)
pSavedTo->Release();
return TRUE;
}
/**//////////////////////////////////////////////////////////////////////
// Create a shell library.
//
using (ShellLibrary library = new ShellLibrary(libraryName, true))
{
}
管理Windows Shell Library
你可以通過調用SHShowManageLibraryUI API顯示出Windows 標準的Shell Library管理對話方塊。值得注意的是,在調用SHShowManageLibraryUI前請確保 shell library沒有被以可寫方式開啟。否則在SHShowManageLibraryUI中對shell library的修改將無法被儲存。
C++ ShowManageLibraryUI
/**//*!
* Shows the library management dialog box of the specified library, which
* enables users to manage the library folders and default save location.
*
* \param pwszLibraryName
* The name of the shell library
*/
BOOL ShowManageLibraryUI(LPWSTR pwszLibraryName)
{
// Get the shell item that represents the library.
IShellItem2* pShellItem = GetShellLibraryItem(pwszLibraryName);
HRESULT hr = SHShowManageLibraryUI(pShellItem, NULL,
L"CppWin7ShellLibrary", L"Manage Library folders and settings",
LMD_ALLOWUNINDEXABLENETWORKLOCATIONS);
// Clean up
if (pShellItem != NULL)
pShellItem->Release();
return SUCCEEDED(hr);
}
C# ShowManageLibraryUI
// ShowManageLibraryUI requires that the library is not currently
// opened with write permission.
ShellLibrary.ShowManageLibraryUI(libraryName, IntPtr.Zero,
"CSWin7ShellLibrary", "Manage Library folders and settings", true);
向Shell Library中添加檔案夾
SHAddFolderPathToLibrary可用來向指定的Shell Library中添加檔案夾。
C++ AddFolderToShellLibrary
/**//*!
* Add a folder to an existing shell library.
*
* \param pShellLib
* The IShellLibrary interface of the shell library
*
* \param pwszFolderPath
* The path of the folder to be added into the shell library
*
* \param bSaveLocation
* If bSaveLocation is TRUE, set the folder as the save location of the shell
* library
*/
BOOL AddFolderToShellLibrary(IShellLibrary* pShellLib,
LPWSTR pwszFolderPath, BOOL bSaveLocation)
{
HRESULT hr = SHAddFolderPathToLibrary(pShellLib, pwszFolderPath);
if (FAILED(hr))
{
_tprintf(_T("SHAddFolderPathToLibrary failed to add a folder ") \
_T("to the shell library w/err 0x%08lx\n"), hr);
return FALSE;
}
// Save the folder as the save location of the shell library
if (bSaveLocation)
{
// Create shell item from folder path
IShellItem2* pShellItemSaveFolder = NULL;
hr = SHCreateItemFromParsingName(pwszFolderPath, 0,
IID_PPV_ARGS(&pShellItemSaveFolder));
if (FAILED(hr))
{
_tprintf(_T("SHCreateItemFromParsingName failed w/err ") \
_T("0x%08lx\n"), hr);
return FALSE;
}
// Set the folder as the save location
pShellLib->SetDefaultSaveFolder(DSFT_DETECT, pShellItemSaveFolder);
if (pShellItemSaveFolder != NULL)
pShellItemSaveFolder->Release();
if (FAILED(hr))
{
_tprintf(_T("IShellLibrary::SetDefaultSaveFolder failed ") \
_T("w/err 0x%08lx\n"), hr);
return FALSE;
}
}
// Commit the change of the shell library
pShellLib->Commit();
return TRUE;
}
C# AddFolderToShellLibrary
using (ShellLibrary library = ShellLibrary.Load(libraryName, false))
{
/**//////////////////////////////////////////////////////////////////
// Add a folder to the shell library.
//
// Add the folder to the shell library
library.Add(folderPath);
library.DefaultSaveFolder = folderPath;
}
枚舉Shell Library中的檔案夾
IShellLibrary::GetFolders可用來得到Shell Library中的檔案夾。
C++ ListFoldersInShellLibrary
/**//*!
* List all folders in the shell library.
*
* \param pShellLib
* The IShellLibrary interface of the shell library
*/
void ListFoldersInShellLibrary(IShellLibrary* pShellLib)
{
HRESULT hr = S_OK;
IShellItemArray* pShellItemArray = NULL;
pShellLib->GetFolders(LFF_ALLITEMS, IID_PPV_ARGS(&pShellItemArray));
if (FAILED(hr))
{
_tprintf(_T("IShellLibrary::GetFolders failed to get the folders ") \
_T("of the shell library w/err 0x%08lx\n"), hr);
return;
}
DWORD dwFolderCount;
pShellItemArray->GetCount(&dwFolderCount);
// Iterate through all folders of the shell library
for (DWORD i = 0; i < dwFolderCount; i++)
{
IShellItem *pShellItem;
hr = pShellItemArray->GetItemAt(i, &pShellItem);
if (FAILED(hr))
continue;
// Convert IShellItem to IShellItem2
IShellItem2 *pShellItem2;
pShellItem->QueryInterface(IID_PPV_ARGS(&pShellItem2));
pShellItem->Release();
// Fix folder path changes
IShellItem2 *pShellItemResolvedFolder = NULL;
hr = pShellLib->ResolveFolder(pShellItem2, 5000, IID_PPV_ARGS(
&pShellItemResolvedFolder));
if (SUCCEEDED(hr))
{
// Point to the fixed folder
pShellItem2->Release();
pShellItem2 = pShellItemResolvedFolder;
}
// Else we will show the unfixed folder
// Print the folder path
LPWSTR wszFolderPath;
hr = pShellItem2->GetString(PKEY_ParsingPath, &wszFolderPath);
if (SUCCEEDED(hr))
{
_putws(wszFolderPath);
}
CoTaskMemFree(wszFolderPath);
// Clean up
pShellItem2->Release();
}
pShellItemArray->Release();
}
C# ListFoldersInShellLibrary
using (ShellLibrary library = ShellLibrary.Load(libraryName, false))
{
/**//////////////////////////////////////////////////////////////////
// List all folders in the library.
//
foreach (ShellFolder folder in library)
{
Console.WriteLine(folder);
}
}
刪除一個Shell Library
C++ DeleteShellLibrary
/**//*!
* Delete the shell library under the user's Libraries folder according to the
* specified library name.
*
* \param pwszLibraryName
* The name of the shell library to be deleted.
*/
BOOL DeleteShellLibrary(LPWSTR pwszLibraryName)
{
/**//////////////////////////////////////////////////////////////////////////
// Get the shell item that represents the library and its full path.
//
IShellItem2* pShellItem = GetShellLibraryItem(pwszLibraryName);
// Get the file-system full path of the shell item
LPWSTR wszLibraryFullPath;
pShellItem->GetString(PKEY_ParsingPath, &wszLibraryFullPath);
/**//////////////////////////////////////////////////////////////////////////
// Delete file with the library file-system based full path.
//
BOOL bSuccess = DeleteFileW(wszLibraryFullPath);
// Clean up
CoTaskMemFree(wszLibraryFullPath);
if (pShellItem != NULL)
pShellItem->Release();
return bSuccess;
}
C# DeleteShellLibrary
/**//////////////////////////////////////////////////////////////////////
// Delete the shell library.
//
string librariesPath = Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData),
ShellLibrary.LibrariesKnownFolder.RelativePath);
string libraryPath = Path.Combine(librariesPath, libraryName);
string libraryFullPath = Path.ChangeExtension(libraryPath, "library-ms");
File.Delete(libraryFullPath);
更多關於Windows 7 Shell Library的操作請參見CppWin7ShellLibrary, CSWin7ShellLibrary和VBWin7ShellLibrary樣本。