Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.61/18: Рейтинг темы: голосов - 18, средняя оценка - 4.61
 Аватар для ErikPshat
0 / 0 / 0
Регистрация: 26.08.2016
Сообщений: 76

Как из программы добавить переменные при вызове внешней программы через system?

03.03.2018, 07:29. Показов 3609. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В разрабатываемой программе имеются готовые переменные path и аргумент argv[1] возвращающий название файла.
Я хочу вызвать на исполнение внешнюю консольную утилиту на выполнение моих задач и чтобы сразу подставлять в командную строку нужные опции.
Внешняя утилита имеет следующий синтаксис и только в таком порядке:

PKG_Ripper.exe -o output_Folder -s extract_ICON PKG_File

Я решил сообразить такую конструкцию в конце кода:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Выделяем кусок памяти
  char buf[78];
 
  i = 0;
  memset (buf, 0, sizeof(buf));
 
//Формируем начало строки
  strcpy (buf, "PKG_Ripper -o ");
 
//Прикрепляем в продолжение переменную 'path', что означает - output_Folder
  strcat (buf, path);
 
//Далее продолжаем командой извлечения иконки - extract_ICON
  strcat (buf, " -s ICON0.PNG ");
 
//И травим в конце строки переменную названия файла - PKG_File
  strcat (buf, argv[1]);
 
//Собираем все команды на исполнение внешней программы
  system(buf);
Эмм, немного не понимаю, но командная строка не отрабатывает, а выдаёт ошибку:
Windows Batch file
1
2
"PKG_Ripper" не является внутренней или внешней
командой, исполняемой программой или пакетным файлом.
Где я мог допустить ошибку? Или может есть более простой метод?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
03.03.2018, 07:29
Ответы с готовыми решениями:

При вызове внешней программы остальное не работает
Есть такой кусочек кода: if volts < previous_voltage: command=os.system("sudo shutdown -h now") ...

Выполнение внешней программы (exec, system)
Доброго времени суток. Безуспешно пытаюсь выполнить внешнюю программу из php, хотя при этом если выполнить "echo x" то...

Исключение System.NullReferenceException при вызове через Android.Net.Sip
Приветствую. ВОзникла небольшая проблема. Пишу программу для совершения вызовов через SIP.Вот код using System; using Android.App; ...

13
 Аватар для ErikPshat
0 / 0 / 0
Регистрация: 26.08.2016
Сообщений: 76
03.03.2018, 08:05  [ТС]
Кстати, я заметил, что, если убрать все пробелы в кавычках, то в командную строку выстраивается весь скрипт с замещёнными переменными, но без пробелов. А без пробелов прога не выполняется. Каким образом можно подменить пробелы?
Вложения
Тип файла: zip PKG_Ripper.zip (29.4 Кб, 8 просмотров)
0
Модератор
Эксперт С++
 Аватар для zss
13771 / 10964 / 6491
Регистрация: 18.12.2011
Сообщений: 29,241
03.03.2018, 08:27
1.Значит, у Вас либо нет PKG_Ripper.exe
либо он находится неизвестно где.

2. Пробелы убирать не надо
0
 Аватар для ErikPshat
0 / 0 / 0
Регистрация: 26.08.2016
Сообщений: 76
03.03.2018, 09:38  [ТС]
zss, да нет, проверил 100 раз, всё лежит в одной папке, и сама компилируемая программа, и эта утилита PKG_Ripper.exe и тестовый PKG и консоль запущена в этой папке. Тут же я прогу правлю, тут же её компилирую, тут же её проверяю.

Если убрать все пробелы в кавычках, то командная строка выводится полностью верно, но конечно без пробелов. А если я обратно ставлю пробелы, то появляется только название программы, причём без пробела с сообщением: "PKG_Ripper" не является внутренней или внешней командой, исполняемой программой или пакетным файлом.

Если бы у меня что-то не там лежало, тогда бы и командная строка без пробелов не выводилась бы в таком виде:
C++
1
2
3
$ pdb_gen demo.pkg
Created pkg directory 80000053
"PKG_Ripper-o80000053-sICON0.PNGdemo.pkg"
Я где-то щас нагуглил, что при добавлении переменных в командную строку, нужно экранировать пробелы. Только что-то не экранируются они никак

Добавлено через 41 минуту
Хотя моя прога на чистом Си. Может в этом всё дело?
0
2734 / 888 / 331
Регистрация: 10.02.2018
Сообщений: 2,100
03.03.2018, 09:43
В Visual Studio, про другие среды не скажу, если программа запускается из самой среды, то рабочий каталог отличается от места расположения исполняемого файла. Если вторая программа лежит в одном каталоге с первой, то как раз будет подобная ошибка. Можно для теста запустить программу ручками из проводника.
1
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
03.03.2018, 09:43
Полный путь к PKG_Ripper укажи.
1
 Аватар для Avaddon74
571 / 353 / 133
Регистрация: 15.09.2017
Сообщений: 1,239
03.03.2018, 09:47
Лучший ответ Сообщение было отмечено ErikPshat как решение

Решение

ErikPshat, 1. Лучше указывать явно расширение файла
2. Какой путь используете относительный или полный?
Если относительный, то исполнение программы во время компиляции использует один рабочий каталог, а прямой запуск программы из того же каталога уже будет другой рабочий каталог
3. Виндовый интерпретатор не будет выводить всю строку если в первой же команде (до пробела) обнаружена ошибка

Цитата Сообщение от ErikPshat Посмотреть сообщение
"PKG_Ripper" не является внутренней или внешней командой, исполняемой программой или пакетным файлом.
Это ошибка возникает если не найден файл или он действительно не исполняемый

Попробуйте вывести на экран всю строку которая у вас формируется и ручка прописать её в интерпретатор
1
 Аватар для ErikPshat
0 / 0 / 0
Регистрация: 26.08.2016
Сообщений: 76
03.03.2018, 10:06  [ТС]
Цитата Сообщение от Avaddon74 Посмотреть сообщение
Это ошибка возникает если не найден файл или он действительно не исполняемый
А как же тогда выводится вот это у меня, когда без пробелов?
C++
1
2
3
$ pdb_gen demo.pkg
Created pkg directory 80000053
"PKG_Ripper-o80000053-sICON0.PNGdemo.pkg"
Я всё делаю в одном открытом окне консоли MinGW (почти аналог консоли Windows).
То есть, я всё прописываю в исходник. Потом компилирую программу с Makefile через консоль командой make.
Затем тут же через консоль на готовую программу pdb_gen.exe натравливаю demo.pkg.
И сама программа дальше выполняет работу, т.е. сама создаёт папку 80000053 и вызывает системный вызов на PKG_Ripper, ну и вы видите в коде выше что она пишет без пробелов. А вот если есть пробелы, то ошибка.

Я же с пробелами пользуюсь той же консолью (не закрываю её никогда), натравливаю тот же demo.pkg. Почему же тогда без пробелов прога находит и PKG_Ripper и demo.pkg, а с пробелами как будто не находит?
0
 Аватар для Avaddon74
571 / 353 / 133
Регистрация: 15.09.2017
Сообщений: 1,239
03.03.2018, 10:13
ErikPshat, Вы пытаетесь нам рассказать все ваши 100500 манипуляций, зачем? нам они ни к чему.
я же вам написал:
Цитата Сообщение от Avaddon74 Посмотреть сообщение
1. Лучше указывать явно расширение файла
Добавлено через 48 секунд
если не поможет, тогда использовать полный путь
1
 Аватар для ErikPshat
0 / 0 / 0
Регистрация: 26.08.2016
Сообщений: 76
03.03.2018, 10:52  [ТС]
Цитата Сообщение от Avaddon74 Посмотреть сообщение
если не поможет, тогда использовать полный путь
Расширение я итак указывал явно.
А вот полный путь действительно сработал. Только вот нужно полный путь не только для утилиты PKG_Ripper указывать, а и к файлу PKG так же, т.к. теперь ошибка, что не найден этот PKG ))).
Короче получается тупик, потому что утилиту я могу в %TEMP% по постоянному пути заранее скидывать. А вот файлы PKG у каждого юзера на компе могут находиться где угодно.

В общем system получается создаёт параллельную реальность и тут относительные пути уже не работают.

Добавлено через 11 минут
А как-то тогда можно по другому написать код, чтобы вызвать внешний файл без всяких system?
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
03.03.2018, 11:13
Ну а как ты хотел? Если путь заранее не известен, то надо указывать явно.
1
2734 / 888 / 331
Регистрация: 10.02.2018
Сообщений: 2,100
03.03.2018, 11:23
ErikPshat, можно программно получить текущую директорию (getcwd) и собрать полные пути из относительных.
1
 Аватар для ErikPshat
0 / 0 / 0
Регистрация: 26.08.2016
Сообщений: 76
05.03.2018, 20:07  [ТС]
Ygg, ага, спасибо. В общем извратился с такой конструкцией:
C++
1
2
3
4
5
6
7
8
9
10
// Здесь вставляю определение директории:
 
  pkg = fopen (argv[1], "rb");
  char dir[1024];
  getcwd(dir, 1024);
  if (pkg == NULL) {
    perror ("Failed to open .pkg file: ");
    return -2;
  }
// ...Далее идёт куча другого кода...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
//Здесь собираем командную строку с параметрами:
 
  i = 0;
  memset (buf, 0, sizeof(buf));
  strcpy (buf, "%TEMP%/BubbleMaker/utils/PKG_Ripper.exe -o ");
  strcat (buf, "%TEMP%/BubbleMaker/dev_hdd0/vsh/game_pkg/");
  strcat (buf, path);
  strcat (buf, " -s ICON0.PNG ");
  strcat (buf, dir);
  strcat (buf, "\\");
  strcat (buf, argv[1]);
  
  system(buf);
Ну в общем насколько мозгов хватило. Не хватило, как переименовать ICON0.PNG в FILE_ICON, т.к. именно такое название мне нужно на выходе. Желательно сразу это сделать, не выходя из функции, т.к. переменная path каждый раз изменяется.
0
2 / 2 / 1
Регистрация: 22.10.2012
Сообщений: 23
08.03.2018, 14:44
Лучший ответ Сообщение было отмечено ErikPshat как решение

Решение

Ygg,
getcwd отдаёт путь до первого параметра, по крайней мере для консольной утилиты с дрэг-н-дропом на неё pkg файла.

Вот такой вариант родился:
C
1
2
3
4
5
6
7
#include <stdlib.h>
 
char dir[_MAX_DIR];
char drive[_MAX_DRIVE];
memset(dir, 0, sizeof(dir));
memset(drive, 0, sizeof(drive));
_splitpath(argv[0], drive, dir, NULL, NULL);
А потом подкидываем в команду drive+dir, что при лежащем рядом pkg_ripper даёт полный путь и к нему тоже.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
08.03.2018, 14:44
Помогаю со студенческими работами здесь

Запуск из программы с админскими привилегиями внешней программы без прав админа
Нужно в программе которая запущенна под амином запустить другую программу без прав админа.

Как правильно задать глобальные переменные при старте программы?
Подскажите пожалуйста, как правильно задать глобальные переменные при старте программы. Что-бы работать с ними в обработчиках событий.

ShellExecute: задержка выполнения программы до отработки внешней программы
Вообщем, нужно запустить на исполнение gbak, приостановить программу на период его исполнения, и дождавшись окончания процесса продолжить. ...

Запуск внешней программы программы из коммнадной строки
Здравствуйте, есть программа D:\user\start.exe Как средствами excel vba вызвать командную строку и запустить программу из коммандной...

Сложности при вызове программы
В связке участвуют 2 программы (обе - мои) Одна на WinApi, другая на Qt. В какой из них возможно решение проблемы, я не знаю. Чтобы не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru