For a programme I've created in Borland C++ Builder 4.0, I would like to be able to create a version with which I can set up a batch script. The batch srcipt would call my .exe (without launching the main form window) which would result in the main process of my program being performed using the inputs specified in the batch file. Once the outputs have been generated the program would shut down.
The first three parameters of the batch script would specify the location for three primary input files (files that otherwise are loaded with a button), set a switch to define whether an interpolation is to be done for a single case or multiple (something like -m or -s). If the former is true, the program would read the location for a fourth type of input file. In the case of the latter it would read in another csv which gives the location of multiple input files of this fourth type of input. The batch file would also define the output location and the output filename.
Based on what I've read so far here and on different forums, I'm thinking the easiest way to achieve this would be to use ParamCount() and ParamStr() and maybe FindCmdLineSwitch. It is still a bit hazy how exactly I'm meant to use these (I apologise for my ignorance, but this is not only my first BCB project but also my first real experience with coding in C++ and creating a Windows GUI)... From what I understand I can use these in a similar fashion to what is described here http://docwiki.embarcadero.com/CodeExamples/Seattle/en/ParamCount_(C%2B%2B).
There are several things I don't know:
How would the batch file look like? How are the parameters separated in it? Just by spaces? Say, after I've included the new part in my script, can I create a batch script which looks something like this?
"C:/Program Files/myprogram/myprogram.exe" "Location of first input" "location of second input" -m etc.
(I have used Ansys CFX, a CFD tool before in batch mode and that for example has switches to define which file is the definition file [-def] and the initialization file [-ini]).
Related to the aboove, how do switches come into the picture? When should they be used? For example, when I want to define a location for the first input, should there be a switch before it, something like -inp1? I see an example here Selection of Forms just after program execution but I'm not sure how does this differ from a simple ParamStr? More specifically, how and when do I use FindCmdLineSwitch?
Finally, using any of the above three functions, do I have to change anything in the WINAPI WinMain() call parameters?
Thank you.
Where in my program should I place the ParamCount() and ParamStr() parts which check whether I've launched the .exe from the command line/with a batch file?
Inside the project's WinMain()
function, like I told you in comments. For example:
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
if (ParamCount() >= 5)
{
String InputFile1 = ParamStr(1);
String InputFile2 = ParamStr(2);
String InputFile3 = ParamStr(3);
String Interpolation = ParamStr(4);
int index = 5;
if (Interpolation == "-s")
{
String InputFile4 = ParamStr(index++);
// load file as needed...
}
else
{
// load CSV as needed...
}
String OutputFile = ParamStr(index);
// process files as needed...
}
else
{
// normal GUI code here...
}
return 0;
}
it is suggested to place it in the main .cpp file, the one which initializes the forms
Yes.
How would the batch file look like?
For example:
myprogram.exe "inputfile1" "inputfile2" "inputfile3" -m "outputfile"
myprogram.exe "inputfile1" "inputfile2" "inputfile3" -s "inputfile4" "outputfile"
How are the parameters separated in it? Just by spaces?
Yes. And parameters that have spaces in of them need to be quoted.
Say, after I've included the new part in my script, can I create a batch script which looks something like this?
Yes.
Related to the aboove, how do switches come into the picture? When should they be used? For example, when I want to define a location for the first input, should there be a switch before it, something like -inp1?
You can do that, but it is not necessary in this situation since the parameters have fixed positions. If you wanted to name your switches, you could do something more like this:
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
int count = ParamCount();
if (count > 0)
{
String InputFile1;
String InputFile2;
String InputFile3;
String InputFile4;
String Interpolation;
String OutputFile;
int idx = 1;
while (idx <= count)
{
String param = ParamStr(idx++);
if (param == "-inp1")
InputFile1 = ParamStr(idx++);
else if (param == "-inp2")
InputFile2 = ParamStr(idx++);
else if (param == "-inp3")
InputFile3 = ParamStr(idx++);
else if (param == "-s")
{
Interpolation = param;
InputFile4 = ParamStr(idx++);
}
else if (param == "-m")
Interpolation = param;
else if (param == "-out")
OutputFile = ParamStr(idx++);
}
// process files as needed...
}
else
{
// normal GUI code here...
}
return 0;
}
I see an example here "Selection of Forms just after program execution" but I'm not sure how does this differ from a simple ParamStr? More specifically, how and when do I use FindCmdLineSwitch?
FindCmdLineSwitch()
searches the entire command line for the specified switch. The switch itself can exist in any position within the command line. That is fine when you don't know, or care, about the order of the parameters, you just want to know if the switch exists. FindCmdLineSwitch()
is not useful when the position of the switch is important, or other parameters are associated with the switch, since FindCmdLineSwitch()
does not tell you the position where it found the switch.
Finally, using any of the above three functions, do I have to change anything in the WINAPI WinMain() call parameters?
No. However, ParamStr()
does have some known parsing issues (see QC #3946), and FindCmdLineSwitch()
is limited to just two formats ("/switch" and "-switch", it cannot handle things like "/switch:value", "switch=value", etc). In those cases, if you find that you need to parse the command line manually, you can use the lpCmdLine
parameter of WinMain()
(though GetCommandLine()
is generally a better option).