Is there any way to stop opening the dos window?

I use _popen to start a process to run a command and collect output

This is my C ++ code:

bool exec(string &cmd, string &result) { result = ""; FILE* pipe = _popen(cmd.c_str(), "rt"); if (!pipe) return(false); char buffer[128]; while(!feof(pipe)) { if(fgets(buffer, 128, pipe) != NULL) result += buffer; } _pclose(pipe); return(true); } 

Is there a way to do this without opening the dos window (as it currently does in the _popen statement)?

+6
source share
3 answers

As far as I know, you can’t 1 : you start the console application (cmd.exe, which will run the specified command), and Windows always creates a console window when the console application starts.


  • although you can hide the window after starting the process or even hide it if you pass the corresponding CreateProcess flags; the problem is, _popen do not skip these flags, so to create your channel you need to use the Win32 APIs instead of _popen .
+2
source

On Windows, CreateProcess with a STARTUPINFO structure in which dwFlags includes STARTF_USESSHOWWINDOW. Setting STARTUPINFO.dwFlags to SW_HIDE will then hide the hidden console window at startup. Sample code (which may be poorly formatted and contains a combination of C ++ and WinAPI):

 #include <windows.h> #include <iostream> #include <string> using std::cout; using std::endl; void printError(DWORD); int main() { STARTUPINFOA si = {0}; PROCESS_INFORMATION pi = { 0 }; si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; si.wShowWindow = SW_HIDE; BOOL result = ::CreateProcessA("c:/windows/system32/notepad.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); if(result == 0) { DWORD error = ::GetLastError(); printError(error); std::string dummy; std::getline(std::cin, dummy); return error; } LPDWORD retval = new DWORD[1]; ::GetExitCodeProcess(pi.hProcess, retval); cout << "Retval: " << retval[0] << endl; delete[] retval; cout << "Press enter to continue..." << endl; std::string dummy; std::getline(std::cin, dummy); return 0; } void printError(DWORD error) { LPTSTR lpMsgBuf = nullptr; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); cout << reinterpret_cast<char*>(lpMsgBuf) << endl; LocalFree(lpMsgBuf); } 
+3
source

[Final Edit]

a similar SO question combines all of the above and gives you your result C ++ command console without a console

[Edited again]

Erk. sorry i was worried about spawning. I reread your q. and besides an extra window, you are actually trying to get stdout / stderr processes. I just would like to add that for this purpose all my proposals, unfortunately, are not relevant. but I will leave them here for reference.

[Changed]

For no specific reason (except that "open" works for both windows and macs), I use ShellExecute for spawning processes, not for CreateProcess. I will explore this later ... but here is my StartProcess function.

Hidden or smoothed seem to give the same result. the cmd window appears, but it is minimized and never appears on the desktop, which may be your main goal.

 #if defined(PLATFORM_WIN32) #include <Windows.h> #include <shellapi.h> #elif defined(PLATFORM_OSX) #include <sys/param.h> #endif namespace LGSysUtils { // ----------------------------------------------------------------------- // pWindow : {Optional} - can be NULL // pOperation : "edit", "explore", "find", "open", "print" // pFile : url, local file to execute // pParameters : {Optional} - can be NULL otherwise a string of args to pass to pFile // pDirectory : {Optional} - set cwd for process // type : kProcessWinNormal, kProcessWinMinimized, kProcessWinMaximized, kProcessHidden // bool StartProcess(void* pWindow, const char* pOperation, const char* pFile, const char* pParameters, const char* pDirectory, LGSysUtils::eProcessWin type) { bool rc = false; #if defined(PLATFORM_WIN32) int showCmd; switch(type) { case kProcessWinMaximized: showCmd = SW_SHOWMAXIMIZED; break; case kProcessWinMinimized: showCmd = SW_SHOWMINIMIZED; break; case kProcessHidden: showCmd = SW_HIDE; break; case kProcessWinNormal: default: showCmd = SW_NORMAL; } int shellRC = (int)ShellExecute(reinterpret_cast<HWND>(pWindow), pOperation,pFile,pParameters,pDirectory,showCmd); //Returns a value greater than 32 if successful, or an error value that is less than or equal to 32 otherwise. if( shellRC > 32 ) { rc = true; } #elif defined(PLATFORM_OSX) char cmd[1024]; sprintf(cmd, "%s %s", pOperation, pFile); int sysrc = system( cmd ); dbPrintf("sysrc = %d", sysrc); rc = true; #endif return rc; } } 

[and previously mentioned]

If you control the source code of the running application, you can try adding it to the top of your main.cpp (or whatever you called it)

 // make this process windowless/aka no console window #pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) 

You can also pass these parameters directly to the linker. The above is easier to play with various imho build configurations.

0
source

Source: https://habr.com/ru/post/912443/


All Articles