訓練
啟動應用程式 (ShellExecute、ShellExecuteEx、SHELLEXECUTEINFO)
一旦您的應用程式找到檔案物件,下一個步驟通常是以某種方式處理它。 例如,您的應用程式可能會想要啟動另一個應用程式,讓使用者修改資料檔案。 如果感興趣的檔案是可執行檔,您的應用程式可能只想啟動它。 本檔討論如何使用 ShellExecute 或 ShellExecuteEx 來執行這些工作。
若要使用 ShellExecute 或 ShellExecuteEx,您的應用程式必須指定要執行的檔案或資料夾物件,以及指定要執行作業的 動詞 。 針對 ShellExecute,將這些值指派給適當的參數。 針對 ShellExecuteEx,填入 SHELLEXECUTEINFO 結構的適當成員。 另外還有數個可用來微調兩個函式行為的其他成員或參數。
檔案和資料夾物件可以是檔案系統或虛擬物件的一部分,而且可以透過路徑或專案識別碼清單的指標來識別 (PIDL) 。
物件可用的動詞基本上是您在物件快捷方式功能表上找到的專案。 若要尋找可用的動詞,請在登錄的 下方查看
\ HKEY_CLASSES_ROOTClsid\{object_clsid}\殼\動詞
其中 object_clsid 是 物件的 CLSID) (類別識別碼,而 動詞命令是可用動詞 的名稱。 verb\命令子機碼包含資料,指出叫用該動詞時會發生什麼事。
若要瞭解哪些動詞可供 預先定義的 Shell 物件使用,請在登錄的 下方查看
\ HKEY_CLASSES_ROOT\ object_name殼\動詞
其中 object_name 是預先定義的 Shell 物件名稱。 同樣地,動詞\命令子機碼包含資料,指出叫用該動詞時會發生什麼事。
常用的動詞包括:
動詞命令 | 描述 |
---|---|
編輯 | 啟動編輯器,並開啟檔以進行編輯。 |
尋找 | 起始從指定目錄開始的搜尋。 |
開啟 | 啟動應用程式。 如果這個檔案不是可執行檔,則會啟動其相關聯的應用程式。 |
列印檔案檔。 | |
properties | 顯示物件的屬性。 |
runas | 以系統管理員身分啟動應用程式。 使用者帳戶控制 (UAC) 會提示使用者同意提高許可權執行應用程式,或輸入用來執行應用程式的系統管理員帳號憑證。 |
每個動詞命令都會對應至用來從主控台視窗啟動應用程式的命令。 open動詞是不錯的範例,因為通常支援它。 針對.exe檔案, 開啟 只會啟動應用程式。 不過,它通常用來啟動在特定檔案上運作的應用程式。 例如,Microsoft WordPad 可以開啟.txt檔案。 .txt檔案的 開啟 動詞,因此會對應至類似下列命令的內容:
"C:\Program Files\Windows NT\Accessories\Wordpad.exe" "%1"
當您使用 ShellExecute 或 ShellExecuteEx 開啟.txt檔案時,Wordpad.exe會以指定的檔案作為其引數來啟動。 某些命令可以有額外的引數,例如旗標,可以視需要新增以正確啟動應用程式。 如需快顯功能表和動詞命令的進一步討論,請參閱 擴充快顯功能表。
一般而言,嘗試判斷特定檔案的可用動詞清單有點複雜。 在許多情況下,您可以直接將 lpVerb 參數設定為 Null,以叫用檔案類型的預設命令。 此程式通常相當於將 lpVerb 設定為 「open」,但某些檔案類型可能會有不同的預設命令。 如需詳細資訊,請參閱 擴充快顯功能表 和 ShellExecuteEx 參考檔。
網站鏈結的服務可以控制專案啟用的許多行為。 從Windows 8開始,您可以提供ShellExecuteEx的網站鏈結指標,以啟用這些行為。 若要將網站提供給 ShellExecuteEx:
- 在SHELLEXECUTEINFO的fMask成員中指定SEE_MASK_FLAG_HINST_IS_SITE旗標。
- 在SHELLEXECUTEINFO的hInstApp成員中提供IUnknown。
當使用者在 Windows 檔案總管中以滑鼠右鍵按一下資料夾圖示時,其中一個功能表項目是 「搜尋」。 如果選取該專案,Shell 會啟動其搜尋公用程式。 此公用程式會顯示對話方塊,可用來搜尋指定文字字串的檔案。 應用程式可以透過程式設計方式啟動目錄的搜尋公用程式,方法是呼叫 ShellExecute,並將 「find」 作為 lpVerb 參數,以及目錄路徑作為 lpFile 參數。 例如,下列程式程式碼會啟動 c:\MyPrograms 目錄的 Search 公用程式。
ShellExecute(hwnd, "find", "c:\\MyPrograms", NULL, NULL, 0);
下列範例主控台應用程式說明 如何使用 ShellExecuteEx。 為了清楚起見,省略大部分的錯誤檢查程式碼。
#include <shlobj.h>
#include <shlwapi.h>
#include <objbase.h>
main()
{
LPITEMIDLIST pidlWinFiles = NULL;
LPITEMIDLIST pidlItems = NULL;
IShellFolder *psfWinFiles = NULL;
IShellFolder *psfDeskTop = NULL;
LPENUMIDLIST ppenum = NULL;
STRRET strDispName;
TCHAR pszParseName[MAX_PATH];
ULONG celtFetched;
SHELLEXECUTEINFO ShExecInfo;
HRESULT hr;
BOOL fBitmap = FALSE;
hr = SHGetFolderLocation(NULL, CSIDL_WINDOWS, NULL, NULL, &pidlWinFiles);
hr = SHGetDesktopFolder(&psfDeskTop);
hr = psfDeskTop->BindToObject(pidlWinFiles, NULL, IID_IShellFolder, (LPVOID *) &psfWinFiles);
hr = psfDeskTop->Release();
hr = psfWinFiles->EnumObjects(NULL,SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &ppenum);
while( hr = ppenum->Next(1,&pidlItems, &celtFetched) == S_OK && (celtFetched) == 1)
{
psfWinFiles->GetDisplayNameOf(pidlItems, SHGDN_FORPARSING, &strDispName);
StrRetToBuf(&strDispName, pidlItems, pszParseName, MAX_PATH);
CoTaskMemFree(pidlItems);
if(StrCmpI(PathFindExtension(pszParseName), TEXT( ".bmp")) == 0)
{
fBitmap = TRUE;
break;
}
}
ppenum->Release();
if(fBitmap)
{
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = NULL;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile = pszParseName;
ShExecInfo.lpParameters = NULL;
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_MAXIMIZE;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
}
CoTaskMemFree(pidlWinFiles);
psfWinFiles->Release();
return 0;
}
應用程式會先擷取 Windows 目錄的 PIDL,並列舉其內容,直到找到第一個.bmp檔案為止。 不同于先前的範例, IShellFolder::GetDisplayNameOf 是用來擷取檔案的剖析名稱,而不是其顯示名稱。 因為這是檔系統資料夾,所以剖析名稱是完整的路徑,這是 ShellExecuteEx所需的路徑。
一旦找到第一個.bmp檔案,就會將適當的值指派給 SHELLEXECUTEINFO 結構的成員。 lpFile成員會設定為檔案的剖析名稱,並將lpVerb成員設定為Null,以開始預設作業。 在此情況下,預設作業為 「開啟」。 結構接著會傳遞至 ShellExecuteEx,這會啟動點陣圖檔案的預設處理常式,通常是MSPaint.exe開啟檔案。 函式傳回之後,會釋放 PIDL,並釋放 Windows 資料夾的 IShellFolder 介面。