Suppressing stdout for a system() call in Windows (C) - c++

Like this I have a cross platform piece of code which needs to start a separate process, I'm using a system() call for ease of use and because it is cross-platform, but in Windows I can't find a method of stopping the stdout from the system() call going to the terminal window.
This is very annoying as the .exe the system call starts has a lot of pointless outputs which can't be silenced with options.
Here's the code:
std::system("wgrib2 C:/Inputs/HRES_ENS_2014032500+000.grib2 -lola -8.0:140:0.1 48.0:140:0.1 C:/Inputs/HRES_ENS_2014032500+000.bin bin -for 2:2:1");
In case it makes any difference, I'm using minGW as a compiler.

Related

Launch command line programs behind all open windows from a C++ executable

I am working on C++ program in windows which launches numerous external programs using command lines in quick succession after previous one finishes. Currently a new terminal pops up in front every time I make an external program call. I have tried SYSTEM an POPEN. Is there a way to launch these terminals in the back behind all open windows so that its not annoying to the end user who may be working on other stuff?
One solution is listed here but doesn't work for me as it still pops up terminal in the foreground.
c++ run system() in background, with spaces in dir path, + output to text file
system("start \"\" cmd abcd.exe");
Unless you really need to use system(), I would recommend using ShellExecuteA, if you set nShowCmd to 0, it doesn't generate any windows or pop up any consoles.

MSVC compiler (cl.exe) starts new console window. how to prevent?

One of my Win10 desktops has very odd problem with visual c++ compiler (vc142 toolchain/msvs2019, Win10): it opens new console window each time when c++ compiler (cl.exe) is started by any GUI app.
as the compiler is in the use by IDEs (e.g. VisualStudio, CLion, QtCreator etc) , it's very useless because output of the compiling can't be caught by callee (IDE) and IDEs don't show any compilation output , especially compile message in case of error. Obviously these IDEs do this indirectly , via build systems like msbuild or cmake . anyway , the problem is there.
So NMake or MSBuild can't be used correctly , because those ones run cl.exe in separate window. I have to run a build procedure from command line manually to see the error message.
the same toolchain can be used correctly on other Win10 hosts. I don't see the difference...
any idea why it 's happening and how to fix?
P.S. probably this is not a problem of cl but some windows terminal settings... or even security issues (I'm not an admin on that host)
For us, it was a corporate spyware program, BeyondTrust/PowerBroker for windows that was somehow making cl.exe misbehave.
PowerBroker basically takes over the UAC control and forces apps to run in privileged mode or non-privileged mode, etc. I'm not sure the mechanism but somehow it interfered with cl.exe writing to stderr, or ninja.exe's ability to redirect stderr to itself, or ninjas ability to pipe it somewhere or something.
Anyways, putting a whitelist rule in (or killing the beyondtrust service) made VSCode calling cmake calling ninja calling cl.exe behave properly.
EDIT: More details: cmake.exe, ninja.exe, and cmd.exe are the processes that need to get exempted from BeyondTrust's PRIVMAN to make cmake builds from VSCode function without popups.

Show command prompt with Qt Creator and CMake

The dev environment in question consists of:
Windows 7
MinGW (g++)
CMake
Qt Creator
The problem is that Qt Creator, a lovely IDE as far as I can tell, does not display programs' command-line output. It seems to have its own proprietary debug pane, but it doesn't give me, for example, runtime errors. It just tells me that the program has failed and gives me the exit code. I'm using Creator only for its C++ capabilities, and not using Qt in any way, so the proprietary pane is useless to me.
So I ask this: Can something be done? Am I missing something really, stupidly obvious like a built-in command line? Or, if not, can I at least use some filthy and/or repulsive hack to get it to display the Windows command prompt upon running a program?
Last thing; I did do some research, and found a way to edit the Qt project file to display the prompt, but... I'm using CMake, not Qt projects. So that doesn't answer my question. If I can do something similar with CMakeLists.txt, that would be wonderful. But Google has failed me on that front, so I'm not holding out too much hope.
EDIT:
I'm specifically worried about runtime errors. cout and printf are rerouted to Qt Creator's window, so that's fine. I don't get runtime errors unless the debugger catches them, and the frequency of that is less than ideal.
Windows GUI programs don't have standard output.
In Windows there are two possible entry points in the standard runtime. The console one and the windows one. The console one will inherit console window from parent process or create a new one and connect the standard input/output/error streams to it, while the windows one will leave them unconnected unless they were explicitly redirected by the invoking process. A Qt application is (probably; you could have console Qt-Core application) a GUI application and Qt Creator (nor any other Windows IDE) does not redirect the output explicitly. Therefore the standard output is not open at all and the writes are being discarded.
However windows have separate logging facility for debugging purpose. This is what you see in the debug window. You can write to it using the native OutputDebugString API. I am sure you can also direct the Qt debug log there.
Note, that when it tells you the program has exited with status 0, it means the program ran, which in turn means it compiled successfully and thus there were no errors from g++. There may have been warnings, in which case you should see them in the appropriate other window. Compiler and program output are different things; the IDE does read the compiler output.

How to make a linux command-line program work in windows?

I'm a beginner with programming, and I've been doing work in C/C++ in Ubuntu. When I tell something to cin/cout/cerr or printf/scanf or take arguments from the command line, this all happens from the linux terminal in Ubuntu.
Now if I want to run these same programs (very simple programs, beginner-level) and run them in Windows, how do I run them from the Windows command line? A previous course I've taken had us download cygwin to simulate the linux command line in windows, but what if I want to just run the program from the ordinary windows command line? Is that possible, and does it require modification of the software?
You can cross-compile the program for Windows from linux.
On Ubuntu, process is basically this:
sudo apt-get install wine mingw32 mingw32-binutils mingw32-runtime
...
i586-mingw32msvc-g++ -o myProgram.exe myProgram.cpp
Easy, right? Google for "ubuntu cross-compile windows," there's a ton of information out there.
It's exactly the same. You run cmd and write the command (almost) exactly as you would in Linux.
For example, if you build your program to program, you would run it in Linux like this:
./program --option1 -o2 file1 file2
And in Windows, first you have to make the output have a .exe suffix and then in cmd you would write:
program.exe --option1 -o2 file1 file2
Basically saying, cmd is Windows' terminal. It's nowhere near as good as the Linux terminal, but that would be all you get without installing additional software.
cin/cout/cerr and printf/scanf/fprintf(stderr, ...) use the standard C preopened files stdin, stdout and stderr which are defined both in Linux and Windows. Once you run the application from Windows' terminal (cmd), you see the input/output exactly as you would in the Linux terminal. I/O redirection is also very similar.
cin and cout, and printf and scanf, work much the same in Windows as they do in Linux. (I'm pretty sure cerr does too, but that one i'm not 100% sure about. At the very least, though, it's there and works.) The biggest difference is that Windows typically won't expand wildcards (stuff like *.txt) before running your program; you have to do that yourself in most cases.
Basically, as long as the app doesn't use anything specific to Linux or GCC, you could just recompile it on the target machine using whatever compiler you like to test.
If you don't want to recompile...well...good luck with that. Even Cygwin won't run native Linux binaries. You'd need a virtual machine with Linux on it.
Well, if you program is portable and not using any features specific to Linux, you would have to compile it from source on Windows to make it work on Windows.
You would need the GCC tool-chain for windows to do that, which you can get from the TDM-GCC homepage. Its MinGW internally and the installer allows you to choose the features you want to install as well as the target directory for installation. It also adds itself to Windows path so that the compiler commands are available from the shell prompt.
I have to do the cross compilation regularly and it works without any issues for me. There is one change which you must make if your project is using Makefiles. For the target binary, such as <target>.out in linux, you would have to edit your Makefile and rename it to <target>.exe so that it runs on the command line. If you are not using Makefiles and just doing gcc <file.c>, the a.exe is produced by default (similar to a.out in Linux).
Say you have this program code you want to run on UNIX and Windows:
#include <stdio.h>
int main()
{
printf("Hi\n");
return 0;
}
When you type a command in a UNIX shell it will be something like this.
/usr/home/bobby# gcc main.c
/usr/home/bobby# ./a.out
Hi
/usr/home/bobby#
On Windows you'd have to first choose your development environment/compiler. Without going to something like Cygwin, you could install the Windows SDK or Visual studio (although if the latter you might just want to develop in the GUI).
Start -> Run -> cmd /k ""C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"" x86
C:\Windows\system32>cd c:\bobby
C:\bobby>cl main.c
C:\bobby>main.exe
Hi
C:\bobby>
When a C program is compiled into an executable this is done in a system dependent way. On Ubuntu the ELF format is used and on Windows we have PE.
When you start a process the ELF or PE is read giving instructions/map on how to allocate memory and where to put various pieces of the process in a virtual memory table. Further it links up to dynamically loaded libraries, already in physical memory, that it share with other processes which is using the same libraries. Or if the dynamic libraries is not present load them. (Linux .so, windows .dll). If it has static libraries these are allocated and linked in (Linux .a, Windows .lib). - Very simplified.
Memory restrictions etc are inherited from previous process.
Environment variables are put into the running environment for the process. This being paths, arguments, etc. Then main() is added to the stack and called.
Now everything happening before main is called and how linkage etc are resolved, and so many other things, depends on the system. This is why one simply can't run an executable compiled on Linux on Windows.
Using cygwin one is simply creating a virtual environment where those linkages etc are the same and would work. One create an ELF environment.
To get it linked for native Windows command line one would have to compile for Windows. On that matter I see there is lots of answers already.
The ELF and PE, as on different systems, also have different ways of handling environment variables etc. What these are etc. So i.e. file expansion is handled differently. However both running processes has the default streams like stderr, stdout and stdin. But below your code in C they are not the same.
It is like driving a diesel vs a petrol car. Much is the same but under the hood quite a few things is different.
Be aware that i.e. signals are handled different on Windows.

Problem spawning application

Gosh, this is so weird, I don't know what to say. The short version is that I have a simulator app which I spawn from my application when the user asks me to. It recently stopped working, though I can run the simulator fine from the command line or Start menu. This could be due to moving to VS2010 or Windows 7 or something I didn't notice reviewing source control diffs.
I have a second simulator which I try to spawn in the same fashion and it works fine.
By default, I'm using Qt3's QProcess wrapper around CreateProcess for this purpose, but I get the same behavior using system, my own CreateProcess, and ShellExecute.
ShellExecute of a cmd.exe "/c application params" does provide me with some more information however. I get the dialog
"The program can't start because MSVCR80.dll is missing from your computer. Try reinstalling the program to fix this problem."
Inconveniently, both the parent application and the second simulator use MSVCR80.dll.
Upon copying MSVC*80.dll from g:\windows\winsxs\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.4927_none_d08a205e442db5b5 to the same directory as my executable, the error message changes to
"Runtime Error!
Program: g:\path\to\app.exe
R6034
An application has made an attempt to load the C runtime library incorrectly.
Please contact the application's support team for more information.
Followed by
The application was unable to start correctly (0xc0000142). Click OK to close the application.
And, once again, the application runs fine from the command line with those dlls in place.
Update:
I suspected perhaps it was environment related, so changed my ShellExecute mechanism to do cmd /c set && app params. I set up a cmd.exe with those same params and my app is now crashing similarly. Will update when I figure out why :)
It is MATLAB's component runtime tool that is modifying my process's PATH variable to bad effect. It is prepending its own dir full of dll's and wreaking havoc.
A foolish tool I was using did a setenv on PATH, prepending a directory it wanted for dynamically loading some dlls, but which messed up my application later. I ended up using GetEnvironmentStrings as shown in the last example here, erasing the first entry in the PATH env var, and sending the new (original) environment to QProcess, which wraps CreateProcessA.
You need to install the CRT
This may work - if it breaks, you get to keep both pieces :-)
Try installing VC++ redistributable from here - http://www.microsoft.com/downloads/en/details.aspx?familyid=A5C84275-3B97-4AB7-A40D-3802B2AF5FC2&displaylang=en.
Remember to backup your system, create a restore point etc. before installing stuff.
Another idea -try reinstalling the failing appliacation itself. It may come with its own copy of VC++ redistributables, and reinstalling might help. Esp. trying to reinstall it using Windows 7's compability mode (perhaps go back to Vista or XP compatibility) might be even more effective.
To reiterate - you'll have to try, and I've no real idea if either of the above ideas will do you good, or even be sure to do no harm. That said, if I were faced with a similar problem, these are the steps I'd try. HTH!