3.編譯並測試結果:
a.清空命令行變量。
b.打開一個命令行窗口,並且將目錄(cd)改變到SLUtil.exe文件的所在位置(… \debug\SLUtil.exe)
c.打開緊鄰命令行窗口的庫Shell文件夾,你將會看到你使用SLUtil工具所做的變化。
d.在命令行中嘗試下面的SLUtil命令:
i.SLUtil ?
ii.SLUtil Create NewLibrary
iii.SLUtil AddFolder NewLibrary C:\Users
iv.SLUtil RemoveFolder NewLibrary C:\Users
注意 :
由於解釋器能夠找到最為匹配的命令,所以你可以使用“SLUtil Cr Lib”這種指令去創 建一個庫,或者使用“SLUtil Add Lib C:\”指令去添加一個文件夾。嘗試一下。
任務 4 –添加刪除和重命名命令
刪除和重命名一個庫,是刪除或重命名與其一致的*.library-ms文件的庫的一系列操作 。要刪除一個文件,我們可以使用SHFileOperation() 或 DeleteFile()。第一種方法可以 同時將庫放入回收站,而且後續的操作更加簡單,所以我們將使用這個方法。如果要對文件 進行重命名,我們可以再次使用基於文件系統的API,但是我們也可以使用拷貝庫的方式, 然後將原先的實例刪除掉。
1.向SLUtil.cpp文件中添加下面的代碼:
C++ (SLUtil.cpp)
//Delete a library
void Delete(const CCommand &command, const vector<PCWSTR> &arguments)
{
PWSTR libraryFullPath;
HRESULT hr = GetLibraryFromLibrariesFolder(arguments[0], NULL, false,
&libraryFullPath);
if (FAILED(hr))
{
wcerr << L"Delete: Can't get library." << endl;
exit(4);
}
//We use delete file with the library file-system based full path
DeleteFile(libraryFullPath);
CoTaskMemFree(libraryFullPath);
}
COMMAND(L"Delete", L"SLUtil Delete LibraryName", L"Delete a library", L"SLUtil Delete MyLib", 1, Delete);
//Rename an existing library
void Rename(const CCommand &command, const vector<PCWSTR> &arguments)
{
IShellLibrary *shellLibrary = OpenLibrary (L"Rename", arguments[0]);
IShellItem *savedTo = NULL;
//Save a new copy of the library under the user's Libraries folder with
//the new name.
HRESULT hr = shellLibrary- >SaveInKnownFolder(FOLDERID_UsersLibraries,
arguments[1], LSF_MAKEUNIQUENAME, &savedTo);
if (FAILED(hr))
{
wcerr << L"Rename: Can't save library." << endl;
exit(5);
}
if (shellLibrary != NULL)
shellLibrary ->Release();
if (savedTo != NULL)
savedTo- >Release();
//Create parameters to delete the old copy of the library
vector<PCWSTR> deleteArguments;
deleteArguments.push_back(arguments [0]);
//Call the delete command
Delete(command, deleteArguments);
}
COMMAND(L"Rename", L"SLUtil Rename OldName NewName", L"Rename a library", L"SLUtil Rename MyLib MyLibNewName", 2, Rename);
2.編譯並測試:
a.打開一個命令行窗口,並且將目錄(cd)切換到SLUtil.exe所在的位置。
b.打開緊鄰命令行窗口的庫Shell文件夾,你將會看到你使用SLUtil工具所做的變化。
c.在命令行中,測試SLUtil.exe rename mynewlibrary2 mynewlibrary4命令。
d.使用SLUtil.exe del MyLib來刪除庫。
e.如果你一不小心刪除了一個已經定義好的庫,你還可以恢復它:
任務 5 –添加存儲文件夾,NavPanePinnedState 和圖標命令
這三個命令共享公用行為。用戶只需要提供庫的名稱,就可以使用這些命令來查詢該庫 的狀態。
1.向SLUtil.cpp文件中添加下面的代碼:
a.SaveFolder --允許你查詢和設置當前的默認存儲文件夾。
那麼如果庫中的文件夾列表是空的,這個值也將是空的。庫中保存文件夾的信息,但這 些信息可能是陳舊過時的。比如,默認的存儲路徑,可能指向的是一個用戶已經重命名了的 文件夾。要解決這些問題,IshellLibrary提供了一個叫做ResolveFolder()的方法。
b.NavPanePinnedState --允許你查詢和設置庫的名稱是否能夠出現在浏覽器的導航欄中 。
我們通過設置庫的可選標志LOF_PINNEDTONAVPANE來實現這項功能,並且這個標志是當前 唯一可用的選項。
c.Icon --允許你查詢或設置圖標資源名稱;這個屬性可以為空。
C++ (SLUtil.cpp)
//Set or get the library's save folder path
void SaveFolder(const CCommand &command, const vector<PCWSTR> &arguments)
{
IShellLibrary *shellLibrary = NULL;
IShellItem2 *shellItemSaveFolder = NULL;
HRESULT hr = S_OK;
//Show current default save folder
if (arguments.size() == 1)
{
shellLibrary = OpenLibrary(L"SaveFolder", arguments[0]);
hr = shellLibrary->GetDefaultSaveFolder(DSFT_DETECT,
IID_PPV_ARGS(&shellItemSaveFolder));
if (FAILED (hr))
{
wcerr << L"SaveFolder: Can't extract default save folder."
<< endl;
exit(5);
}
IShellItem2 *shellItemResolvedSaveFolder = NULL;
//Fix folder path changes
hr = shellLibrary->ResolveFolder(shellItemSaveFolder, 5000,
IID_PPV_ARGS(&shellItemResolvedSaveFolder));
if (FAILED (hr))
{
wcerr << L"SaveFolder: Default save location Unavailable."
<< endl;
exit(6);
}
PWSTR defaultSaveFolder;
hr = shellItemResolvedSaveFolder->GetString(PKEY_ParsingPath,
&defaultSaveFolder);
wcout << L"Library " << arguments[0] << L" has folder " <<
defaultSaveFolder << L" as a default save location." << endl;
shellItemResolvedSaveFolder->Release();
CoTaskMemFree(defaultSaveFolder);
}
else //Set current default save folder
{
shellLibrary = OpenLibrary(L"SaveFolder", arguments[0], false);
//Create shell item from folder path
hr = SHCreateItemFromParsingName(arguments[1], 0,
IID_PPV_ARGS(&shellItemSaveFolder));
if (FAILED (hr))
{
wcerr << L"SaveFolder: Can't find folder: " <<
arguments[1] << endl;
exit(6);
}
shellLibrary ->SetDefaultSaveFolder(DSFT_DETECT,
shellItemSaveFolder);
if (FAILED (hr))
{
wcerr << L"SaveFolder: Can't set default save folder to"
<< arguments[1] << endl;
exit(7);
}
//Commit the library changes
shellLibrary ->Commit();
}
if (shellItemSaveFolder != NULL)
shellItemSaveFolder->Release();
if (shellLibrary != NULL)
shellLibrary->Release();
}
COMMAND(L"SaveFolder", L"SLUtil SaveFolder LibraryName [FolderPath]", L"Set or get the library's save folder path", L"SLUtil SaveFolder Documents C:\\Docs", 1, SaveFolder);
//compare strings for equality for the length of the shorter string
bool CompareStringShort(PCWSTR first, PCWSTR second)
{
int length = min(lstrlenW(first), lstrlenW(second));
return CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, first, length,
second, length) == CSTR_EQUAL;
}
//Set or get the library's pinned to navigation pane state
void NavPanePinnedState(const CCommand &command,
const vector<PCWSTR> &arguments)
{
IShellLibrary *shellLibrary = NULL;
HRESULT hr = S_OK;
//Show current pinned to navigation pane state
if (arguments.size() == 1)
{
//Open library with read permissions
IShellLibrary *shellLibrary = OpenLibrary(L"NavPanePinnedState",
arguments [0]);
LIBRARYOPTIONFLAGS optionFlags;
hr = shellLibrary->GetOptions(&optionFlags);
if (FAILED (hr))
{
wcerr << L"NavPanePinnedState: Can't get current pinned "
<< "to navigation pane state." << endl;
exit(5);
}
wcout << L"Library " << arguments[0] << L" is" <<
(((optionFlags & LOF_PINNEDTONAVPANE) != 0)
L" " : L" not ") << L"pinned to naveigation pane." << endl;
}
else //Set the current pinned to navigation pane state
{
//Open library with read/write permissions
IShellLibrary *shellLibrary =
OpenLibrary(L"NavPanePinnedState", arguments[0], false);
LIBRARYOPTIONFLAGS optionFlags = CompareStringShort(
arguments[1], L"TRUE") ? LOF_PINNEDTONAVPANE : LOF_DEFAULT;
hr = shellLibrary->SetOptions(LOF_MASK_ALL, optionFlags);
if (FAILED (hr))
{
wcerr << L"NavPanePinnedState: Can't set pinned to " <<
"navigation pane state." << endl;
exit(6);
}
//Commit the library changes
shellLibrary ->Commit();
}
if (shellLibrary != NULL)
shellLibrary ->Release();
}
COMMAND(L"NavPanePinnedState", L"SLUtil NavPanePinnedState LibraryName [TRUE|FALSE]", L"Set or get the library's Pinned to navigation pane state", L"SLUtil NavPanePinnedState MyLib TRUE", 1, NavPanePinnedState);
//Set or get the library's icon
void Icon(const CCommand &command, const vector<PCWSTR> &arguments)
{
IShellLibrary *shellLibrary = NULL;
HRESULT hr = S_OK;
//Show current icon resource name
if (arguments.size() == 1)
{
//Open library with read permissions
IShellLibrary *shellLibrary = OpenLibrary(L"Icon", arguments[0]);
PWSTR iconName;
hr = shellLibrary->GetIcon(&iconName);
if (FAILED (hr))
{
wcerr << L"Icon: Can't get icon resource name." << endl;
exit(5);
}
wcout << L"Library " << arguments[0] << L": Icon resource name: "
<< iconName << endl;
CoTaskMemFree(iconName);
}
else //Set the current icon resource name
{
//Open library with read/write permissions
IShellLibrary *shellLibrary =
OpenLibrary(L"Icon", arguments[0], false);
hr = shellLibrary->SetIcon(arguments[1]);
if (FAILED (hr))
{
wcerr << L"Icon: Can't set icon resource name." << endl;
exit(6);
}
//Commit the library changes
shellLibrary ->Commit();
}
if (shellLibrary != NULL)
shellLibrary ->Release();
}
COMMAND(L"Icon", L"SLUtil Icon LibraryName [Icon]", L"Set or get the library's icon", L"SLUtil Icon MyLib imageres.dll,-1005", 1, Icon);