Iniciar aplicaciones (ShellExecute, ShellExecuteEx, SHELLEXECUTEINFO)

Una vez que la aplicación haya localizado un objeto de archivo, el siguiente paso suele ser actuar sobre él de alguna manera. Por ejemplo, es posible que la aplicación quiera iniciar otra aplicación que permita al usuario modificar un archivo de datos. Si el archivo de interés es un archivo ejecutable, es posible que la aplicación desee simplemente iniciarlo. En este documento se describe cómo usar ShellExecute o ShellExecuteEx para realizar estas tareas.

Uso de ShellExecute y ShellExecuteEx

Para usar ShellExecute o ShellExecuteEx, la aplicación debe especificar el objeto de archivo o carpeta en el que se va a actuar y un verbo que especifique la operación. Para ShellExecute, asigne estos valores a los parámetros adecuados. En ShellExecuteEx, rellene los miembros adecuados de una estructura SHELLEXECUTEINFO . También hay otros miembros o parámetros que se pueden usar para ajustar el comportamiento de las dos funciones.

Los objetos file y folder pueden formar parte del sistema de archivos o de los objetos virtuales, y se pueden identificar mediante rutas de acceso o punteros a listas de identificadores de elementos (PIDL).

Verbos de objeto

Los verbos disponibles para un objeto son básicamente los elementos que se encuentran en el menú contextual de un objeto. Para buscar qué verbos están disponibles, busque en el registro en .

HKEY_CLASSES_ROOT\CLSID\{object_clsid}\Cáscara\Verbo

donde object_clsid es el identificador de clase (CLSID) del objeto y el verbo es el nombre del verbo disponible. La subclavedel comandoverbo\ contiene los datos que indican lo que sucede cuando se invoca ese verbo.

Para averiguar qué verbos están disponibles para los objetos shell predefinidos, busque en el registro en .

HKEY_CLASSES_ROOT\Object_name\Cáscara\Verbo

donde object_name es el nombre del objeto Shell predefinido. De nuevo, la subclavedel comandoverbo\ contiene los datos que indican lo que sucede cuando se invoca ese verbo.

Los verbos disponibles con frecuencia incluyen:

Verbo Descripción
edición Inicia un editor y abre el documento para su edición.
find Inicia una búsqueda a partir del directorio especificado.
abrir Inicia una aplicación. Si este archivo no es un archivo ejecutable, se inicia su aplicación asociada.
imprimir Imprime el archivo de documento.
properties Muestra las propiedades del objeto.
runas Inicia una aplicación como administrador. El Control de cuentas de usuario (UAC) solicitará al usuario que dé su consentimiento para ejecutar la aplicación con privilegios elevados o escribirá las credenciales de una cuenta de administrador usada para ejecutar la aplicación.

Cada verbo corresponde al comando que se usaría para iniciar la aplicación desde una ventana de consola. El verbo abierto es un buen ejemplo, ya que normalmente se admite. Para .exe archivos, abra simplemente inicia la aplicación. Sin embargo, se usa con más frecuencia para iniciar una aplicación que funciona en un archivo determinado. Por ejemplo, Microsoft WordPad puede abrir .txt archivos. El verbo abierto de un archivo .txt correspondería por lo tanto a algo parecido al siguiente comando:

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

Cuando se usa ShellExecute o ShellExecuteEx para abrir un archivo .txt, se inicia Wordpad.exe con el archivo especificado como argumento. Algunos comandos pueden tener argumentos adicionales, como marcas, que se pueden agregar según sea necesario para iniciar la aplicación correctamente. Para obtener más información sobre los menús contextuales y los verbos, consulte Extensión de menús contextuales.

En general, intentar determinar la lista de verbos disponibles para un archivo determinado es algo complicado. En muchos casos, simplemente puede establecer el parámetro lpVerb en NULL, que invoca el comando predeterminado para el tipo de archivo. Este procedimiento suele ser equivalente a establecer lpVerb en "abierto", pero algunos tipos de archivo pueden tener un comando predeterminado diferente. Para obtener más información, consulte Extensión de menús contextuales y la documentación de referencia de ShellExecuteEx .

Uso de ShellExecuteEx para proporcionar servicios de activación desde un sitio

Los servicios de una cadena de sitio pueden controlar muchos comportamientos de activación de elementos. A partir de Windows 8, puede proporcionar un puntero a la cadena de sitio a ShellExecuteEx para habilitar estos comportamientos. Para proporcionar el sitio a ShellExecuteEx:

Usar ShellExecute para iniciar el cuadro de diálogo Buscar

Cuando un usuario hace clic con el botón derecho en un icono de carpeta en el Explorador de Windows, uno de los elementos de menú es "Buscar". Si seleccionan ese elemento, shell inicia su utilidad de búsqueda. Esta utilidad muestra un cuadro de diálogo que se puede usar para buscar archivos de una cadena de texto especificada. Una aplicación puede iniciar mediante programación la utilidad de búsqueda para un directorio mediante una llamada a ShellExecute, con "find" como el parámetro lpVerb y la ruta de acceso del directorio como el parámetro lpFile . Por ejemplo, la siguiente línea de código inicia la utilidad De búsqueda para el directorio c:\MyPrograms.

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

Un ejemplo sencillo de cómo usar ShellExecuteEx

La siguiente aplicación de consola de ejemplo muestra el uso de ShellExecuteEx. La mayoría del código de comprobación de errores se ha omitido para mayor claridad.

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

La aplicación recupera primero el PIDL del directorio de Windows y enumera su contenido hasta que encuentra el primer archivo .bmp. A diferencia del ejemplo anterior, IShellFolder::GetDisplayNameOf se usa para recuperar el nombre de análisis del archivo en lugar de su nombre para mostrar. Dado que se trata de una carpeta del sistema de archivos, el nombre del análisis es una ruta de acceso completa, que es lo que se necesita para ShellExecuteEx.

Una vez que se encuentra el primer archivo .bmp, los valores adecuados se asignan a los miembros de una estructura SHELLEXECUTEINFO . El miembro lpFile se establece en el nombre de análisis del archivo y el miembro lpVerb en NULL para comenzar la operación predeterminada. En este caso, la operación predeterminada es "abierta". A continuación, la estructura se pasa a ShellExecuteEx, que inicia el controlador predeterminado para los archivos de mapa de bits, normalmente MSPaint.exe, para abrir el archivo. Una vez que la función vuelve, se liberan las PIDL y se libera la interfaz IShellFolder de la carpeta Windows.