2009-12-21 5 views
3

J'essaye d'écrire un programme très simple pour remplacer un exécutable existant. Il devrait légèrement argumenter ses arguments et exec le programme original avec les nouveaux arguments. Il est supposé être appelé automatiquement et silencieusement par une bibliothèque tierce.Comment cacher la fenêtre de console du sous-processus?

Il fonctionne très bien, mais il affiche une fenêtre de console pour afficher la sortie du programme invoqué. J'ai besoin de cette fenêtre de console pour ne pas être là. Je me fiche de la sortie du programme.

Ma première tentative a été créée comme une application de la console, donc je pensais que je pouvais résoudre ce problème en écrivant une nouvelle application GUI Windows qui a fait la même chose. Mais il apparaît toujours la console. Je suppose que la commande d'origine est marquée comme une application de console, et donc Windows lui donne automatiquement une fenêtre de console pour s'exécuter. J'ai également essayé de remplacer mon appel original à _exec() par un appel à system(), juste au cas. Pas d'aide.

Est-ce que quelqu'un sait comment je peux faire cette fenêtre de console disparaître?

Voici mon 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; 
    } 
} 

Répondre

0

Vous devez créer une application non-console (à savoir une application GUI Windows). Si tout ce que fait cette application est un traitement de fichiers ou autre, vous n'aurez pas besoin d'avoir un WinMain, n'enregistrer aucune fenêtre ou avoir une boucle de message - il suffit d'écrire votre code comme pour une application de console. Bien sûr, vous ne pourrez pas utiliser printf et al. Et quand vous venez de l'exécuter, utilisez la famille de fonctions exec(), pas system().

+0

C'est ce que j'ai déjà essayé, c'est ce que je voulais dire par "application non-console". Il semble toujours apparaître la fenêtre de la console pour l'application appelée. –

+0

Désolé, j'ai mal lu. Si vous utilisez exec(), il ne devrait certainement pas apparaître d'aconsole - voir cette réponse à une question légèrement différente http://stackoverflow.com/questions/597818/gcc-c-how-to-hide-console-window –

+0

ce n'est pas ce que je vois. Si je remplace mon appel à exec avec ceci: newArgsP = new char const * [2]; newArgsP [0] = "hello.txt"; newArgsP [1] = NULL; _execv ("c: \\ WINDOWS \\ system32 \\ write.exe", newArgsP); ... alors le tableau de bord apparaît correctement sans fenêtre de console. Mais si je le laisse exécuter l'application c'est supposé, puis vient une console avec la sortie standard du programme. Donc, je suis sûr que c'est quelque chose à voir avec le programme qui est invoqué, pas mon programme. –

1

Aha, je pense avoir trouvé la réponse sur MSDN, au moins si je suis prêt à utiliser .NET. (Je ne pense pas que je suis vraiment censé, mais j'ignorerons pour l'instant.)

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(); 

Ce sont ces deux lignes marquées // 1 // 2 et qui sont importants. Les deux doivent être présents.

Je ne comprends vraiment pas ce qui se passe ici, mais il semble fonctionner.

+0

Qu'est-ce qui se passe là-bas, est-ce que cela dit à .NET de faire ce que [la solution de tyranid] (http://stackoverflow.com/a/1986893/43452) suggère. – Stobor

4

Utilisez la fonction CreateProcess au lieu de execve. Pour le paramètre dwCreationFlags, passez l'indicateur CREATE_NO_WINDOW. Vous devrez également passer la ligne de commande en tant que chaîne.

par exemple.

 
STARTUPINFO startInfo = {0}; 
PROCESS_INFORMATION procInfo; 
TCHAR cmdline[] = _T("\"path\\to\\app.exe\" \"arg1\" \"arg2\""); 
startInfo.cb = sizeof(startInfo); 
if(CreateProcess(_T("path\\to\\app.exe"), cmdline, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &startInfo, &procInfo)) 
{ 
    CloseHandle(procInfo.hProcess); 
    CloseHandle(procInfo.hThread); 
} 
Questions connexes