_popen fails to return java version - c++

In my C++ on Windows program I have to collect java version by firing the command "java -version".
I am using _popen API for the same.
When I use _popen command for firing any windows command prompt commands then _open returns properly the output of the command in the buffer.
char versionCmd[256] = "";
char buffer[1024];
strcpy(versionCmd, "netstat -an");
FILE *File_p = _popen(versionCmd, "r");
if (!File_p)
{
return -1;
}
while(fgets(buffer, sizeof(buffer), File_p))
{
printf("buffer = %s", buffer);
}
But when I run the same program with command "java -version" then _popen does not return anything in the buffer.
strcpy(versionCmd, "java -version");
Instead the output gets printed on the console from where I ran this windows program.
Looks like the output of the command is getting redirected to console instead of buffer.
Is there anyway I can redirect the output of the "java -version" command to the program's buffer?
How to resolve this issue?

Related

failing to execute a shell command in windows using WindowsAPI

I am trying to execute a ping command in windows via their ShellExecute function.
ShellExecute(0, L"open", L"cmd.exe", normToWide(command).c_str(), 0, SW_HIDE);
This is how i call the Function.
to get the wide string i use this function
std::wstring normToWide(std::string str)
{
std::wstring str2(str.length(), L' ');
std::copy(str.begin(), str.end(), str2.begin());
return str2;
}
the command is this:
ping 127.9 -l 4 -n 300 > output.txt
Although the ip is invalid it should not matter as output.txt should still be populated with some sort of error message at hte least. What is going on with my function?
I expected there to be a output.txt file with the output of the command
I also tried hardcoding my command to make sure it was not a widestr issue
The problem is ping is not a built in command in cmd.exe and it will not automatically execute the command you pass to it, thus ping even if it is installed and in the command path will not be executed. To fix this you have two choices.
The first is to prefix the command string with the /C option which "Carries out the command specified by string and then terminates" like so
/C ping 127.9 -l 4 -n 300 > output.txt
This will force cmd.exe to execute ping if it is in installed and in the command path.
The second is just as easy - just specify ping.exe as the command for ShellExecute to execute instead of cmd.exe.
ShellExecute(0, L"open", L"ping.exe", normToWide(command).c_str(), 0, SW_HIDE);
If you want to execute ping.exe and capture the output it produces, it'll be much cleaner to use something on this order:
FILE *f = _popen("ping 127.9 -l 4 -n 300");
char buffer[256];
while (fgets(buffer, sizeof(buffer), f) {
// `buffer` contains a line of output from `ping`
}
ShellExecute(NULL,NULL,L"cmd.exe", L"/K ping 127.9 -l 4 -n 300 > d://test.txt",NULL, SW_SHOWNORMAL);
/k: end cmd window does not disappear
/c: end cmd window disappear

PyRun_SimpleFile in C++ (Visual Studio Desktop application) does not call Python file (No error)

I hope I am not duplicating posts from the past (although I have read and tried many existing posts in stackoverflow without any gain). I have a VC++ application where I am trying to call a function that would then run a Python file. I have Python 311 installed and configured via the project settings. The code compiles fine but I believe does not run the file encode_post.py. The returned value from PyRun_SimpleFile is 0 (if I run another file the result is -1). In the encode_post.py file, I am simply opening a test.txt file and appending the command line argument argv[1] "Hello world" (I tried without providing the argument too). If I double click encode_post.py in the folder or run it via the command prompt, it runs fine and writes the line in test.txt, but running the file via C++ does not append anything. Below is my code which does not throw any error or breaks the application. In project settings, I also configured to run Debug DLL in runtime library in code generation. Any advice would be great as at this point I am not sure where exactly the issue is arising. I also have #include <Python.h> in my code without any error
char* argv[2];
argv[0] = "encode_post.py";
argv[1] = "Hello world";
try {
Py_Initialize();
Py_SetProgramName((wchar_t*)argv[0]);
PySys_SetArgv(2, (wchar_t**)argv);
file = fopen(argv[0], "r");
if (file) {
int result = PyRun_SimpleFile(file, argv[0]);
fclose(file);
}
Py_Finalize();
}
catch (IOException^ ex) {
// Could not open the file
}
Use _Py_fopen_obj. The snippet below works for me.
PyObject* obj = Py_BuildValue("s", argv[0]);
FILE* file = _Py_fopen_obj(obj, "r");
if (file) {
PyRun_SimpleFile(file, argv[0]);
}

Run a bash script with C++ on Windows

I am trying to write a program in C++ that can execute a bash script on Windows and then read the output of the bash script and store it into a string or something like that. Is this even possible without installing any extra software on Windows? If so, how?
Also, would it work if I wrote the program on Linux with a Posix library and then cross-compiled the C++ program for Windows inside Linux and then move it over to Windows where it needs to execute the bash script?
You can use the popen function.
FILE *fp;
fp = popen("bash script.sh", "r");
Now you can read the output just like you would read a file. Example:
char output[100];
fgets(output, sizeof(output), fp);

viewing output of system() call in C++

How can I view the output of a system command. Ex:
int _tmain(int argc, _TCHAR* argv[]) {
system("set PATH=%PATH%;C:/Program Files (x86)/myFolder/bin");
system("cd C:/thisfolder/");
std::cin.get();
return 0;
}
when I run the program in Visual Studio it give me a black screen and I cannot see the command being run. I need it so I can view whether it worked or not. Thanks!
Use popen instead of system. See example here https://msdn.microsoft.com/en-us/library/96ayss4b.aspx
char psBuffer[128];
FILE *pPipe;
if( (pPipe = _popen( "set PATH=%PATH%;C:/Program Files (x86)/myFolder/bin", "rt" )) == NULL )
exit( 1 );
then
while(fgets(psBuffer, 128, pPipe)) {
printf(psBuffer);
}
if (feof( pPipe))
printf( "\nProcess returned %d\n", _pclose( pPipe ) );
The output of a system call should show up on stdout.
I do not think those commands generally have any output to display if they are successful. Try adding a dir or pwd after to list the directory you are in.
If you want to get the output from the commands into the program for processing that is another issue. You will have to use os specific api, or maybe redirect the output into a file you can read.
Try adding pause as below to wait after each command. On failure, error message will be displayed. On success, actual output from the command, if any, will be displayed.
system("set PATH=%PATH%;C:/Program Files (x86)/myFolder/bin & pause");
system("cd C:/thisfolder/ & pause");
Note that each call to system uses cmd.exe( as cmd /c [command] ) to execute your command and env variables like PATH in one command won't effect another.
cmd.exe /c set PATH=%PATH%;C:/Program Files (x86)/myFolder/bin
cmd.exe /c cd C:/thisfolder/

Nodejs and UNIX newbie: run node command in a cpp program

I'd like to run a nodejs program through the system() function in stdlib.h. I can run the bash command /usr/local/bin/node ~/some_folder/xml2js.js in terminal, but when I ran this:
int main(int argc, const char * argv[])
{
// insert code here...
//system("/usr/local/bin/node ~/some_folder/xml2js.js");
system("~/some_folder/run.sh");
std::cout << "Hello, World!\n";
return 0;
}
It told me node: command not found.
the run.sh is below:
#! /bin/bash
node ./xml2js.js
Are there any other ways to call other programs in UNIX? And how to get the output of the command into stdout?
Try writing the absolute path to that script. It should work.
You could try system("/home/$(whoami)/some_folder/run.sh") assuming that your user's home folder is in /home.
Also, does that script have execute permissions? Also, check the return code of system.