How can I hide the window when I run a exe - c++

I have this
static std::string exec(char* cmd) {
FILE* pipe = _popen(cmd, "r");
if (!pipe) return "ERROR -22";
char buffer[128];
std::string result = "";
while(!feof(pipe)) {
if(fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
_pclose(pipe);
return result;
}
But the problem i have is that i want to hide the program that lunches how can I do that? thx

As Hans Passant mentioned in the comments, you have to use CreateProcess to spawn the child process instead of _popen, since _popen does not give you any control over the window creation process.
To hide the console window, use the CREATE_NO_WINDOW process creation flag for the dwCreationFlags parameter.
In order to capture the output of the process, you need to create a pipe for its standard output stream with CreatePipe. Assign that pipe handle to the hStdOutput member of the STARTUPINFO structure you pass in, and make sure to set the STARTF_USESTDHANDLES flag in the startup info's dwFlags so it knows that that member is valid. Then, to read data, you just use ReadFile on the pipe handle.
Hans also provided a link to a good example of creating pipes with a child process here, although that example is doing more than you need to do—it's creating pipes for all three streams (stdin, stdout, and stderr), whereas you only need to capture stdout.

Related

Windows: how can I let the child process read the input anonymous pipe without closing it?

As per subject I'm trying to develop a simple piped parent/child program.
Main purpose of this program is to keep the child process alive and use std::cin and std::cout to communicate between parent/child processes.
On Linux all of this works quite well.
On Windows I've been following the example here and there's one peculiar difference with Linux: one has to invoke
CloseHandle(g_hChildStd_IN_Wr)
To write to the child pipe and flush it. This has the side effect to close the pipe, thus terminating my in-connection to the child process.
I've also tried to use FlushFileBuffers but it doesn't work.
Any idea how can I flush the buffer without having to close the anonymous pipe?
Below sources of both Parent and Child processes.
If the code of the parent process is basically the one in the example above:
// IN_Wr_ is initialized as below with bInheritHandle=TRUE
::CreatePipe(&IN_Rd_, &IN_Wr_, &saAttr, 0);
// and
::SetHandleInformation(IN_Wr_, HANDLE_FLAG_INHERIT, 0)
// When I spawn the child process I do
STARTUPINFO siStartInfo = {0};
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = INVALID_HANDLE_VALUE;
siStartInfo.hStdOutput = OUT_Wr_;
siStartInfo.hStdInput = IN_Rd_;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
...
// then in order to write to std::cin
const DWORD reqSz = static_cast<DWORD>(std::strlen(request));
DWORD written = 0;
while(true) {
DWORD curWritten = 0;
if(!WriteFile(IN_Wr_, request + written, reqSz-written, &curWritten, NULL))
throw std::runtime_error("Error on WriteFile");
written += curWritten;
if(written == reqSz) {
// all written, done
break;
}
}
::FlushFileBuffers(IN_Wr_);
// only when I do this CloseHandle then the child process
// is able to read data
::CloseHandle(IN_Wr_);
this child code is a simple echo server, along the lines of:
buif[2048+1];
while(std::cin) {
std::cin.read(buf, 2048);
const auto rb = std::cin.gcount();
buf[rb] = '\0';
std::cout << buf << std::endl; // this does flush
}
Here's your problem:
std::cin.read(buf, 2048);
It's doing exactly what you've asked it to: waiting until it has read 2048 characters or reaches the end of file. You're not sending 2048 characters, so nothing happens until the server closes the pipe, which counts as the end of file in this context.
Instead, you should be using something like getline(s, 2048, '\0') which will stop reading when it sees a null character. (And, of course, you will need to modify the sender so that it writes that null character at the end of the string.)
Alternatively, you could use the native API: ReadFile has the semantics you seem to be wanting. Ideally you would use a message-mode pipe, which is designed precisely for this sort of use.
The article here might be helpful: https://support.microsoft.com/en-us/kb/190351. It has a section on flushing problems when printf is used to send data to the redirected pipe, which seems to be done in your case. The suggested solution is to use fflush(NULL) to flush the C run-time IO buffers.
It looks like the issue is a MSFT implementation of std::cin::read (and even fread(..., ..., ..., stdin)).
If instead of relying on:
// C++ API
while(std::cin) {
std::cin.read(buf, 2048);
...
// or also "C" API
int rb = 0;
while(0 < (rb = fread(buf, 2048, 1, stdin))) {
...
I do
// Low level Win32 "C" API
while(::ReadFile(hStdin, buf, 2048, &rb, 0)) {
...
// or also low level unix-like "C" API
int rb = 0;
while(0 < (rb = _read(0, buf, 2048))) {
...
The above example just works fine (funnily enough, the call to FlushFileBuffers is not even needed).

ReadFileEx, variable length - a few questions

I'm trying to read from stderr of a child process. The data is lines of text created with sprintf(stderr, "some debug info\n"). I'm using ReadFileEx with a completion routine. I don't know how many lines of text or how long each line will be. So, what do I put as the nNumberOfBytesToRead parameter?
My guess is I put the max size of my buffer, which I will make 4k; although I don't know if that's an optimal size. I'm guessing that if the line written to stderr is shorter than 4k, the completion routine won't fire. I'm guessing that when the 4k is reached but more data remains, I have to fire off another ReadFileEx within the completion routine. I'll know this is the case because GetLastError will return ERROR_MORE_DATA. I'm hoping that I get a call when the buffer isn't full, but the child process has exited. I'm not sure I get a completion callback when the child process exits, because I passed the stderr write handle to the child when I created it; maybe I get the callback when I close that handle. Are there any race conditions when the child closes wrt to my reading stderr?
Here is the psuedo code of how the process and handles are created:
Attr.bInheritHandle = true
CreatePipe(&hr, &hw, &Attr, 0) and SetHandleInformation(hX, HANDLE_FLAG_INHERIT) on hX the child uses.
Si.hStdXXX = handles from CreatePipe that child uses
CreateProcess(inherit=true, &Si)
Details (Tx extension is a wrapper that throws errors):
HANDLE Create() {
STARTUPINFO SI, *pSI = NULL;
bool fInherit = m_fInherit;
if (m_fStdOut || m_fStdIn || m_fStdErr) {
fInherit = true;
SECURITY_ATTRIBUTES Attr;
Attr.nLength = sizeof(SECURITY_ATTRIBUTES);
Attr.bInheritHandle = TRUE;
Attr.lpSecurityDescriptor = NULL;
if (m_fStdOut) // Create a pipe for the child process's STDOUT. The child will use the write.
CHandle::CreatePipe(m_hStdOutR, m_hStdOutW, &Attr, CP_INHERIT_WRITE);
if (m_fStdErr) // Create a pipe for the child process's STDERR. The child will use the write.
CHandle::CreatePipe(m_hStdErrR, m_hStdErrW, &Attr, CP_INHERIT_WRITE);
if (m_fStdIn) // Create a pipe for the child process's STDIN. The child will use the read.
CHandle::CreatePipe(m_hStdInR, m_hStdInW, &Attr, CP_INHERIT_READ);
// Set up members of the STARTUPINFO structure.
// This structure specifies the STDIN and STDOUT handles for redirection.
ZeroStruct(SI);
SI.cb = sizeof(STARTUPINFO);
SI.hStdError = m_hStdErrW, SI.hStdOutput = m_hStdOutW, SI.hStdInput = m_hStdInR;
SI.dwFlags |= STARTF_USESTDHANDLES;
pSI = &SI;
}
// m_fCpu, m_fNuma are masks to set affinity to cpus or numas
CreateProcessTx(NULL, m_szCmdLine, fInherit, m_fFlags, pSI, &m_pi, m_fCpu, m_fNuma, 5);
m_hProc = m_pi.hProcess;
m_hThread = m_pi.hThread;
if (!m_fThread)
m_hThread.Close();
return m_hProc;
}
static void CreatePipe(CHandle &hRead, CHandle &hWrite, SECURITY_ATTRIBUTES* pAttr, BYTE fInheritMask) {
HANDLE hReadTmp = NULL, hWriteTmp = NULL;
CreatePipeTx(hReadTmp, hWriteTmp, pAttr);
SetHandleInformation(hReadTmp, HANDLE_FLAG_INHERIT, (fInheritMask&CP_INHERIT_READ) ? HANDLE_FLAG_INHERIT : 0);
SetHandleInformation(hWriteTmp, HANDLE_FLAG_INHERIT, (fInheritMask&CP_INHERIT_WRITE) ? HANDLE_FLAG_INHERIT : 0);
hRead = hReadTmp;
hWrite = hWriteTmp;
}
Anonymous pipes created with CreatePipe can't used asynchronously. From the Windows SDK documentation:
Asynchronous (overlapped) read and write operations are not supported by anonymous pipes.
This means that you cannot use the ReadFileEx and WriteFileEx functions with anonymous pipes. >In addition, the lpOverlapped parameter of ReadFile and WriteFile is ignored when these >functions are used with anonymous pipes.
Basically CreatePipe doesn't accept a FILE_FLAG_OVERLAPPED flag, and asynchronous I/O requires that you use the flag when creating the file handle.
You'll have to use CreateNamedPipe to create named pipes. The question Overlapped I/O on anonymous pipe has answer with a link to a replacement function MyCreatePipeEx you can use.
Your completion port should receive a zero length read event after attempting to read from a pipe that has been closed on the other end.
To read a variable amount of data from the client process just issue read requests of whatever size you find convenient and be prepared to handle read events that are shorter than you requested. Don't interpret a short but non-zero length as EOF. Keep issuing read requests until you get a zero length read or an error.
Also WaitForMultipleObjects won't work with completion routines, as they're only called while the thread is in an alterable state. Use WaitForMultipleObjectEx with the bAlertable argument set to to true. This function will return WAIT_IO_COMPLETION after running one or more completion routines. In that case you'll probably want to immediately call WaitForMultipleObjectEx again.

Reading from pipes blocks and deadlock

I am developing a remote shell like program. for running commands on remote machine I create a cmd.exe process and I redirect its stdin and stdout to a pair of pipes.
I use these pipes to send commands and get the result.
I used ReadFile function for returning the output of command from cmd.exe but I don't know the
exact amount of data that I must read from pipe. so if the data is not ready the readfile
goes to blocking mode and waiting for data.
I am using MSVC++ 2010 and my OS is Win7. Here is a part of my code as an example:
void CpipesDlg::OnBnClickedBtnredirstd()
{
char Cmd[]="dir *.*\r\n";
char Buff[129];
CString str;
HANDLE hStdIn_Read, hStdIn_Write;
HANDLE hStdOut_Read, hStdOut_Write;
SECURITY_ATTRIBUTES sAttr;
STARTUPINFOA StartInf;
PROCESS_INFORMATION procInf;
DWORD dwBytesToWrite,dwBytesReadFrom;
sAttr.nLength = sizeof(sAttr);
sAttr.bInheritHandle = TRUE;
sAttr.lpSecurityDescriptor = NULL;
CreatePipe(&hStdIn_Read,&hStdIn_Write,&sAttr,0);
CreatePipe(&hStdOut_Read,&hStdOut_Write,&sAttr,0);
//SetHandleInformation(hStdIn_Read, HANDLE_FLAG_INHERIT, 0);
//SetHandleInformation(hStdIn_Write, HANDLE_FLAG_INHERIT, 0);
memset(&StartInf,0, sizeof(StartInf));
memset(&procInf,0,sizeof(procInf));
StartInf.cb = sizeof(StartInf);
StartInf.dwFlags = STARTF_USESTDHANDLES;
StartInf.hStdError = hStdOut_Write;
StartInf.hStdOutput = hStdOut_Write;
StartInf.hStdInput = hStdIn_Read;
WriteFile(hStdIn_Write,Cmd,sizeof(Cmd),&dwBytesToWrite,NULL);
if(!CreateProcessA(NULL,"cmd.exe",NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW ,NULL,NULL,&StartInf,&procInf))
{
MessageBoxA(m_hWnd, "Can't Create Process","Error",MB_OK | MB_ICONERROR);
}
WriteFile(hStdIn_Write,Cmd,sizeof(Cmd),&dwBytesToWrite,NULL);
BOOL bSUCCESS =TRUE;
Sleep(100);
while(bSUCCESS)
{
BOOL bResult = ReadFile(hStdOut_Read,Buff,70,&dwBytesReadFrom,NULL);
if(!bResult)
{
break;
}
Buff[dwBytesReadFrom]=0;
str+= Buff;
bSUCCESS = dwBytesReadFrom!=0;
}
m_Disp = str;
UpdateData(FALSE);
CloseHandle(hStdIn_Read);
CloseHandle(hStdIn_Write);
CloseHandle(hStdOut_Read);
CloseHandle(hStdOut_Write);
}
In above code, in debugging mode the first calls to ReadFile function returns
true data but last call of it blocks, because there is no enough data to read.
Here is my Question:
How can I avoid the blocking mode or get the exact number of bytes for reading?
Regards!
You PROBABLY want to use the PeekNamedPipe function, which allows you to interrogate a pipe to see how much data there is available at any given time. If the lpBuffer is NULL then no data is being read.

how to get linux command output string and output status in c++

I want to get a Linux command's output string as well as command output status in a C++ program. I am executing Linux commands in my application.
for example:
Command:
rmdir abcd
Command output string:
rmdir: failed to remove `abcd': No such file or directory
Command Status:
1 (Which means command has been failed)
I tried using Linux function system() which gives the output status, and function popen() which gives me output string of a command, but neither function gives me both
the output string and output status of a Linux command.
The output string is in standard output or standard error descriptor (1 or 2, respectively).
You have to redirect these streams (take a look at dup and dup2 function) to a place, where you can read them (for example - a POSIX pipe).
In C I'd do something like this:
int pd[2];
int retValue;
char buffer[MAXBUF] = {0};
pipe(pd);
dup2(pd[1],1);
retValue = system("your command");
read(pd[0], buffer, MAXBUF);
Now, you have (a part of) your output in buffer and the return code in retValue.
Alternatively, you can use a function from exec (i.e. execve) and get the return value with wait or waitpid.
Update: this will redirect only standard output. To redirect standard error, use dup2(pd[1],1).
The simplest solution is to use system, and to redirect standard out and standard error to a temporarly file, which you can delete later.
Unfortunately there's no easy and simple way in C on Linux to do this. Here's an example how to read/write stdout/stderr/stdin of child process correctly.
And when you want to receive exit code you have to use waitpid (complete example is provided on the bottom of the provided page):
endID = waitpid(childID, &status, WNOHANG|WUNTRACED);
Now you just have to join those two together :)
There's also a great free book named Advanced Linux Programming (ALP) containing detailed information about these kinds of problem available here.
Building on Piotr Zierhoffer answer above, here's a function that does just that, and also restores stdout and stderr their original state.
// Execute command <cmd>, put its output (stdout and stderr) in <output>,
// and return its status
int exec_command(string& cmd, string& output) {
// Save original stdout and stderr to enable restoring
int org_stdout = dup(1);
int org_stderr = dup(2);
int pd[2];
pipe(pd);
// Make the read-end of the pipe non blocking, so if the command being
// executed has no output the read() call won't get stuck
int flags = fcntl(pd[0], F_GETFL);
flags |= O_NONBLOCK;
if(fcntl(pd[0], F_SETFL, flags) == -1) {
throw string("fcntl() failed");
}
// Redirect stdout and stderr to the write-end of the pipe
dup2(pd[1], 1);
dup2(pd[1], 2);
int status = system(cmd.c_str());
int buf_size = 1000;
char buf[buf_size];
// Read from read-end of the pipe
long num_bytes = read(pd[0], buf, buf_size);
if(num_bytes > 0) {
output.clear();
output.append(buf, num_bytes);
}
// Restore stdout and stderr and release the org* descriptors
dup2(org_stdout, 1);
dup2(org_stderr, 2);
close(org_stdout);
close(org_stderr);
return status;
}
you can use popen system call, it will redirect output to a file and from file you can redirect output to a string. like :
char buffer[MAXBUF] = {0};
FILE *fd = popen("openssl version -v", "r");
if (NULL == fd)
{
printf("Error in popen");
return;
}
fread(buffer, MAXBUF, 1, fd);
printf("%s",buffer);
pclose(fd);
For more information read man page for popen.

Executing dos commands with Borland C++ and saving output

New to C++.
I have been looking most of the afternoon, does anyone know a simple way to execute DOS commands and save to a variable for a windows forms application?
You can use system("dir"); . This will bring up the command prompt and run the dir command.
Alternatively you can use WinExec.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687393(v=vs.85).aspx
You can make the command to redirect to a text file, and read off of it.
bool execDosCommand(char *command, AnsiString &output)
{
SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa,sizeof(SECURITY_ATTRIBUTES));
sa.nLength=sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle=true;
sa.lpSecurityDescriptor=NULL;
HANDLE ReadPipeHandle;
HANDLE WritePipeHandle; // not used here
if(!CreatePipe(&ReadPipeHandle, &WritePipeHandle, &sa, 0))
return false;
STARTUPINFOA si;
ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb=sizeof(STARTUPINFO);
si.dwFlags=STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
si.wShowWindow=SW_HIDE;
si.hStdOutput=WritePipeHandle;
si.hStdError=WritePipeHandle;
PROCESS_INFORMATION pi;
ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));
text cmd;
cmd.print("/c %s", command);
char pathbuf[MAX_PATH];
_searchenv("CMD.EXE", "PATH", pathbuf);
if(!CreateProcessA(pathbuf, cmd.t_str(), NULL, NULL, true, 0, NULL, NULL, &si, &pi))
return false;
char Data[1024];
for (;;)
{
DWORD BytesRead;
DWORD TotalBytes;
DWORD BytesLeft;
if(!PeekNamedPipe(ReadPipeHandle,Data,sizeof(Data),&BytesRead, &TotalBytes,&BytesLeft)) return false;
if(BytesRead)
{
if(!ReadFile(ReadPipeHandle,Data,sizeof(Data)-1,&BytesRead,NULL))
return false;
Data[BytesRead]='\0';
output += Data;
}
else
{
if(WaitForSingleObject(pi.hProcess,0)==WAIT_OBJECT_0)
break;
}
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(ReadPipeHandle);
CloseHandle(WritePipeHandle);
return true;
}
for example: execDosCommand("dir C:\", output);
as roymustang mentioned, you can use the system command to execute another command from the system. This could be a batch script for example that pipes the output of the command into a text file. You can then read the text file to actually get the information.
The Problem you have with "returning" the command output is, how does the command output look like? In what data structure would you store it? Most of the time you'll get a bunch of unformatted text, which can't be parsed to easily so there is no real generic way to return the output of an application or script into a C++ data structure.
You might as well want to take a look here:
http://docwiki.embarcadero.com/RADStudio/en/System,_wsystem
Like described above I don't believe there is a way to return the output of an application call to your program, at least none that I ever heard about.
Greets,
Florian