啟動應用程式 (ShellExecute、ShellExecuteEx、SHELLEXECUTEINFO)

一旦您的應用程式找到檔案物件,下一個步驟通常是以某種方式處理它。 例如,您的應用程式可能會想要啟動另一個應用程式,讓使用者修改資料檔案。 如果感興趣的檔案是可執行檔,您的應用程式可能只想啟動它。 本檔討論如何使用 ShellExecuteShellExecuteEx 來執行這些工作。

使用 ShellExecute 和 ShellExecuteExecuteEx

若要使用 ShellExecuteShellExecuteEx,您的應用程式必須指定要執行的檔案或資料夾物件,以及指定要執行作業的 動詞 。 針對 ShellExecute,將這些值指派給適當的參數。 針對 ShellExecuteEx,填入 SHELLEXECUTEINFO 結構的適當成員。 另外還有數個可用來微調兩個函式行為的其他成員或參數。

檔案和資料夾物件可以是檔案系統或虛擬物件的一部分,而且可以透過路徑或專案識別碼清單的指標來識別 (PIDL) 。

物件動詞

物件可用的動詞基本上是您在物件快捷方式功能表上找到的專案。 若要尋找可用的動詞,請在登錄的 下方查看

\ HKEY_CLASSES_ROOTClsid\{object_clsid}\\動詞

其中 object_clsid 是 物件的 CLSID) (類別識別碼,而 動詞命令是可用動詞 的名稱。 verb\命令子機碼包含資料,指出叫用該動詞時會發生什麼事。

若要瞭解哪些動詞可供 預先定義的 Shell 物件使用,請在登錄的 下方查看

\ HKEY_CLASSES_ROOT\ object_name\動詞

其中 object_name 是預先定義的 Shell 物件名稱。 同樣地,動詞\命令子機碼包含資料,指出叫用該動詞時會發生什麼事。

常用的動詞包括:

動詞命令 描述
編輯 啟動編輯器,並開啟檔以進行編輯。
尋找 起始從指定目錄開始的搜尋。
開啟 啟動應用程式。 如果這個檔案不是可執行檔,則會啟動其相關聯的應用程式。
print 列印檔案檔。
properties 顯示物件的屬性。
runas 以系統管理員身分啟動應用程式。 使用者帳戶控制 (UAC) 會提示使用者同意提高許可權執行應用程式,或輸入用來執行應用程式的系統管理員帳號憑證。

每個動詞命令都會對應至用來從主控台視窗啟動應用程式的命令。 open動詞是不錯的範例,因為通常支援它。 針對.exe檔案, 開啟 只會啟動應用程式。 不過,它通常用來啟動在特定檔案上運作的應用程式。 例如,Microsoft WordPad 可以開啟.txt檔案。 .txt檔案的 開啟 動詞,因此會對應至類似下列命令的內容:

"C:\Program Files\Windows NT\Accessories\Wordpad.exe" "%1"

當您使用 ShellExecuteShellExecuteEx 開啟.txt檔案時,Wordpad.exe會以指定的檔案作為其引數來啟動。 某些命令可以有額外的引數,例如旗標,可以視需要新增以正確啟動應用程式。 如需快顯功能表和動詞命令的進一步討論,請參閱 擴充快顯功能表

一般而言,嘗試判斷特定檔案的可用動詞清單有點複雜。 在許多情況下,您可以直接將 lpVerb 參數設定為 Null,以叫用檔案類型的預設命令。 此程式通常相當於將 lpVerb 設定為 「open」,但某些檔案類型可能會有不同的預設命令。 如需詳細資訊,請參閱 擴充快顯功能表ShellExecuteEx 參考檔。

使用 ShellExecuteEx 從網站提供啟用服務

網站鏈結的服務可以控制專案啟用的許多行為。 從Windows 8開始,您可以提供ShellExecuteEx的網站鏈結指標,以啟用這些行為。 若要將網站提供給 ShellExecuteEx

使用 ShellExecute 啟動搜尋對話方塊

當使用者在 Windows 檔案總管中以滑鼠右鍵按一下資料夾圖示時,其中一個功能表項目是 「搜尋」。 如果選取該專案,Shell 會啟動其搜尋公用程式。 此公用程式會顯示對話方塊,可用來搜尋指定文字字串的檔案。 應用程式可以透過程式設計方式啟動目錄的搜尋公用程式,方法是呼叫 ShellExecute,並將 「find」 作為 lpVerb 參數,以及目錄路徑作為 lpFile 參數。 例如,下列程式程式碼會啟動 c:\MyPrograms 目錄的 Search 公用程式。

ShellExecute(hwnd, "find", "c:\\MyPrograms", NULL, NULL, 0);

如何使用 ShellExecuteEx 的簡單範例

下列範例主控台應用程式說明 如何使用 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 介面。