Как вы запускаете внешние программы с параметрами без отображения окна cmd в Windows?

Я только что задал вопрос ранее сегодня, потому что хотел запустить исполняемый файл, который берет параметры из моего кода C++, и он не работал.

Теперь это работает, но у меня все еще есть проблемы, так как я думал, что иду правильным путем, но похоже, что то, чего я хочу достичь, не может быть сделано так, как я к этому подхожу...

Это мой исправленный код из моего другого вопроса:

#include <stdlib.h>
#include <conio.h>

int main (){
    system("\"\"C:\\Users\\Adam\\Desktop\\pdftotext\" -layout \"C:\\Users\\Adam\\Desktop\\week 4.pdf\"\"");
    _getch();
}

то есть я запускаю «pdftotext -layout myfile.pdf», как если бы я запускал его из окна CMD.

Дело в том, что я на самом деле не хочу, чтобы cmd отображался, так как у меня есть графический интерфейс поверх него, и я хочу отображать более приятный индикатор выполнения вместо того, чтобы видеть всплывающие окна для каждого файла, который мне нужно проанализировать.

Я огляделся и либо не понимаю, что читаю, так как я относительно новичок в C++, либо я просто не нашел то, что искал. Я обнаружил, что с помощью CreateProcess я должен быть в состоянии сделать это, но после копирования некоторого кода, который я нашел где-то еще, окно cmd все равно всплывает.

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

Изменить: Как и просили в комментарии, код для CreateProcess, который я пробовал, я нашел по этому URL-адресу:

http://www.goffconcepts.com/techarticles/development/cpp/createprocess.html

Что (с моими собственными параметрами, которые, я думаю, должны туда идти):

#include <windows.h>
#include <string>
#include <conio.h>

size_t ExecuteProcess(std::wstring FullPathToExe, std::wstring Parameters, size_t SecondsToWait)
{
    size_t iMyCounter = 0, iReturnVal = 0, iPos = 0;
    DWORD dwExitCode = 0;
    std::wstring sTempStr = L"";

    /* - NOTE - You should check here to see if the exe even exists */

    /* Add a space to the beginning of the Parameters */
    if (Parameters.size() != 0)
    {
        if (Parameters[0] != L' ')
        {
            Parameters.insert(0,L" ");
        }
    }

    /* The first parameter needs to be the exe itself */
    sTempStr = FullPathToExe;
    iPos = sTempStr.find_last_of(L"\\");
    sTempStr.erase(0, iPos +1);
    Parameters = sTempStr.append(Parameters);

     /* CreateProcessW can modify Parameters thus we allocate needed memory */
    wchar_t * pwszParam = new wchar_t[Parameters.size() + 1];
    if (pwszParam == 0)
    {
        return 1;
    }
    const wchar_t* pchrTemp = Parameters.c_str();
    wcscpy_s(pwszParam, Parameters.size() + 1, pchrTemp);

    /* CreateProcess API initialization */
    STARTUPINFOW siStartupInfo;
    PROCESS_INFORMATION piProcessInfo;
    memset(&siStartupInfo, 0, sizeof(siStartupInfo));
    memset(&piProcessInfo, 0, sizeof(piProcessInfo));
    siStartupInfo.cb = sizeof(siStartupInfo);

    if (CreateProcessW(const_cast<LPCWSTR>(FullPathToExe.c_str()),
                            pwszParam, 0, 0, false,
                            CREATE_DEFAULT_ERROR_MODE, 0, 0,
                            &siStartupInfo, &piProcessInfo) != false)
    {
         /* Watch the process. */
        dwExitCode = WaitForSingleObject(piProcessInfo.hProcess, (SecondsToWait * 1000));
    }
    else
    {
        /* CreateProcess failed */
        iReturnVal = GetLastError();
    }

    /* Free memory */
    delete[]pwszParam;
    pwszParam = 0;

    /* Release handles */
    CloseHandle(piProcessInfo.hProcess);
    CloseHandle(piProcessInfo.hThread);

    return iReturnVal;
} 

int main(void){
    ExecuteProcess(L"C:\\Users\\Adam\\Desktop\\pdftotext", L"-layout \"C:\\Users\\Adam\\Desktop\\week 4.pdf\"", 0);
    _getch();
}

Я немного ошеломлен, так как он использует некоторые вещи, которые я никогда раньше не использовал, но я думаю, что понимаю суть (ключевое слово: думать). Однако это не решает мою проблему, потому что появляется cmd, и, повторно протестировав его, я действительно заметил, что cmd даже не запускает .exe и не выдает мне сообщение об ошибке.

Я надеюсь, что этот фрагмент кода поможет... Я не хотел углубляться в это, так как казалось, что я даже не двигался в правильном направлении.


person Adam Smith    schedule 02.04.2012    source источник
comment
Покажите код (используя CreateProcess), который не работает.   -  person zwol    schedule 02.04.2012
comment
Однако это не решает мою проблему, потому что появляется cmd, и, повторно протестировав его, я действительно заметил, что cmd даже не запускает .exe. Вы имеете в виду, что окно командной строки появляется, даже если CreateProcess не создает указанный файл .exe? Если это так, то похоже, что ваш основной исполняемый файл скомпилирован как консольное приложение, а не как оконное.   -  person jamesdlin    schedule 02.04.2012
comment
@jamesdlin Я получаю пустое черное окно консоли, которое остается там из-за _getch();, но я вижу, что оно кажется пустым и исчезает, если я удаляю _getch();. Это может показаться глупым, но я действительно не понимаю, что вы имеете в виду под своим комментарием. Я использую Visual Studio 2010 и на самом деле не знаю параметров компиляции, я всегда выбираю «Создать пустой проект» (или создаю проект Qt4 для проектов с графическим интерфейсом). Если вы имели в виду, что мой компилятор не компилирует его так, как должен, не могли бы вы объяснить, как это сделать иначе? Я знаю, это звучит по-детски, но обычно я делаю небольшие консольные приложения или использую Qt с самодельным кодом.   -  person Adam Smith    schedule 02.04.2012
comment
Попробуйте добавить siStartupInfo.dwFlags = STARTF_USESHOWWINDOW; и siStartupInfo.wShowWindow = SW_HIDE; перед вызовом CreateProcess.   -  person Jesse Good    schedule 02.04.2012
comment
@Jesse Это не сработало, но, как упомянул Джеймсдлин, появившаяся командная строка может быть не связана с CreateProcess, поэтому я буду продолжать тестирование, пока не увижу, что она хотя бы вызывает .exe, и тогда я узнаю если он работает. Я опубликую еще один комментарий, чтобы сообщить вам, когда я смогу полностью протестировать его. Что касается jamesdlin, я не знаю, как остановить отображение командной строки по умолчанию (если только она не всегда отображается в режиме отладки)   -  person Adam Smith    schedule 02.04.2012
comment
@AdamSmith: Когда вы связываете свое приложение, обязательно используйте /SUBSYSTEM:WINDOWS, если вы не хотите, чтобы у него было окно консоли. Также см. stackoverflow.com/questions/2422430/   -  person jamesdlin    schedule 02.04.2012
comment
jamesdlin Спасибо, он больше ничего не отображает, мне просто нужно найти, что не так с кодом (вероятно, я просто неправильно понимаю, как я должен передавать параметры, я сначала поиграюсь с этим)   -  person Adam Smith    schedule 02.04.2012


Ответы (3)


Вместо этого используйте CreateProcess. системы.

--РЕДАКТИРОВАТЬ--

код для CreateProcess, который я пробовал, я нашел по этому URL-адресу:

Код беспорядок, я бы посоветовал избегать этого URL в будущем.

В конце статьи «CreateProcess» есть ссылка «Создание процессов", который содержит более простой пример, который легче читать. Используйте его в качестве отправной точки.

person SigTerm    schedule 02.04.2012
comment
@SigTerm: если ваш ответ не расширяет знания ОП, он бесполезен и требует отрицательного голоса. Бремя написания хорошего ответа лежит не на людях, оставляющих комментарии... - person ildjarn; 02.04.2012
comment
@SigTerm Спасибо за попытку помочь, но, попробовав CreateProcess с использованием кода, который я отредактировал в своем OP, у меня все еще есть та же проблема, и я видел эту ссылку раньше. Я попробовал несколько примеров кода, которые мог найти в другом месте, так как я не полностью понимаю все параметры в этой ссылке, поэтому мне нужен пример или толчок в правильном направлении, чтобы я мог быть на правильном пути. По крайней мере, теперь я знаю, что CreateProcess — правильный путь. - person Adam Smith; 02.04.2012
comment
@ildjarn: бремя... ба. Времени, которое вы потратили на написание комментария, было достаточно, чтобы написать лучший ответ. - person SigTerm; 02.04.2012
comment
@AdamSmith: я обновил ответ ссылкой на более чистый пример. В будущем вместо посещения случайных веб-сайтов я бы посоветовал начать с msdn или официальной документации. - person SigTerm; 02.04.2012
comment
@SigTerm: Согласен, но если бы вы не установили планку так низко, дело могло бы быть иначе. - person ildjarn; 02.04.2012
comment
@SigTerm Я буду иметь это в виду, но, как я уже сказал, я новичок в C ++ и не знал, что такое хорошие / плохие ресурсы, прежде чем вы упомянули их, поэтому я пошел на случайные веб-сайты, а затем пришел спросить здесь. Я, очевидно, вижу, что ссылка, которую вы разместили, намного лучше, чем та, которую я впервые использовал, и я благодарю вас за это. Я попробую свой код с примером по ссылке в вашем посте. Спасибо! - person Adam Smith; 02.04.2012
comment
@AdamSmith: не знал, что хорошего для информации о winapi - msdn (или google msdn functionName). Качество msdn немного ухудшилось за последние годы, но его по-прежнему поддерживает Microsoft (которая создала winapi), поэтому лучше всего начать с msdn. Для информации о C++ — cplusplus.com/reference. Для сторонних библиотек и наборов инструментов сначала проверьте веб-сайт библиотеки/набора инструментов. - person SigTerm; 02.04.2012

После добавления следующих строк для siStartupInfo окно cmd больше не будет появляться с моим собственным тестом *.exe.

siStartupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
siStartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
siStartupInfo.hStdOutput =  GetStdHandle(STD_OUTPUT_HANDLE);
siStartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
siStartupInfo.wShowWindow = SW_HIDE;

Но у меня другая проблема. Когда я пытаюсь запустить другой исполняемый файл, чья командная строка будет

TEST.exe <input-file> output-file

в окне cmd WaitForSingleObject() возвращает 258, а GetLastError() возвращает 1813 ("Указанный тип ресурса не может быть найден в файле изображения"). Дополнительные сведения см. в разделе system() и CreateProcess()/CreateProcessW().

Любые идеи будут высоко оценены!

person dehiker    schedule 02.04.2012
comment
Моя проблема решена с помощью инструкции RemyLebeau в stackoverflow.com/questions/ 8649212/ - person dehiker; 02.04.2012

Единственный способ, которым я нашел, как выполнить внешнюю программу, это: system("start C:\file path\ file"); Единственная проблема заключается в том, что в файле или каталоге не может быть пробелов.

person EmptyStatic    schedule 21.01.2014