2012-04-02 5 views
2

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

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

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

#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 отображался, так как у меня есть интерфейс GUI поверх него, и я хочу отобразить более приятный индикатор выполнения, а не видеть всплывающие окна для каждого файла I нужно разбирать.

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

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

Edit: В соответствии с просьбой в комментарии, код для 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 и не дает мне сообщение об ошибке.

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

+3

Пожалуйста, покажите код (используя «CreateProcess»), который не работает. – zwol

+0

«Это не решает мою проблему, потому что cmd появляется, и, протестировав его, я действительно заметил, что cmd даже не запускает .exe». Вы имеете в виду, что окно командной строки появляется, даже если 'CreateProcess' не порождает указанный .exe-файл? Если это так, похоже, ваш основной исполняемый файл скомпилирован как консольное приложение, а не оконное приложение. – jamesdlin

+0

@jamesdlin Я получаю пустое черное консольное окно, которое остается там из-за _getch() ;, но я вижу, что оно кажется пустым и исчезает, если я удаляю _getch() ;. Это может показаться глупым, но я не знаю, что вы подразумеваете под своим комментарием. Я использую Visual Studio 2010 и не знаю параметров компиляции, я всегда выбираю Create Empty Project (или создаю проект Qt4 для проектов с GUI). Если вы имели в виду, что мой компилятор не компилирует его так, как должен, не могли бы вы объяснить, как это сделать в противном случае? Я знаю, что это звучит noobish, но обычно я делаю небольшие консольные приложения или использую Qt с самодельным кодом. –

ответ

0

Использовать CreateProcess вместо системы.

--EDIT--

код для CreateProcess, что я попробовал, что я нашел на этом URL:

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

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

+3

Он сказал, что попробовал это. Пожалуйста, будьте более конкретными. – zwol

+3

@SigTerm: Если ваш ответ не расширяет знания OP, он «не полезен» и требует нисходящего хода. Бремя написания хорошего ответа заключается не в том, что люди оставляют комментарии ... – ildjarn

+0

@SigTerm Спасибо за попытку помочь, но, попробовав CreateProcess, используя код, который я редактировал в моем OP, у меня все еще есть та же проблема, и я видел, что ссылку раньше. Я пробовал некоторые примеры кодов, которые я мог найти в другом месте, так как я не полностью понимаю все параметры в этой ссылке, поэтому мне нужен пример или толчок в правильном направлении, чтобы я мог быть на правильном пути. По крайней мере, теперь я знаю, что CreateProcess - это правильный способ. –

0

После добавления следующих строк для 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() and CreateProcess()/CreateProcessW() для получения более подробной информации.

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

+1

Моя проблема решена с помощью инструкции RemyLebe в http://stackoverflow.com/questions/8649212/createprocess-and-command-line-arguments – dehiker

0

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