2009-12-04 5 views
3

Supposons que j'exécute une application, après quelque temps cette application sera fermée par l'utilisateur. Est-il possible de savoir quand le programme se termine? Puis-je obtenir son identifiant de processus lorsque je lance cette application?Exécuter un programme Windows et détecter quand il se termine avec C++

+0

De quel OS parlez-vous? Comment gérez-vous le processus? Est-ce votre programme exécutant un autre processus via exec, fork? –

+0

Windows, je veux exécuter cette application dans mon application C++. – EBAG

Répondre

9

C'est une citation de here:

#include <windows.h> 
#include <stdio.h> 
#include <tchar.h> 
#include <conio.h> 

void _tmain(int argc, TCHAR *argv[]) 
{ 
STARTUPINFO si; 
PROCESS_INFORMATION pi; 
STARTUPINFO sj; 
PROCESS_INFORMATION pj; 

ZeroMemory(&si, sizeof(si)); 
si.cb = sizeof(si); 
ZeroMemory(&pi, sizeof(pi)); 

ZeroMemory(&sj, sizeof(sj)); 
sj.cb = sizeof(sj); 
ZeroMemory(&pj, sizeof(pj)); 

// Start the child process p1.exe. Make sure p1.exe is in the 
// same folder as current application. Otherwise write the full path in first argument. 
if(!CreateProcess(L".\\p1.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &sj, &pj)) 
{ 
printf("Hello CreateProcess failed (%d)\n", GetLastError()); 
getch(); 
return; 
} 

// Start child process p2.exe. Make sure p2.exe is in the 
// same folder as current application. Otherwise write the full path in first argument. 
if(!CreateProcess(L".\\p2.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) 
{ 
printf("CreateProcess2 failed (%d)\n", GetLastError()); 
getch(); 
return; 
} 

// Wait until child processes exit. 
WaitForSingleObject(pi.hProcess, INFINITE); 
WaitForSingleObject(pj.hProcess, INFINITE); 

// Close process and thread handles. 
CloseHandle(pi.hProcess); 
CloseHandle(pi.hThread); 
CloseHandle(pj.hProcess); 
CloseHandle(pj.hThread); 
getch(); 
} 
+0

Nettoyer. Merci. Existe-t-il un moyen de suivre le processeur, l'utilisation des E/S et l'état du processus créé? –

+0

Jetez un oeil à cette question http://stackoverflow.com/questions/2475341/monitoring-cpu-and-disk-utilization-of-a-single-program –

0

Dans une recherche rapide à Google, je trouve ces deux méthodes de msdn qui peuvent être utiles:

CreateProcess et GetExitCodeProcess. Cela suppose que vous créez un processus dans votre application.

Vous pouvez effectuer une méthode d'interrogation en vérifiant l'état du processus créé. Je n'ai jamais fait ce genre de chose, mais cela me semble une approche très étrange.

2

CreateProcess et WaitForSingleObject est le moyen simple de réaliser ceci, vous obtenez la poignée de processus de CreateProcess, puis attendez avec OSV Ere, sans oublier de fermer toutes les poignées tu utilises. Mais attendez ... il y a un problème. Le problème est que - pour les processus GUI - les deux processus peuvent se bloquer. Pourquoi?

Le problème vient du fait que votre application possède une fenêtre mais ne pompe pas les messages. Si l'application spawned appelle SendMessage avec l'une des cibles de diffusion (HWND_BROADCAST ou HWND_TOPMOST), SendMessage ne retournera pas à la nouvelle application tant que toutes les applications n'auront pas traité le message, mais que votre application ne pourra pas gérer le message car elle n'est pas t messages de pompage .... de sorte que la nouvelle application se bloque, de sorte que votre attente ne réussit jamais .... DEADLOCK. Si vous avez un contrôle absolu sur l'application générée, il existe des mesures que vous pouvez prendre, comme l'utilisation de SendMessageTimeout plutôt que SendMessage (par exemple pour les initiations DDE, si quelqu'un l'utilise encore). Mais il existe des situations qui provoquent des diffusions SendMessage implicites sur lesquelles vous n'avez aucun contrôle, telles que l'utilisation de l'API SetSysColors par exemple. Les seuls moyens sûrs autour de ceci sont (a) diviser l'attente dans un fil séparé, (b) utiliser un délai d'attente sur le Wait et utiliser PeekMessage dans votre boucle d'attente pour s'assurer que vous pomper des messages, (c) utiliser l'API MsgWaitForMultipleObjects au lieu de WaitForSingleObject.

1

Une autre approche qui offre encore plus de contrôle consiste à utiliser l'API Win32 Job, voir CreateJobObject() et AssignProcessToJobObject(). Cela vous permettrait de surveiller votre processus engendré de manière asynchrone en utilisant un port d'achèvement d'E/S en utilisant SetInformationJobObject() il est plus complexe et probablement plus que nécessaire, mais il vous donne beaucoup plus de contrôle sur les processus générés.

1

Je voudrais mentionner que vous n'avez pas réellement créer un processus, afin d'être en mesure d'attendre sa fin. En gros, si vous connaissez son PID, vous pouvez le faire:

HANDLE h = OpenProcess(SYNCHRONIZE, TRUE, pid); 
WaitForSingleObject(h, INFINITE); 

Exemple complet: https://gist.github.com/rdp/6b5fc8993089ee12b44d (laisser un commentaire ici si vous souhaitez une version compilée à disposition).

0

Au moins sous Windows, il existe une fonctionnalité de bibliothèque d'exécution C (sous-utilisée?) Disponible pour cela. Voir C Run-Time Library Reference > Process and Environment Control.

Plus précisément, vous avez _spawnlp(_P_WAIT, cmdname, arg0, ..., argn, 0) ("spawn avec l'argument l ist, en utilisant variable p ath pour localiser le fichier") qui recherche nomcmd dans PATH et dans le répertoire courant. Notez que "Après argn, il doit y avoir un pointeur NULL pour marquer la fin de la liste d'arguments."

E.g.

#include <stdio.h> 
#include <process.h> 
int main() { 
    puts("waiting"); 
    _spawnlp(_P_WAIT, "mspaint.exe", "mspaint.exe", 0); 
    puts("returned"); 
} 
Questions connexes