J'ai une situation où je démarre un processus dans mon code afin de configurer une chaîne IPC. Le processus que je démarre est une application MFC sans support CLR. L'application à partir de laquelle je commence ce processus est un module C # dans une application WPF (pensée que je ne pense pas que cela est consécutif à mon problème). Cela fonctionne avec une version de l'application qui prend en charge CLR et fonctionne sur chaque ordinateur, à l'exception de la cible de déploiement, un ordinateur tactile avec Windows 7. Mais pour une raison quelconque, lorsque je l'essaie avec ce scénario exact, l'objet de processus jamais résout une poignée de fenêtre principale ( Si cela aide, voici mon code. p> processus.mainwindowhandle code>). Y a-t-il une autre méthode (peut-être même pinvoke) de faire cela? Est-ce une chose de sécurité? Je suis celui qui regarde le processus. La poignée de la fenêtre principale du processus existe. Je ne vois pas ce qui pourrait être faux.
_applicationProcess = new Process();
_applicationProcess.StartInfo.FileName = _strProcessPath;
_applicationProcess.StartInfo.Arguments = _strProcessArguments;
_applicationProcess.Start();
long nTicks = Environment.TickCount;
if (_applicationProcess.WaitForInputIdle(1 /*minute(s)*/ * 60000))
{
try
{
do
{
// Don't let total processing take more than 1 minute(s).
if (Environment.TickCount > nTicks + 1 /*minute(s)*/ * 60000)
throw new ApplicationException("MFCApplication.Startup failed! The main window handle is zero!");
_applicationProcess.Refresh();
}
while (_applicationProcess.MainWindowHandle.ToInt32() == 0);
_applicationHandle = new IntPtr(_applicationProcess.MainWindowHandle.ToInt32());
}
catch (Exception ex)
{
//Do some stuff...
throw;
}
}
else
{
// Do exception handling.
}
4 Réponses :
Mon habitude consiste à appeler Enumwindows dans une boucle combinée à GetWindowTheadProcessid pour trouver la poignée de la fenêtre.
C Code, adapt to your language DWORD TargetHWND; //... while (EnumWindows(EnumWndProc, (LPARAM)(DWORD)pid)) { Sleep(100); } //... BOOL EnumWndProc(HWND hWnd, LPARAM lParam) { DWORD pid = (DWORD)-1; GetWindowThreadProcessId(hWnd, &pid); if (pid == (DWORD)lParam) { TargetHWND = hWnd; return FALSE; } return TRUE; }
Comment cela m'aide-t-il exactement? J'essaie d'obtenir une poignée de fenêtre d'un autre processus. Pouvez-vous me fournir un code?
Donc, fondamentalement, cela obtient toutes les fenêtres de l'ID de processus donné, intéressant.
Je ne sais pas pourquoi cela pourrait être différent, mais après avoir créé le processus, essayez de faire:
Process[] allProcesses = Process.GetProcessesByName("YourWindowTitle");
C'est différent, mais de la manière opposée. Obtenir un processus de cette façon, vous n'avez pas de confiance enbout et vous ne pouvez donc rien faire de rien, et certainement pas sa poignée. Ce n'est que lorsque vous démarrez un processus, pouvez-vous interagir avec elle dans un sens significatif.
La valeur que vous sortez du processus.MainWindowhandle est malheureusement une supposition. Il n'y a pas de fonction API disponible pour un programme qui le permet de dire Windows "Ceci est ma fenêtre principale". La règle qu'elle utilise est documentée, c'est la première fenêtre créée par un processus lorsqu'il est démarré. Cela provoque des problèmes si cette première fenêtre est, disons, une fenêtre de connexion ou un écran éclaboussure. P>
Pas grand chose que vous pouvez faire à ce sujet, vous devez en savoir plus sur la manière dont le programme se comporte pour trouver que la fenêtre principale réelle em>. Enumérant Windows avec EnumthreadWindows () pourrait vous aider à trouver, tant que la première fenêtre a été créée sur le même fil que la fenêtre principale. Un Enumwindows plus élaboré () sera nécessaire si ce n'est pas le cas. P>
Pour obtenir Si j'exécute du code ci-dessous dans ma fenêtre principale WPF sans réglage mainwindowhandle code> au moyen de votre processus, assurez-vous que votre application WPF est affichée dans la barre des tâches, c'est-à-dire
showintaskbar = "vrai" code> et définir
Application.Currrent.MainWindow code> Propriété à la fenêtre que vous souhaitez définir comme fenêtre principale.
showintaskbar = "vrai" Code> J'ai toujours 0 en tant que
Mainwindowhandle code> car ma fenêtre WPF était en plein écran et non affichée dans la barre des tâches. P>
Application.Current.MainWindow = this;
var Query = System.Diagnostics.Process.GetProcessesByName("ProcessName");
if (Query.Any())
{
Query.FirstOrDefault().Refresh();
MessageBox.Show(Query.FirstOrDefault().MainWindowHandle.ToInt32().ToString());
}
Avez-vous fatigué avec
waitforinputidle code> comme suggéré par les documents MSDN? Il est également préférable d'utiliser
lancer code> au lieu de
lancer ex code>, car vous perdrez des informations de trace de pile avec
jette ex code> (
jette ex < / code> redémarre le lancer d'exception et donc la trace de la pile).
@jordan je vois votre édition. Vous devez inclure @Asername dans vos commentaires afin que l'autre utilisateur que vous répondiez est notifié.
@jordan dans votre fusion \ tandis que la boucle, je pense que vous confondez des tiques avec des millisecondes. Une tique est un 100 nanosecondes. Il est probablement plus simple d'utiliser un
chronomètre code> pour cela.
@jordan, il vaut probablement la peine d'être envisagé de mettre un
thread.sleep code> dans votre boucle pour accélérer votre
Actualiser les appels code>.
@chibity Nope Aucun de cela fonctionne. Et je ne pensais pas que le @ était nécessaire depuis que vous étiez le seul commentateur.
Est-ce une version 64 bits de Windows?
J'ai une théorie, je cache la fenêtre principale peu de temps après sa charge. L'acte de cacher une fenêtre la modifier de l'état de la fenêtre principale? Juste une pensée. @Hans oui c'est.
Connexes: Stackoverflow.com/Questtions/3276439/...
@chibacité, pour l'enregistrement, selon la documentation
Environnement.TickCount Code> est en millisecondes pas de ticks. Nom confus, mais les tiques étaient des millisecondes. Je fais comme
chronomètre code> cependant.
@Jordon I Stand corrigé,
Environnement.TickCount Code> est en effet en millisecondes et non des tiques. C'est déroutant. À votre santé.