2010-03-08 76 views
3

在Windows XP和Vista中,我可以運行此代碼:爲什麼RunDLL32進程在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); 
} 

它的運作,因爲我所期望的,即WaitForSingleObject的不返回,直到調制解調器控制面板窗口已經被用戶關閉。

在Windows 7上,相同的代碼WaitForSingleObject直接返回(返回代碼0表示對象用信號通知請求的狀態)。

同樣,如果我把它的命令行,在XP和Vista中,我可以運行

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

,直到控制面板窗口關閉它不返回控制到命令提示符,但在Windows 7它立即返回。

這是RunDll32的變化嗎?我知道MS在Windows 7中對UAC中的RunDll32做了一些更改,從這些實驗中可以看出,其中一項更改可能會產生額外的進程來顯示窗口,並允許初始化進程退出。唯一讓我想到這可能不是這樣的情況是,使用顯示進程創建和銷燬的進程資源管理器,除了被稱爲rundll32進程本身之外,我沒有看到任何額外的創建。

我能解決這個問題的其他方法嗎?我只是不希望函數返回,直到控制面板窗口關閉。

+0

嘗試使用功能 「系統」,看看會發生什麼。 – 2010-03-08 18:11:32

+0

@Jive Dadson:謝謝你的建議。不幸的是使用「系統」有同樣的問題 - 在XP和Vista上調用系統塊直到控制面板窗口關閉,但在Windows 7上它立即返回(使控制面板窗口保持打開狀態)。 我想知道如何使用CreateProcess(),而不是返回一個實例句柄,我不能解決如何等待(WaitForSingleObject不起作用)。 – Vicky 2010-03-08 21:02:45

+0

對不起,在我最近的評論中,我的意思是「我想知道如何使用ShellExecute()」。 – Vicky 2010-03-08 21:05:27

回答

3

如果有人在同一個問題上磕磕絆絆:我終於在Microsoft Tech Support的幫助下解決了這個問題。

他們能夠確認原始的RunDll32進程仍在運行(它沒有產生新的進程),但無論出於什麼原因,他們不知道答案,WaitForSingleObject()立即返回該進程。

的解決方法是在控制面板窗口不同的斷火,使用的CPlApplet如本例:http://support.microsoft.com/kb/232536

然而,問題是由事實進一步複雜化的是,32位調制解調器控制面板不工作, 64位Windows(它顯示但「添加」按鈕不起作用)。我已經在64位平臺的RunDLL解決方案中關閉了WOW64重定向功能,並且工作正常,但是無法在32位應用程序中加載64位庫,因此我必須生成一個新進程來執行此操作。

總結:

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 
相關問題