代码之家  ›  专栏  ›  技术社区  ›  Vicky

为什么rundll32进程会在Windows7上提前退出?

  •  3
  • Vicky  · 技术社区  · 15 年前

    在Windows XP和Vista上,我可以运行以下代码:

    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在用户关闭modem控制面板窗口之前不会返回。

    在Windows7上,相同的代码waitForSingleObject直接返回(返回代码为0,表示该对象表示请求的状态)。

    类似地,如果我把它放到命令行,在xp和vista上我可以运行

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

    在控制面板窗口关闭之前,它不会将控件返回到命令提示符,但在Windows7上它会立即返回。

    这是rundll32中的更改吗?我知道ms在windows7foruac中对rundll32做了一些更改,从这些实验来看,其中一个更改可能涉及生成一个额外的进程来显示窗口,并允许原始进程退出。唯一让我认为可能不是这样的情况是,使用显示进程的创建和销毁的process explorer,除了被调用的rundll32进程本身之外,我看不到任何额外的创建。

    我还有别的办法解决这个问题吗?我只是不希望在控制面板窗口关闭之前函数返回。

    1 回复  |  直到 15 年前
        1
  •  3
  •   Vicky    15 年前

    万一其他人也遇到同样的问题:我终于在微软技术支持部门的帮助下解决了这个问题。

    他们能够确认原始rundll32进程仍在运行(它没有生成新的进程),但无论出于什么原因,他们不知道答案,waitforsingleobject()将立即返回该进程。

    解决方法是使用cplapplet以不同的方式触发控制面板窗口,如下例所示: http://support.microsoft.com/kb/232536

    然而,由于32位调制解调器控制面板在64位窗口中不工作(它显示,但“添加”按钮没有效果),这个问题更加复杂。我已经在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
    
    推荐文章