Как вызвать внешнюю программу с параметрами?
-
20-08-2019 - |
Вопрос
Я хотел бы вызвать программу Windows в своем коде с параметрами, определенными в самом коде.
Я не собираюсь вызывать внешнюю функцию или метод, а реальный exe-файл или пакетный файл / скрипт в среде WinXP.
Предпочтительным языком был бы C или C ++, но если это проще сделать на любом другом языке, дайте мне знать (ASM, C #, Python и т.д.).
Решение
Когда вы вызываете CreateProcess(), System() и т.д., убедитесь, что вы заключили строки имени вашего файла в двойные кавычки (включая имя файла командной программы) на случай, если имя (ы) вашего файла и / или полный путь содержат пробелы, в противном случае части пути к имени файла будут проанализированы интерпретатором команд как отдельные аргументы.
system("\"d:some path\\program.exe\" \"d:\\other path\\file name.ext\"");
Для Windows рекомендуется использовать CreateProcess().У него более запутанная настройка, но у вас больше контроля над тем, как запускаются процессы (как описано Грегом Хьюджиллом).Для быстрого и грязного использования вы также можете использовать WinExec().(system() переносима в UNIX).
При запуске пакетных файлов вам может потребоваться запустить с помощью cmd.exe (или command.com).
WinExec("cmd \"d:some path\\program.bat\" \"d:\\other path\\file name.ext\"",SW_SHOW_MINIMIZED);
(или SW_SHOW_NORMAL
если вы хотите, чтобы отображалось командное окно ).
Windows должна найти command.com или cmd.exe в системном пути so in не обязательно указывать полное имя файла, но если вы хотите быть уверены, вы можете создать полное имя файла с помощью CSIDL_SYSTEM
(не используйте просто C:\Windows\system32\cmd.exe).
Другие советы
Пример C++:
char temp[512];
sprintf(temp, "command -%s -%s", parameter1, parameter2);
system((char *)temp);
Пример C #:
private static void RunCommandExample()
{
// Don't forget using System.Diagnostics
Process myProcess = new Process();
try
{
myProcess.StartInfo.FileName = "executabletorun.exe";
//Do not receive an event when the process exits.
myProcess.EnableRaisingEvents = false;
// Parameters
myProcess.StartInfo.Arguments = "/user testuser /otherparam ok";
// Modify the following to hide / show the window
myProcess.StartInfo.CreateNoWindow = false;
myProcess.StartInfo.UseShellExecute = true;
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
myProcess.Start();
}
catch (Exception e)
{
// Handle error here
}
}
Я думаю, что вы ищете Процесс создания функция в Windows API.На самом деле существует семейство связанных вызовов, но это поможет вам начать.Это довольно просто.
Один из самых простых способов сделать это - использовать system()
функция библиотеки времени выполнения.Он принимает одну строку в качестве параметра (намного меньше параметров, чем CreateProcess
!) и выполняет его так, как если бы оно было введено в командной строке. system()
также автоматически ожидает завершения процесса, прежде чем он вернется.
Существуют также ограничения:
- у вас меньше контроля над stdin и stdout запущенного процесса
- вы не можете делать что-либо еще, пока запущен другой процесс (например, принять решение о его завершении).
- вы не можете получить дескриптор другого процесса, чтобы каким-либо образом запросить его
Библиотека времени выполнения также предоставляет семейство exec*
функции (execl
, execlp
, execle
, execv
, execvp
, более или менее), которые являются производными от наследия Unix и предлагают больший контроль над процессом.
На самом низком уровне в Win32 все процессы запускаются CreateProcess
функция, которая дает вам наибольшую гибкость.
простой пример c ++ (найден после поиска на нескольких веб-сайтах)
#include <bits/stdc++.h>
#include <cassert>
#include <exception>
#include <iostream>
int main (const int argc, const char **argv) {
try {
assert (argc == 2);
const std::string filename = (const std::string) argv [1];
const std::string begin = "g++-7 " + filename;
const std::string end = " -Wall -Werror -Wfatal-errors -O3 -std=c++14 -o a.elf -L/usr/lib/x86_64-linux-gnu";
const std::string command = begin + end;
std::cout << "Compiling file using " << command << '\n';
assert (std::system ((const char *) command.c_str ()) == 0);
std::cout << "Running file a.elf" << '\n';
assert (std::system ((const char *) "./a.elf") == 0);
return 0; }
catch (std::exception const& e) { std::cerr << e.what () << '\n'; std::terminate (); }
catch (...) { std::cerr << "Found an unknown exception." << '\n'; std::terminate (); } }