Есть ли лучший способ выложить команду в C ++, чем system ()? - PullRequest
3 голосов
/ 31 октября 2010

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

Что еще хуже, я могу 'Кажется, я не получил никакой информации о том, почему system () не работает.Похоже, не возникло исключение, потому что я делаю улов (...) и ничего не ловится.Мой сервис просто перестает работать.Я знаю, что происходит сбой вызова system (), потому что я поместил информацию о регистрации до и после вызова, а что-то после просто ничего не записывает.

Итак, есть ли другой способЯ могу выложить свою команду?По крайней мере, что-то, что даст мне некоторую информацию, если что-то пойдет не так, или, по крайней мере, позволит мне обработать исключение или что-то в этом роде.

Ответы [ 5 ]

1 голос
/ 31 октября 2010

Я верю system() технически является частью стандартной библиотеки C и поэтому не будет генерировать исключения. Вы должны быть в состоянии проверить код возврата или переменную ERRNO, чтобы получить некоторую информацию о том, что произошло. Эта ссылка MSDN содержит некоторую информацию о возможных кодах возврата в Windows.

Я также видел сбой system() по другим внешним причинам, таким как антивирусные сканеры, так что вы также можете это исследовать.

Я не знаю лучшего способа запуска команд оболочки, но могу ошибаться.

РЕДАКТИРОВАТЬ: Если кажется, что по-прежнему происходит сбой без всякой причины, вы можете попробовать использовать Process Monitor , чтобы увидеть, что происходит на более низком уровне. Так как вывод из монитора процесса может быть довольно подавляющим, я бы хотел использовать хитрость, чтобы добавить выражение прямо перед вызовом system() в вашу программу, чтобы открыть несуществующий файл, такой как «C: \ MARKER.TXT» или что-то в этом роде. затем вы можете выполнить поиск в выходных данных монитора процессов по имени файла и сразу же просмотреть записи, которые могут иметь отношение к проблеме.

1 голос
/ 31 октября 2010

Обычный catch () не будет перехватывать фатальные исключения (например, ошибка сегментации). Вы должны использовать структурированную обработку исключений. Еще лучше включить посмертную отладку; В этой статье объясняется, как включить посмертную отладку служб.

0 голосов
/ 01 ноября 2010

В итоге я использовал CreateProcess. Пока это работает.

0 голосов
/ 31 октября 2010

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

Либо существует проблема среды (отсутствует запись в пути), либо учетная запись, которую использует служба для запуска, не имеет прав на выполнение того, что вы пытаетесь запустить.

Запустите services.msc и посмотрите свойства вашего сервиса. На странице входа в качестве теста измените настройку, чтобы она использовала вашу учетную запись для запуска службы. Если это удастся, вы знаете, в чем проблема.

Еще одна вещь, на которую нужно обратить внимание - это путь внутри службы. Используйте getenv ("PATH") и посмотрите, отсутствует ли путь, на который вы можете положиться.

Надеюсь, это поможет ...

0 голосов
/ 31 октября 2010

Вы можете использовать fork / exec, но я думаю, что это то, что делает система.

...