Iniciando aplicativos (ShellExecute, ShellExecuteEx, SHELLEXECUTEINFO)

Depois que o aplicativo localizar um objeto de arquivo, a próxima etapa geralmente será agir sobre ele de alguma forma. Por exemplo, seu aplicativo pode querer iniciar outro aplicativo que permita que o usuário modifique um arquivo de dados. Se o arquivo de interesse for um executável, talvez seu aplicativo queira simplesmente iniciá-lo. Este documento discute como usar ShellExecute ou ShellExecuteEx para executar essas tarefas.

Usando ShellExecute e ShellExecuteEx

Para usar ShellExecute ou ShellExecuteEx, seu aplicativo deve especificar o objeto de arquivo ou pasta no qual deve ser agido e um verbo que especifica a operação. Para ShellExecute, atribua esses valores aos parâmetros apropriados. Para ShellExecuteEx, preencha os membros apropriados de uma estrutura SHELLEXECUTEINFO . Também há vários outros membros ou parâmetros que podem ser usados para ajustar o comportamento das duas funções.

Objetos de arquivo e pasta podem fazer parte do sistema de arquivos ou objetos virtuais e podem ser identificados por caminhos ou ponteiros para PIDLs (listas de identificadores de item).

Verbos de objeto

Os verbos disponíveis para um objeto são essencialmente os itens que você encontra no menu de atalho de um objeto. Para localizar quais verbos estão disponíveis, procure no Registro em

HKEY_CLASSES_ROOT\CLSID\{object_clsid}\Shell\Verbo

em que object_clsid é o CLSID (identificador de classe) do objeto e verbo é o nome do verbo disponível. Asubchave do comandoverbo\ contém os dados que indicam o que acontece quando esse verbo é invocado.

Para descobrir quais verbos estão disponíveis para objetos Shell predefinidos, procure no Registro em

HKEY_CLASSES_ROOT\Object_name\Shell\Verbo

em que object_name é o nome do objeto Shell predefinido. Novamente, a subchave decomando do verbo\ contém os dados que indicam o que acontece quando esse verbo é invocado.

Os verbos comumente disponíveis incluem:

Verbo Descrição
editar Inicia um editor e abre o documento para edição.
localizar Inicia uma pesquisa a partir do diretório especificado.
Abrir Inicia um aplicativo. Se esse arquivo não for um arquivo executável, seu aplicativo associado será iniciado.
print Imprime o arquivo de documento.
properties Exibe as propriedades do objeto.
runas Inicia um aplicativo como Administrador. O UAC (Controle de Conta de Usuário) solicitará ao usuário consentimento para executar o aplicativo com privilégios elevados ou inserir as credenciais de uma conta de administrador usada para executar o aplicativo.

Cada verbo corresponde ao comando que seria usado para iniciar o aplicativo de uma janela do console. O verbo aberto é um bom exemplo, pois geralmente tem suporte. Para arquivos .exe, abrir simplesmente inicia o aplicativo. No entanto, é mais comumente usado para iniciar um aplicativo que opera em um arquivo específico. Por exemplo, .txt arquivos podem ser abertos pelo Microsoft WordPad. O verbo aberto para um arquivo .txt corresponderia, portanto, a algo semelhante ao seguinte comando:

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

Quando você usa ShellExecute ou ShellExecuteEx para abrir um arquivo .txt, Wordpad.exe é iniciado com o arquivo especificado como seu argumento. Alguns comandos podem ter argumentos adicionais, como sinalizadores, que podem ser adicionados conforme necessário para iniciar o aplicativo corretamente. Para obter mais discussões sobre menus de atalho e verbos, consulte Estendendo menus de atalho.

Em geral, tentar determinar a lista de verbos disponíveis para um arquivo específico é um pouco complicado. Em muitos casos, você pode simplesmente definir o parâmetro lpVerb como NULL, que invoca o comando padrão para o tipo de arquivo. Esse procedimento geralmente é equivalente a definir lpVerb como "open", mas alguns tipos de arquivo podem ter um comando padrão diferente. Para obter mais informações, consulte Estendendo menus de atalho e a documentação de referência shellExecuteEx .

Usando ShellExecuteEx para fornecer serviços de ativação de um site

Os serviços de uma cadeia de sites podem controlar muitos comportamentos de ativação de item. A partir de Windows 8, você pode fornecer um ponteiro para a cadeia de sites para ShellExecuteEx para habilitar esses comportamentos. Para fornecer o site para ShellExecuteEx:

Usando ShellExecute para iniciar a caixa de diálogo Pesquisar

Quando um usuário clica com o botão direito do mouse em um ícone de pasta no Windows Explorer, um dos itens de menu é "Pesquisar". Se eles selecionarem esse item, o Shell iniciará seu utilitário De pesquisa. Esse utilitário exibe uma caixa de diálogo que pode ser usada para pesquisar arquivos em busca de uma cadeia de caracteres de texto especificada. Um aplicativo pode iniciar programaticamente o utilitário Search para um diretório chamando ShellExecute, com "find" como o parâmetro lpVerb e o caminho do diretório como o parâmetro lpFile . Por exemplo, a linha de código a seguir inicia o utilitário Search para o diretório c:\MyPrograms.

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

Um exemplo simples de como usar ShellExecuteEx

O aplicativo de console de exemplo a seguir ilustra o uso de ShellExecuteEx. A maioria dos códigos de verificação de erros foi omitida para maior clareza.

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

O aplicativo primeiro recupera o PIDL do diretório do Windows e enumera seu conteúdo até encontrar o primeiro arquivo .bmp. Ao contrário do exemplo anterior, IShellFolder::GetDisplayNameOf é usado para recuperar o nome de análise do arquivo em vez de seu nome de exibição. Como essa é uma pasta do sistema de arquivos, o nome da análise é um caminho totalmente qualificado, que é o necessário para ShellExecuteEx.

Depois que o primeiro arquivo .bmp for localizado, os valores apropriados serão atribuídos aos membros de uma estrutura SHELLEXECUTEINFO . O membro lpFile é definido como o nome de análise do arquivo e o membro lpVerb como NULL, para iniciar a operação padrão. Nesse caso, a operação padrão é "open". Em seguida, a estrutura é passada para ShellExecuteEx, que inicia o manipulador padrão para arquivos bitmap, normalmente MSPaint.exe, para abrir o arquivo. Depois que a função retorna, as PIDLs são liberadas e a interface IShellFolder da pasta do Windows é liberada.