9
votes

Comment déterminer quand le processus engendré est prêt? (Utilisation de CreateProcess () et Findwindow ())

Cela devrait être facile: je crée un programme qui reproche un processus à l'aide de la fonction Win32 CreateProcess () CODE>. Une fois ce processus chargé, je trouve sa fenêtre à l'aide de Findwindow CODE> et envoyez des messages IT à l'aide de sendMessage () code>. La question est, Comment puis-je savoir quand cette fenêtre est prête à accepter des messages? Strong>

Considérez les suivants: P>

HWND wnd;

BOOL Start()
{
  // Spawn the process
  if (! CreateProcess(...))
    return FALSE;

  // Find the process's window (class and name already known)
  wnd = FindWindow(MY_WINDOW_CLASS, MY_WINDOW_NAME);

  // Always returns FALSE because window has not yet been created.
  return (wnd != NULL);
}


0 commentaires

4 Réponses :


1
votes

Si le processus que vous démarrez est celui que vous pouvez modifier, demandez-lui de renvoyer un message au parent lorsqu'il est prêt. Vous pouvez transmettre le HWND du parent en tant que paramètre de ligne de commande ou utiliser Findwindow si vous pouvez garantir que le parent sera unique.


0 commentaires

9
votes

(éditer): Utilisateur IInpectable a souligné les problèmes avec waitforinPutidle () et suggéré CBT Crows à la place.

(...) Fonction de rappel utilisé avec le Setwindowshookex fonction. Le système appelle cette fonction avant d'activer, créer, (...) une fenêtre; (... beaucoup d'autres choses).

En outre, la CBT est courte pour une formation basée sur ordinateur, pour une raison quelconque.

(vieux, méfiez-vous, voir Commentaires.) Vous recherchez WaitForinPutiveDle () . Citation:

Quand un processus de parent crée un enfant processus, la fonction CreateProcess retourne sans attendre l'enfant processus pour terminer son initialisation. Avant d'essayer de communiquer avec le processus enfant, le processus parent peut Utilisez la fonction WaitForinPutiveDle pour déterminer quand l'enfant L'initialisation est terminée.


6 commentaires

L'API Windows est si énorme personne ne peut s'attendre à tout savoir. J'ai appris quelque chose de nouveau aujourd'hui, merci.


C'est un bug qui attend pour arriver. WaitForinPutiveDle a été inventé pour répondre aux exigences de DDE. L'utiliser pour autre chose va échouer, de la manière la plus subtile. Lecture pertinente: waitforinPutidle doit vraiment être appelé waitforProcessStartututupcompte et < Un href = "https://blogs.msdn.microsoft.com/oldnewthing/20100326-00/?p=14483" rel = "Nofollow Noreferrer"> WaitForinPutiveDle attend n'importe quel fil, ce qui pourrait ne pas être le fil que vous vous souciez de < / a>.


Merci d'avoir apporté ces deux articles de la vieille nouvelle chose à mon attention; L'histoire, comme toujours, est plus compliquée que cela ne paraîtra d'abord, et ce blog est un trésor. Cependant, je suis en désaccord que waitforinputitidle () ne peut pas être utilisé dans ce contexte; La méthode retourne une fois que toutes les threads ont été inactifs à la fois pour la première fois (la plupart du temps suffisamment bon pour le Q), et la manutention Findwindow () == null reste nécessaire même lorsque vous utilisez une synchronisation explicite à l'aide d'un événement nommé (ou similaire). Un peu malheureusement, je ne connais pas non plus de meilleure méthode, à l'exception de la boucle en enfer.


@GIMPF: "La méthode revient une fois que toutes les threads ont été inactifs à la fois pour la première fois" - ce n'est pas le cas de l'article de blog. La fonction renvoie dès que Un thread dans le processus cible a atteint un point, où il peut traiter des messages. Cela pourrait être le fil d'affichage d'un écran éclabousseur ou d'un fil de travail de fond. WaitForinPutiveDle n'est certainement pas assez bon pour ce scénario particulier. Un crochet CBT serait une solution propre à la question posée. Aucun interrogation requis; Le rappel est appelé, quand une fenêtre est créée.


@InInspectable merci pour vos corrections de patients. J'ai relu, et oui, c'est n'importe quel fil , pas tout . Je ne savais pas sur le crochet CBT, celui-ci semble être une solution réalisable sans modification d'application cible. J'ajoute un lien à cela.


Au lieu d'utiliser SetWindowshookex () avec un wh_cbt crochet, vous pouvez également utiliser setwineVenthook () pour gérer event_object_create event_Object_show événements. Même la documentation de Hook suggère en utilisant Winevents au lieu de crochets chaque fois que possible.



2
votes

Avez-vous regardé waitforinputidle ?


1 commentaires

J'ai . Ce n'est certainement pas ce que vous voudriez utiliser.



1
votes

Je suppose que le code source des deux processus est sous votre contrôle.

  • Vous pouvez laisser le deuxième processus poster un message au premier lorsqu'il est prêt, si la seconde connaît les détails nécessaires de la première fenêtre de message de processus.
  • Ou vous pouvez attendre dans le premier processus d'un objet de synchronisation nommé convenu, comme l'événement ou le mutex, étant défini à partir du deuxième processus.

0 commentaires