views:

303

answers:

3

I'm trying to write a very simple program to replace an existing executable. It should munge its arguments slightly and exec the original program with the new arguments. It's supposed to be invoked automatically and silently by a third-party library.

It runs fine, but it pops up a console window to show the output of the invoked program. I need that console window to not be there. I do not care about the program's output.

My original attempt was set up as a console application, so I thought I could fix this by writing a new Windows GUI app that did the same thing. But it still pops up the console. I assume that the original command is marked as a console application, and so Windows automatically gives it a console window to run in. I also tried replacing my original call to _exec() with a call to system(), just in case. No help.

Does anyone know how I can make this console window go away?

Here's my code:

int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       char*    lpCmdLine,
                       int       nCmdShow)
{
    char *argString, *executable;
    // argString and executable are retrieved here

    std::vector< std::string > newArgs;
    // newArgs gets set up with the intended arguments here

    char const ** newArgsP = new char const*[newArgs.size() + 1];
    for (unsigned int i = 0; i < newArgs.size(); ++i)
    {
        newArgsP[i] = newArgs[i].c_str();
    }
    newArgsP[newArgs.size()] = NULL;

    int rv = _execv(executable, newArgsP);
    if (rv)
    {
        return -1;
    }
}
A: 

You need to create a non-console application (i.e. a Windows GUI app). If all this app does is some processing of files or whatever, you won't need to have a WinMain, register any windows or have a message loop - just write your code as for a console app. Of course, you won't be able to use printf et al. And when you come to execute it, use the exec() family of functions, not system().

anon
That's what I already tried, that's what I meant by "non-console application". It still seems to pop up the console window for the called application though.
Matthew Exon
Sorry, I misread. If you use exec(), it definitely should not pop up aconsole - see this answer to a slightly different question http://stackoverflow.com/questions/597818/gcc-c-how-to-hide-console-window
anon
But that's not what I'm seeing. If I replace my call to exec with this:newArgsP = new char const*[2];newArgsP[0] = "hello.txt";newArgsP[1] = NULL;_execv("c:\\WINDOWS\\system32\\write.exe", newArgsP);...then wordpad correctly comes up with no console window. But if I let it execute the application it's supposed to, then up comes a console with the standard output of the program. So I'm sure it's something to do with the program that's being invoked, not my program.
Matthew Exon
If the program produces something on standard output, it's a console program. If it is a console program, you can't stop it displaying the console. I think your question would be much clearer if you posted some code in the original question indicating exactly what you are doing.
anon
+1  A: 

Aha, I think I found the answer on MSDN, at least if I'm prepared to use .NET. (I don't think I'm really supposed to, but I'll ignore that for now.)

 System::String^ command = gcnew System::String(executable);
 System::Diagnostics::Process^ myProcess = gcnew Process;
 myProcess->StartInfor->FileName = command;
 myProcess->StartInfo->UseShellExecute = false; //1
 myProcess->StartInfo->CreateNowindow = true;   //2
 myProcess->Start();

It's those two lines marked //1 and //2 that are important. Both need to be present.

I really don't understand what's going on here, but it seems to work.

Matthew Exon
+2  A: 
tyranid