2010-03-08 4 views
3

Sous Windows XP et Vista, je peux exécuter ce code:Pourquoi RunDLL32 se termine-t-il tôt sur Windows 7?

STARTUPINFO si; 
PROCESS_INFORMATION pi; 
BOOL bResult = FALSE; 

ZeroMemory(&pi, sizeof(pi)); 

ZeroMemory(&si, sizeof(si)); 

si.cb = sizeof(STARTUPINFO); 
si.dwFlags = STARTF_USESHOWWINDOW; 
si.wShowWindow = SW_SHOW; 

bResult = CreateProcess(NULL, 
         "rundll32.exe shell32.dll,Control_RunDLL modem.cpl", 
         NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, 
         &si, &pi); 

if (bResult) 
{ 
    WaitForSingleObject(pi.hProcess, INFINITE); 
    CloseHandle(pi.hProcess); 
    CloseHandle(pi.hThread); 
} 

et il fonctionne comme j'attendre, à savoir la WaitForSingleObject ne retourne pas jusqu'à ce que la fenêtre Panneau de configuration du modem a été fermé par l'utilisateur.

Sur Windows 7, le même code, WaitForSingleObject renvoie tout de suite (avec un code de retour de 0 indiquant que l'objet a signalé l'état demandé).

De même, si je prends à la ligne de commande, sur XP et Vista, je peux courir

start /wait rundll32.exe shell32.dll,Control_RunDLL modem.cpl 

et il ne retourne pas le contrôle à l'invite de commande jusqu'à ce que la fenêtre Panneau de configuration est fermé, mais sous Windows 7 il revient immédiatement.

Est-ce un changement dans RunDll32? Je sais que MS a apporté quelques modifications à RunDll32 dans Windows 7 pour UAC, et il semble de ces expériences comme si l'un de ces changements impliquait un processus supplémentaire pour afficher la fenêtre et permettre au processus d'origine de se terminer. La seule chose qui me fait penser que ce n'est peut-être pas le cas est qu'en utilisant un explorateur de processus qui montre la création et la destruction de processus, je ne vois rien de supplémentaire créé au-delà du processus appelé rundll32 lui-même.

Toute autre façon que je peux résoudre ce problème? Je ne veux pas que la fonction revienne tant que la fenêtre du panneau de contrôle n'est pas fermée.

+0

Essayez la fonction "système" et de voir ce qui se passe. –

+0

@Jive Dadson: Merci pour la suggestion. Malheureusement, l'utilisation de "système" a le même problème - sur XP et Vista, l'appel aux blocs système jusqu'à la fermeture de la fenêtre du Panneau de configuration, mais sur Windows 7, il revient immédiatement (laissant la fenêtre Control Panl ouverte). Je me suis interrogé sur l'utilisation de CreateProcess() à la place, mais cela renvoie un handle d'instance et je ne peux pas savoir comment attendre (WaitForSingleObject ne fonctionne pas). – Vicky

+0

Désolé, dans mon dernier commentaire, je voulais dire "Je me suis posé la question de l'utilisation de ShellExecute()". – Vicky

Répondre

3

Au cas où quelqu'un d'autre trébucherait sur le même problème: J'ai finalement travaillé autour de cela avec l'aide de Microsoft Tech Support.

Ils ont pu confirmer que le processus RunDll32 d'origine est toujours en cours d'exécution (il n'a pas engendré un nouveau processus) mais pour une raison quelconque dont ils ne connaissent pas la réponse, WaitForSingleObject() retourne immédiatement sur ce processus .

La solution consiste à tirer différemment de la fenêtre du panneau de commande, en utilisant CPlApplet comme dans cet exemple: http://support.microsoft.com/kb/232536

Cependant, la question est encore compliquée par le fait que le panneau de commande du modem 32 bits ne fonctionne pas Windows 64 bits (il s'affiche mais le bouton "Ajouter" n'a aucun effet). Je désactivais déjà la redirection WOW64 dans ma solution RunDLL sur les plates-formes 64 bits, et cela a fonctionné correctement, mais vous ne pouvez pas charger une bibliothèque 64 bits dans une application 32 bits. J'ai donc dû lancer un nouveau processus pour cela .

En résumé:

Win 7 64 bit: call CPLApplet via CreateProcess in 64-bit executable 
Win 7 32 bit: call CPLApplet within my installer 
XP/Vista 64 bit: turn off WOW64 redirection, use RunDll32 
XP/Vista 32 bit: use RunDll32