Как запустить одну программу из другой?

Автор: Артур Вартанов

Версия текста: 1.0

Существует несколько способов запуска одной программы из другой.

  1. WinExec - устаревшая функция, используется только для совместимости с 16-битной Windows. Не рекомендуется к использованию в Win32-приложениях.

  2. CreateProcess - замена WinExec для Win32.

        BOOL CreateProcess(
          LPCTSTR lpApplicationName,
          LPTSTR lpCommandLine,
          LPSECURITY_ATTRIBUTES lpProcessAttributes,
          LPSECURITY_ATTRIBUTES lpThreadAttributes,
          BOOL bInheritHandles,
          DWORD dwCreationFlags,
          LPVOID lpEnvironment,
          LPCTSTR lpCurrentDirectory,
          LPSTARTUPINFO lpStartupInfo,
          LPPROCESS_INFORMATION lpProcessInformation
        );
    

    Параметры:

    lpApplicationName имя программы
    lpCommandLine параметры командной строки
    lpProcessAttributes атрибуты безопасности процесса (имеет смысл только в NT/2000)
    lpThreadAttributes атрибуты безопасности главного потока (имеет смысл только в NT/2000)
    bInheritHandles если bInheritHandles == TRUE, то созданный процесс (запущенная программа), наследует дескрипторы (handles) запускающей программы
    dwCreationFlags параметры создания. Здесь можно указать класс приоритета создаваемого процесса и некоторые дополнительные параметры
    lpEnvironment указатель на блок окружения или NULL, тогда используется блок окружения родителя
    lpCurrentDirectory текущая директория или NULL, тогда используется текущая директория родителя
    lpStartupInfo указатель на структуру STARTUPINFO, которая определяет положение главного окна
    lpProcessInformation сюда будет записана информация о созданном процессе

    Пример запуска notepad.exe.

    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    
    GetStartupInfo(&si);
    
    if(!CreateProcess(
        "c:\\windows\\notepad.exe",
        NULL,
        NULL,
        NULL,
        FALSE,
        0,
        NULL,
        NULL,
        &si,
        &pi)) {
        // обработка ошибок
    }
    

    Следует обратить внимание на то, что указан полный путь к файлу notepad.exe. CreateProcess не производит поиск файлов в путях, указанных в переменной PATH.

  3. ShellExecute и ShellExecuteEx - эти функции предназначены не только для запуска программ, но и для открытия и печати различных документов, т.е. запуска приложений, сопоставленных определенным типам файлов. Если, например, в качестве имени файла указать mydoc.doc, то будет запущено приложение, сопоставленное файлам с расширением doc (Microsoft Word). Функции ShellExecute и ShellExecuteEx в отличие от CreateProcess производят поиск файла в путях, указанных в переменной PATH.

    HINSTANCE ShellExecute(
        HWND hwnd, 
        LPCTSTR lpOperation,
        LPCTSTR lpFile, 
        LPCTSTR lpParameters, 
        LPCTSTR lpDirectory,
        INT nShowCmd
    );
    

    Эта функция возвращает значение >32 в случае успешного выполнения и значение <= 32 в случае ошибки.

    Параметры:

    hwnd дескриптор родительского окна
    lpOperation строка, описывающая операцию: "open" - открытие (запуск), "print" - печать, "explore" - открыть окно с заданной папкой
    lpFile имя файла
    lpParameters параметры командной строки
    lpDirectory текущая директория для запускаемой программы
    nShowCmd параметр, указывающий, как будет показано приложение при открытии. Имеет тот же смысл, что и nCmdShow в WinMain

    Пример запуска notepad.exe:

    if((UINT)ShellExecute(
        NULL,
        "open",
        "notepad.exe",
        NULL,
        NULL,
        SW_SHOWNORMAL) <= 32) {
        // обработка ошибок
    }
    

    Пример открытия файла doc1.doc.

    if((UINT)ShellExecute(
        NULL,
        "open",
        "doc1.doc",
        NULL,
        NULL,
        SW_SHOWNORMAL) <= 32) {
            // обработка ошибок
    }
    
    WINSHELLAPI BOOL WINAPI ShellExecuteEx(
        LPSHELLEXECUTEINFO lpExecInfo
    );
    

    Формат структуры SHELLEXECUTEINFO:

    typedef struct _SHELLEXECUTEINFO{
        DWORD cbSize;           // размер структуры
        ULONG fMask;            // маска, указывающая
        HWND hwnd; 
        LPCTSTR lpVerb;         // команда
        LPCTSTR lpFile;         // имя файла
        LPCTSTR lpParameters;   // параметры командной строки
        LPCTSTR lpDirectory;    // текущая директория
        int nShow;              // параметр, указывающий, как будет показано приложение при открытии.
        HINSTANCE hInstApp;     // сюда будет записан hInstance приложения
    
        // Optional members 
        LPVOID lpIDList;        // IDL, определяющий файл для выполнения
        LPCSTR lpClass;         // имя класса файла или GUID
        HKEY hkeyClass;         // дескриптор ключа в реестре для класса файла
        DWORD dwHotKey;         // горячая клавиша
        HANDLE hIcon;           // иконка для класса файла
        HANDLE hProcess;        // дескриптор процесса
    } SHELLEXECUTEINFO, FAR *LPSHELLEXECUTEINFO;
    

    Пример запуска notepad.exe:

    SHELLEXECUTEINFO SHExecInfo;
    ZeroMemory(&SHExecInfo, sizeof(SHExecInfo));
    
    SHExecInfo.cbSize = sizeof(SHExecInfo);
    SHExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
    SHExecInfo.nShow = SW_SHOWNORMAL;
    SHExecInfo.lpFile = "notepad.exe";
    
    if(!ShellExecuteEx(&SHExecInfo)) {
        // обработка ошибок
    }
    
  4. Функции, предоставляемые стандартной библиотекой языка программирования. Рассмотрение этих функций выходит за рамки данной статьи.


Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав.