Альтернатива system () и _popen () в Windows - PullRequest
2 голосов
/ 11 февраля 2009

Это связано с: Как прочитать результаты системного вызова () в C ++?

Я пытаюсь сделать то же самое, только что моей программе нужно передать команду «несколько параметров с пробелами». Мне нужен вывод командной строки и код выхода из процесса.

Пример: пример с Textpad. Приложение, которое я действительно использую, печатает на stdout.

<code>
string command1 = "\"C:\Program Files\TextPad 5\Textpad.exe\" C:\readme0.txt";
string command2 = "\"C:\Program Files\TextPad 5\Textpad.exe\" \"C:\read me2.txt\"";
cout << system(command1.c_str()) << endl;
cout << system(command1.c_str()) << endl;

Выход:

0 «C: \ Program» не распознается как внутренняя или внешняя команда, работающая программа или командный файл.

1

Первый вызов системы проходит, а второй не удается с указанной выше ошибкой. _popen в Windows работает аналогично в Windows, так что тут никакой помощи. Я легко могу сделать это в Linux, так как могу использовать пробелы в параметрах без использования кавычек.

Альтернативой является написание огромного количества непросплатформенного кода, как указано здесь: http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx

Но если я хочу этого избежать, есть ли альтернативы system () и _popen () в Windows?

Спасибо!

Ответы [ 6 ]

2 голосов
/ 22 августа 2013

Функцией Windows API самого низкого уровня, используемой _popen () и system (), является CreateProcess ().

Однако CreateProcess () не так прост в использовании - особенно когда вы хотите получить выходные данные процесса или записать его во входные данные процесса.

CreateProcess () определенно будет работать с именами файлов, которые содержат пробелы (если они написаны в кавычках так, как вы это сделали).

0 голосов
/ 01 июня 2011

Куча утилитарных библиотек взяла этот кусок непереносимого кода и упаковала его в переносимый интерфейс. Для примера смотрите Qtcess Qt.

0 голосов
/ 09 января 2010

Я делаю это (обратите внимание - это код VB.NET), поэтому я могу записать вывод команды в мой файл журнала (он заключен в метод RunCommand()):

 Try
    Dim myprocess As New Process()
    myprocess.StartInfo.FileName = "C:\Program Files\TextPad 5\Textpad.exe"
    myprocess.StartInfo.RedirectStandardOutput = True
    myprocess.StartInfo.UseShellExecute = False

    ' inArgs are the arguments on the command line to the program
    myprocess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
    myprocess.StartInfo.Arguments = "C:\readme0.txt"

    ' the dir to set as default when the program runs
    Then myprocess.StartInfo.WorkingDirectory = "C:\Program Files\TextPad 5\"

    myprocess.Start()

    ' grab a reader to the standard output of the program
    procReader = myprocess.StandardOutput()

    ' read all the output from the process
    While (Not procReader.EndOfStream)
       procLine = procReader.ReadLine()

       ' write the output to my log
       writeNotes(procLine)
    End While

    procReader.Close()

 Catch ex As Exception
    ' Write the error to my log
    writeErrors("Couldn't execute command "C:\Program Files\TextPad 5\Textpad.exe", ex)
 End Try
0 голосов
/ 11 февраля 2009

Никогда не используйте system () в Windows! Просто перенаправьте дескрипторы ввода / вывода.

0 голосов
/ 11 февраля 2009

Следующее решает пробелы в задаче пути. Поймать вывод команды намного сложнее, однако:

#include <string>
#include <cstdlib>
using namespace std;

int main() {
    string cmd = "\"c:\\program files\\notepad++\\notepad++.exe\"";
    system( cmd.c_str() );
    return 0;
}
0 голосов
/ 11 февраля 2009

Я думаю ShellExecute () - это то, что вы ищете.

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