#c #exception #boost #command-line
#c #исключение #повышение #командная строка
Вопрос:
Я использую boost для выполнения команд командной строки из моего приложения. Я использую следующий фрагмент кода, который я инкапсулировал во вспомогательную функцию:
tuple<string, int> Utility::RunCommand(const stringamp; arguments) const
{
string response;
int exitCode;
try
{
ipstream iStream;
auto childProcess = child(arguments, std_out > iStream);
string line;
while (getline(iStream, line) amp;amp; !line.empty())
{
response = line;
}
childProcess.wait();
exitCode = childProcess.exit_code();
}
catch (...)
{
// log error
throw;
}
return make_tuple(response, exitCode);
}
Теперь у меня есть команда, которая выполняется только на машинах с определенными свойствами. Этот метод возвращает ожидаемый ответ и код ошибки на этих машинах. На других машинах он выдает исключение.
Я попытался запустить команду вручную на компьютере, где она должна завершиться с ошибкой, и она возвращает следующий вывод:
POWERSHELL
PS C:Usersxyz> dummy-cmd
dummy-cmd : The term 'dummy-cmd' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
dummy-cmd
~~~~~~~~~~
CategoryInfo : ObjectNotFound: (dummy-cmd:String) [], CommandNotFoundException
FullyQualifiedErrorId : CommandNotFoundException
COMMAND PROMPT
C:Usersxyz>dummy-cmd
'dummy-cmd' is not recognized as an internal or external command,
operable program or batch file.
Как я могу заставить его работать так, чтобы он возвращал ненулевой код ошибки, а не создавал исключение?
Комментарии:
1. Проблема в том, что ваш исполняемый файл не существует. Это то, на что жалуется Powershell.
2. Вы компилируете свой код, чтобы получить a
dummy-cmd.exe
?3. @doron Верно, я знаю об этой части. Мне интересно, есть ли способ вызвать команду, чтобы она возвращала код ошибки вместо исключения?
4. @FredLarson Нет. dummy-cmd.exe существует на одних машинах и отсутствует на других.
Ответ №1:
Это то, для чего предназначено ваше catch
предложение, для обработки исключений. Ему не нужно их повторно перетаскивать:
tuple<string, int> Utility::RunCommand(const stringamp; arguments) const
{
string response;
int exitCode;
try
{
ipstream iStream;
auto childProcess = child(arguments, std_out > iStream);
string line;
while (getline(iStream, line) amp;amp; !line.empty())
{
response = line;
}
childProcess.wait();
exitCode = childProcess.exit_code();
}
catch (PlatformNotSupportedExceptionamp; e)
{
std::cerr << "That operation is not supported on this platform." << std::endl;
exit(1);
}
catch (...)
{
std::cerr << "Unspecified error occurred." << std::endl;
exit(1); // give nonzero exit code
//throw; // take out this
}
return make_tuple(response, exitCode);
}
Комментарии:
1. Я могу это сделать. Но есть ли способ избежать попадания в catch? В основном способ выполнения команды таким образом, чтобы она возвращалась из метода. Кроме того, exit(1) выходит из приложения? Я хотел бы вернуться к вызывающей стороне.
2. @commandocaddy Итак, подождите, вы хотите, чтобы исключение было выдано и перехвачено этим методом, который затем возвращается? Или вы вообще не хотите никаких исключений?
3. В идеале никаких исключений вообще. Потому что на огромном количестве машин не будет этого исполняемого файла. Я бы хотел предотвратить обработку исключений, поскольку это может быть дорого.
4. @commandocaddy Тогда почему бы не изменить свой метод, чтобы не генерировать исключение, а вместо этого просто выдать соответствующий код выхода? Тогда вам не понадобится обработка исключений.