How to call an external program with parameters? - c++

I would like to call a windows program within my code with parameters determined within the code itself.
I'm not looking to call an outside function or method, but an actual .exe or batch/script file within the WinXP environment.
C or C++ would be the preferred language but if this is more easily done in any other language let me know (ASM, C#, Python, etc).

When you call CreateProcess(), System(), etc., make sure you double quote your file name strings (including the command program filename) in case your file name(s) and/or the fully qualified path have spaces otherwise the parts of the file name path will be parsed by the command interpreter as separate arguments.
system("\"d:some path\\program.exe\" \"d:\\other path\\file name.ext\"");
For Windows it is recommended to use CreateProcess(). It has messier setup but you have more control on how the processes is launched (as described by Greg Hewgill). For quick and dirty you can also use WinExec().
(system() is portable to UNIX).
When launching batch files you may need to launch with cmd.exe (or command.com).
WinExec("cmd \"d:some path\\program.bat\" \"d:\\other path\\file name.ext\"",SW_SHOW_MINIMIZED);
(or SW_SHOW_NORMAL if you want the command window displayed ).
Windows should find command.com or cmd.exe in the system PATH so in shouldn't need to be fully qualified, but if you want to be certain you can compose the fully qualified filename using CSIDL_SYSTEM (don't simply use C:\Windows\system32\cmd.exe).

C++ example:
char temp[512];
sprintf(temp, "command -%s -%s", parameter1, parameter2);
system((char *)temp);
C# example:
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
}
}

I think you are looking for the CreateProcess function in the Windows API. There are actually a family of related calls but this will get you started. It is quite easy.

One of the simplest ways to do this is to use the system() runtime library function. It takes a single string as a parameter (many fewer parameters than CreateProcess!) and executes it as if it were typed on the command line. system() also automatically waits for the process to finish before it returns.
There are also limitations:
you have less control over the stdin and stdout of the launched process
you cannot do anything else while the other process is running (such as deciding to kill it)
you cannot get a handle to the other process in order to query it in any way
The runtime library also provides a family of exec* functions (execl, execlp, execle, execv, execvp, more or less) which are derived from Unix heritage and offer more control over the process.
At the lowest level, on Win32 all processes are launched by the CreateProcess function, which gives you the most flexibility.

simple c++ example (found after searching a few websites)
#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 (); } }

Related

Best way for C++ and Lua I/O interaction on stack

I was wondering the best way to interact with lua I/O in C++ code.
lua script:
while true do
local input = io.read("*line")
if input == "hello" then
print("world")
else
print("hmmm...")
end
end
C++ code:
lua_State* L = luaL_newstate();
luaL_openlibs(L);
int r = luaL_dofile(L, "foo.lua");
When I ran the C++ code, the foo.lua script I/O seems replacing the original I/O in C++. The another interesting thing is lua's function print seems to insert the value into the stack.(I can use lua_tostring(L, -1) to fetch the print message).
What I want to know is there any ways to interact with lua script more elegantly instead of covering my std I/O. Like, if I push the "hello" into the stack, it can gives me "world" back?
This is how I tend to write a C program that executes a Lua script using Lua's C API:
#include <stdio.h>
#include <stdlib.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#define MIN_ARGC 2
int main(int argc, char** argv) {
// Check to make sure a Lua file was passed to this program as a command-line
// argument.
if (argc < MIN_ARGC) {
fprintf(stderr, "Lua filename expected from command line\n");
exit(EXIT_FAILURE);
}
lua_State* L = luaL_newstate();
// NOTE: good idea to make sure the lua_State* initialized.
if (!L) {
fprintf(stderr, "Error initializing Lua\n");
exit(EXIT_FAILURE);
}
// Open standard Lua libraries--math, string, etc.
luaL_openlibs(L);
// At this point, I register any C functions for use in Lua using the macro
// lua_register.
// I usually create an int called fail; if an error occurs during the execution of
// the Lua script, fail is set to 1.
int fail = 0;
// Execute the Lua script passed to this program as argv[1]; and, in the event of
// an error, print it to stderr.
if ((fail = luaL_dofile(L, argv[1])))
fprintf(stderr, "%s\n", lua_tostring(L, -1));
// Make sure to close your lua_State*.
lua_close(L);
return (fail) ? EXIT_FAILURE : EXIT_SUCCESS;
}
Here is a trivial example of a C function that can be called from Lua. It returns an int and has one parameter, a lua_State*:
int lua_foo(lua_State* L) {
printf("foo\n");
return 0;
}
This is a lua_CFunction, and its return value refers to the number of values it will push on to the Lua stack. In the case of my trivial function lua_foo, it pushes nothing on to the stack, so it returns 0.
It could be registered with the macro lua_register as follows:
lua_register(L, "foo", lua_foo);
It could then be called from Lua, in a script executed by this program via luaL_dofile, as foo().
As for the example script that you provided in your question, there is no condition to break out of the while-loop. Try this instead:
while (true) do
local input = io.read("*l")
if (input == "hello") then
print("world")
-- Include a statement here to break out of the loop once the user has
-- input 'hello'.
break
else
print("hmm...")
end
end
Upon inputting "hello," the loop will break and the script should successfully exit; and the value of r in your C/C++ code will be set to 0, indicating normal script execution by luaL_dofile.
EDIT:
As far as the part of your question concerning Lua I/O and "elegant" interaction with C, you have to remember that Lua is implemented in ANSI C; which means that, at a lower level, Lua calls C functions. There is nothing wrong with calling Lua I/O functions, so long as you handle them correctly, as they are simply Lua wrappers for C functions.

Keep boost.process alive outside of the function is was called from

I'm using Visual Studio 2019 on Windows 10, using the boost.process library. I'm trying to make chess, and I'm using the stockfish engine as a separate executable. I need the engine to run throughout the entirety of the game, as that's how it's designed to be used.
Currently I have in ChessGame.h
class ChessGame
{
public:
void startStockFish();
void beginGame();
void parseCommand(std::string cmd);
private:
boost::process::child c;
boost::process::ipstream input;
boost::process::opstream output;
}
And in ChessGame.cpp
#include ChessGame.h
void ChessGame::startStockFish()
{
std::string exec = "stockfish_10_x32.exe";
std::vector<std::string> args = { };
boost::process::child c(exec, args, boost::process::std_out > input,
boost::process::std_in < output);
//c.wait()
}
void ChessGame::beginGame()
{
parseCommand("uci");
parseCommand("ucinewgame");
parseCommand("position startpos");
parseCommand("go");
}
void ChessGame::parseCommand(std::string cmd)
{
output << cmd << std::endl;
std::string line;
while (std::getline(input, line) && !line.empty())
{
std::cout << line << std::endl;
}
}
And in main.cpp
ChessGame chessGame = ChessGame(isWhite); //isWhite is a boolean that control who the player is, irrelevent to the question
//std::thread t(&ChessGame::startStockFish, chessGame);
chessGame.startStockFish();
chessGame.beginGame();
The problem is that I believe as soon as the function startStockFish finishes it terminates c, as nothing is outputted to the terminal as described above, but if I use beginGame() within startStockFish() it outputs as expected. Also, if I uncomment the line c.wait() and the funtion waits for stockfish to exit, it gets stuck as stockfish never gets the exit command. If I instead try running startStockFish on a separate thread in main (as seen above) I
get the following two errors:
the argument to a feature-test macro must be a simple identifier.
In file 'boost\system\detail\config.hpp' line 51
and
'std::tuple::tuple': no overloaded function takes 2 arguments.
In file 'memory' line 2042
Also, I don't want to use threads as I can imagine that will have its own issues with the input and output streams.
So is there a way for me to keep the process alive out of this function, or do I need to reorganise my code some other way? I believe having the process being called in main would work, but I really don't want to do that as I want to keep all the chess-related code in ChessGame.cpp.
Ok I believe that adding c.detach(); after initialising the boost.process child in startStockFish() has done what I want, as the program no longer terminates c when the function ends. Input appears to work fine with a detached process, simply writing output << cmd << std::endl; where cmd is the desired command as a std::string has no issues. However, output does have some issues, the usual method of
std::string line;
while (std::getline(input, line) && !line.empty())
{
// Do something with line
}
somewhat works, but std::getline(input, line) will get stuck in an infinite loop when there are no more lines to output. I couldn't find a direct solution to this, but I did find a work around.
Firstly I changed the initialisation of the boost.process child to
boost::process::child c(exec, args, boost::process::std_out > "console.txt", boost::process::std_in < output);
And then changed input to a std::ifstream, a file reader stream. Then to get the output I used
input.open("console.txt");
std::string line;
while (std::getline(input, line))
{
// Do something with line
}
input.close();
I also added remove("console.txt"); to the beginning of startStockFish() to attain a fresh text file.
I'm not confident that this is the best solution, as I am worried about what would happen if stockfish tried to write to console.txt as input was reading from it, but that hasn't seemed to occur or doesn't seemed to be an issue if it has occurred, so right now it is an adequate solution.

Simultaneously running 2 or more boost testcases belonging to different test suites via cmd

Consider the following scenario:
BOOST_AUTO_TEST_SUITE(suite1)
{
BOOST_AUTO_TEST_CASE(case1)
{
//my test code here
}
}
BOOST_AUTO_TEST_SUITE(suite2)
{
BOOST_AUTO_TEST_CASE(case1)
{
//my test code here
}
BOOST_AUTO_TEST_CASE(case2)
{
//my test code here
}
}
Now, if I want to run suite1/case1 and suite2/case2 at once, I try the following command line argument:
MyProject.exe --run_test="suite1/case1, suite2/case2"
But this doesn't seem to run.
I know that I can separately run these test cases, as:
MyProject.exe --run_test="suite1/case1"
and
MyProject.exe --run_test="suite2/case2"
But I want to run them together at one go. What should I do?
Thanks in advance :)
This is not a feature currently supported by Boost.Test. The documentation states that you can use a comma separated list if the tests are in the same suite:
Running multiple test cases residing within the same test suite by listing their names in coma separated list.
You can also use wildcards to select suites and test cases, but depending on the names of your suites and cases, you may not be able to limit the selection to just to two cases you desire.
http://www.boost.org/doc/libs/1_55_0/libs/test/doc/html/utf/user-guide/runtime-config/run-by-name.html
Edit It seems I might have taken the question title a bit too literally. Running tests simultaneously means "in parallel" to me.
Anyways, if you are happy to run suite2/case1 as well, you can just
MyProject.exe --run_test="suite1,suite2"
See it Live On Coliru too.
Old answer: What is wrong with running the two processes in parallel? By all means, uncomplicate!
However, if you insist, you can fork copies of the main process:
#include <sys/types.h>
#include <sys/wait.h>
#include <iostream>
static int relay_unit_test_main(std::vector<std::string> args);
int main()
{
if (int const child_pid = fork())
{
int exit_code = relay_unit_test_main({"--run_test=suite1"});
int child_status;
while (-1 == waitpid(child_pid, &child_status, 0));
if (!WIFEXITED(child_status)) {
std::cerr << "Child process (" << child_pid << ") failed" << std::endl;
return 1;
}
return exit_code? exit_code : WEXITSTATUS(child_status);
} else
{
return relay_unit_test_main({"--run_test=suite2"});
}
}
See it Live On Coliru
The function relay_unit_test_main is really nothing more than a convenience wrapper around unit_test_main that avoids meddling with argv[] manually:
static bool init_function() { return true; }
static int relay_unit_test_main(std::vector<std::string> args)
{
std::vector<char const*> c_args;
c_args.push_back("fake_program_name");
std::transform(args.begin(), args.end(), std::back_inserter(c_args), std::mem_fn(&std::string::data));
c_args.push_back(nullptr);
return unit_test_main( &init_function, c_args.size()-1, const_cast<char**>(c_args.data()) );
}
This actually spawns a child process - and even tries to usefully combine the exit code information. Having a separate process prevents the problems that you'd get from using code that wasn't designed for multi-threaded use on different threads.
One caveat remains: if your program does static initializations before entry of main(), and these use external resources (like, log files, e.g.) there might be conflicts. See
man fork(3)
Does Boost Log support process forking? for an example of a lib that has potential issues with fork()

How to make tcl interpreter not to continue after exit command?

static int
MyReplacementExit(ClientData unused, Tcl_Interp *interp, int argc, const char *argv[])
{
// Tcl_DeleteInterp(interp);
// Tcl_Finalize();
return TCL_OK;
}
int main() {
Tcl_Interp *interp = Tcl_CreateInterp();
Tcl_CreateCommand(interp, "exit", MyReplacementExit, NULL, NULL);
Tcl_Eval(interp, "exit ; puts 11111111");
std::cout << "22222222222" << std::endl;
return 0;
}
I need to handle exit command evaluation of tcl interpreter. By default it tries to delete itself and also calls std::exit which closes whole program.It is not what I want so I am trying to replace it by custom proc. I dont need to delete interpreter in exit handler proc(I can do it later), only need it to not continue evaluating commands after exit command.
In this code I need to change MyReplacementExit proc somehow, so 11111111 doesn't be printed but
22222222222 does printed.
It can be achieved by returning TCL_ERROR from MyReplacementExit proc, but then I can't distinguish other error situations from this.
Make your replacement for exit delete the interpreter (which stops further commands from being executed, but doesn't actually immediately delete the data structure as it is still in use) and, important, wrap the call to Tcl_Eval with calls to Tcl_Preserve and Tcl_Release. Don't call Tcl_Finalize if you can possibly avoid it; that is for when you're about to unload the Tcl library from memory and can be quite tricky (it's easier to just quit the process, frankly).
Here's how to do it with your code (adapted):
static int
MyReplacementExit(ClientData unused, Tcl_Interp *interp, int argc, const char *argv[])
{
Tcl_DeleteInterp(interp); // <------------------
return TCL_OK;
}
int main() {
Tcl_Interp *interp = Tcl_CreateInterp();
Tcl_CreateCommand(interp, "exit", MyReplacementExit, NULL, NULL);
Tcl_Preserve(interp); // <------------------
Tcl_Eval(interp, "exit ; puts 11111111");
Tcl_Release(interp); // <------------------
std::cout << "22222222222" << std::endl;
return 0;
}
Be aware that you should not access the interpreter at all after the Tcl_Release as it might've been destroyed (as in, the memory released and scribbled over with random junk) at that point. If you need to retrieve results and use them (e.g., printing them out) do so beforehand.
Note that in this specific case, you don't need the preserve/release pair; your code isn't actually touching the interpreter after the Tcl_Eval (which does its own preserve/release internally).
If you don't want the interpreter to terminate, that's much trickier. The cleanest way in 8.4 is probably to throw a custom exception code (i.e., anything greater than TCL_CONTINUE) but there's no guarantee that it will work for arbitrary code as Tcl's catch command can still trap it. If you're really in that situation, it's actually easier to create an interpreter, run the arbitrary code in the sub-interp, and tear it down at the end of the script; you can then drop that interpreter without losing much context. Indeed, you could do:
Tcl_Preserve(interp);
if (Tcl_Eval(interp, theScriptToEval) != TCL_OK)
// Handle unexpected errors here
if (!Tcl_InterpDeleted(interp))
Tcl_DeleteInterp(interp);
Tcl_Release(interp);
Yes, this will mean you want to keep the amount of work you do to set up the interpreter fairly small; you probably won't want to try to call this every millisecond on an interrupt…

DeleteInterpProc called with active evals

I am writing a program which executes tcl scripts. When the script has exit command, the program crashes with this error
DeleteInterpProc called with active evals
Aborted
I am calling Tcl_EvalFile(m_interpreter, script.c_str()) where script is the file name.
Also I have tried Tcl_Eval with arguments interpreter and "source filename". Result is the same. Other tcl comands (eg. puts) interpreter executes normally. How this can be fixed?
#include <tcl.h>
#include <iostream>
int main() {
Tcl_Interp *interp = Tcl_CreateInterp();
//Tcl_Preserve(interp);
Tcl_Eval (interp, "exit");
//Tcl_Release(interp);
std::cout << "11111111111" << std::endl;
return 0;
}
This is the simple case. "11111111111" are not printed. As I understand whole program is exited when calling Tcl_Eval (interp, "exit");. The result is same after adding Tcl_Preserve and Tcl_Release.
The problem is that the interpreter, the execution context for Tcl code, is getting its feet deleted out from under itself; this makes it very confused! At least you're getting a clean panic/abort rather than a disgusting hard-to-reproduce crash.
The easiest fix is probably to do:
Tcl_Preserve(m_interpreter);
// Your code that calls Tcl_EvalFile(m_interpreter, script.c_str())
// and deals with the results.
Tcl_Release(m_interpreter);
Be aware that after the Tcl_Release, the Tcl_Interp handle may refer to deleted memory.
(Yes, wrapping the Tcl_Preserve/Tcl_Release in RAII goodness is reasonable.)
If you want instead to permit your code to run after the script does an exit, you have to take additional steps. In particular, the standard Tcl exit command is not designed to cause a return to the calling context: it will cause the process to call the _exit(2) system call. To change it's behavior, replace it:
// A callback function that implements the replacement
static int
MyReplacementExit(ClientData unused, Tcl_Interp *interp, int argc, const char *argv[])
{
// We ought to check the argument count... but why bother?
Tcl_DeleteInterp(interp);
return TCL_OK;
}
int main() {
Tcl_Interp *interp = Tcl_CreateInterp();
// Install that function over the standard [exit]
Tcl_CreateCommand(interp, "exit", MyReplacementExit, NULL, NULL);
// Important; need to keep the *handle* live until we're finished
Tcl_Preserve(interp);
// Or run whatever code you want here...
Tcl_Eval(interp, "exit");
// Important piece of cleanup code
if (!Tcl_InterpDeleted(interp))
Tcl_DeleteInterp(interp);
Tcl_Release(interp);
// After this point, you *MUST NOT* use interp
std::cout << "11111111111" << std::endl;
return 0;
}
The rules for doing memory management in these sorts of scenarios are laid out in the manual page for Tcl_CreateInterp. (That's the 8.6 manual page, but the relevant rules have been true since at least Tcl 7.0, which is over 2 decades ago.) Once an interpreter is deleted, you can no longer count on executing any commands or accessing any variables in it; the Tcl library handles the state unwinding for you.
It might be better to replace (hide) the exit command and create your own exit command that exit your program gracefully. I'm not that good with C and the Tcl C Api, but I hope this can help you.
Eggdrop for example uses the die command to exit gracefully.