Запуск приложений (ShellExecute, ShellExecuteEx, SHELLEXECUTEINFO)

После того как приложение найдет файловый объект, следующим шагом часто является выполнение действий с ним каким-то образом. Например, может потребоваться запустить другое приложение, позволяющее пользователю изменять файл данных. Если файл представляет собой исполняемый файл, приложение может просто запустить его. В этом документе описывается использование ShellExecute или ShellExecuteEx для выполнения этих задач.

Использование ShellExecute и ShellExecuteEx

Чтобы использовать ShellExecute или ShellExecuteEx, приложение должно указать файл или объект папки, с которыми будет выполняться действие, и команду , задающую операцию. Для ShellExecute назначьте эти значения соответствующим параметрам. Для ShellExecuteEx заполните соответствующие элементы структуры SHELLEXECUTEINFO . Существует также несколько других элементов или параметров, которые можно использовать для точной настройки поведения двух функций.

Объекты файлов и папок могут быть частью файловой системы или виртуальных объектов, и их можно определить по путям или указателям на списки идентификаторов элементов (PIDLs).

Команды объектов

Глаголы, доступные для объекта, по сути, являются элементами, которые можно найти в контекстном меню объекта. Чтобы узнать, какие глаголы доступны, просмотрите в реестре в разделе

\ HKEY_CLASSES_ROOT CLSID\{object_clsid}\Оболочки\Глагол

где object_clsid — идентификатор класса (CLSID) объекта, а глагол — имя доступной команды. Подразделкомандыverb\ содержит данные, указывающие, что происходит при вызове этой команды.

Чтобы узнать, какие команды доступны для предопределенных объектов оболочки, просмотрите в реестре в разделе

\ HKEY_CLASSES_ROOT \ object_name Оболочки\Глагол

где object_name — это имя предопределенного объекта оболочки. Опять же, подразделкомандыverb\ содержит данные, указывающие, что происходит при вызове этой команды.

К общедоступным командам относятся:

Команда Описание
изменение; Запускает редактор и открывает документ для редактирования.
поиск Инициирует поиск, начиная с указанного каталога.
open Запускает приложение. Если этот файл не является исполняемым, запускается связанное с ним приложение.
print Выводит файл документа.
properties Отображает свойства объекта .
запуск от имени Запускает приложение от имени администратора. Контроль учетных записей (UAC) запрашивает у пользователя согласие на запуск приложения с повышенными привилегиями или ввод учетных данных учетной записи администратора, используемой для запуска приложения.

Каждая команда соответствует команде, которая будет использоваться для запуска приложения из окна консоли. Команда open является хорошим примером, так как она обычно поддерживается. Для .exe файлов open просто запускает приложение. Однако чаще всего он используется для запуска приложения, которое работает с определенным файлом. Например, microsoft WordPad может открыть .txt файлы. Таким образом , команда open для файла .txt будет соответствовать следующей команде:

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

При использовании ShellExecute или ShellExecuteEx для открытия файла .txt запускается Wordpad.exe с указанным файлом в качестве аргумента. Некоторые команды могут иметь дополнительные аргументы, например флаги, которые можно добавить по мере необходимости для правильного запуска приложения. Дополнительные сведения о контекстных меню и командах см. в разделе Расширение контекстных меню.

Как правило, попытка определить список доступных глаголов для определенного файла несколько сложна. Во многих случаях можно просто задать для параметра lpVerbзначение NULL, которое вызывает команду по умолчанию для типа файла. Эта процедура обычно эквивалентна установке lpVerb значения "открыть", но для некоторых типов файлов может быть другая команда по умолчанию. Дополнительные сведения см. в разделах Расширение контекстных меню и Справочная документация по ShellExecuteEx .

Использование ShellExecuteEx для предоставления служб активации с сайта

Службы цепочки сайтов могут управлять многими поведениями активации элементов. С Windows 8 можно указать указатель на цепочку сайтов на ShellExecuteEx, чтобы обеспечить такое поведение. Чтобы предоставить сайт для ShellExecuteEx, выполните следующие действия.

Использование shellExecute для запуска диалогового окна поиска

Когда пользователь щелкает правой кнопкой мыши значок папки в Windows Обозреватель, одним из пунктов меню является "Поиск". При выборе этого элемента оболочка запускает служебную программу поиска. Эта служебная программа отображает диалоговое окно, которое можно использовать для поиска указанной текстовой строки в файлах. Приложение может программно запустить служебную программу поиска для каталога, вызвав ShellExecute с параметром "find" в качестве параметра lpVerb и путем к каталогу в качестве параметра lpFile . Например, следующая строка кода запускает служебную программу поиска для каталога c:\MyPrograms.

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;
}

Приложение сначала получает PIDL каталога Windows и перечисляет его содержимое, пока не найдет первый .bmp файл. В отличие от предыдущего примера, IShellFolder::GetDisplayNameOf используется для получения имени синтаксического анализа файла вместо отображаемого имени. Так как это папка файловой системы, для анализа используется полный путь, который необходим для ShellExecuteEx.

После поиска первого файла .bmp членам структуры SHELLEXECUTEINFO присваиваются соответствующие значения. Для элемента lpFile задано имя синтаксического анализа файла, а для элемента lpVerbзначение NULL, чтобы начать операцию по умолчанию. В этом случае по умолчанию используется операция "открыть". Затем структура передается в ShellExecuteEx, который запускает обработчик по умолчанию для файлов растровых изображений, обычно MSPaint.exe, чтобы открыть файл. После возврата функции пин-коды освобождаются, а интерфейс IShellFolder папки Windows освобождается.