为什么 RunDLL32 进程在 Windows 7 上提前退出?

发布于 2024-08-24 03:22:08 字数 1214 浏览 3 评论 0原文

在 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 才会返回。

在 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 进程本身之外还创建了任何其他内容。

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

On Windows XP and Vista, I can run this code:

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);
}

and it operates as I would expect, i.e. the WaitForSingleObject does not return until the Modem Control Panel window has been closed by the user.

On Windows 7, the same code, WaitForSingleObject returns straight away (with a return code of 0 indicating that the object signalled the requested state).

Similarly, if I take it to the command line, on XP and Vista I can run

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

and it does not return control to the command prompt until the Control Panel window is closed, but on Windows 7 it returns immediately.

Is this a change in RunDll32? I know MS made some changes to RunDll32 in Windows 7 for UAC, and it looks from these experiments as though one of those changes might have involved spawning an additional process to display the window, and allowing the originating process to exit. The only thing that makes me think this might not be the case is that using a process explorer that shows the creation and destruction of processes, I do not see anything additional being created beyond the called rundll32 process itself.

Any other way I can solve this? I just don't want the function to return until the control panel window is closed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

话少情深 2024-08-31 03:22:08

如果其他人遇到同样的问题:我终于在 Microsoft 技术支持的帮助下解决了这个问题。

他们能够确认原始 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

In case anyone else stumbles on the same problem: I finally worked around this with some help from Microsoft Tech Support.

They were able to confirm that the original RunDll32 process is still running (it hasn't spawned a new process) but for whatever reason that they don't know the answer to, WaitForSingleObject() is returning immediately on that process.

The workaround is to fire off the control panel window differently, using CPLApplet as in this example: http://support.microsoft.com/kb/232536

However the issue is complicated further by the fact that the 32-bit modem control panel doesn't work in 64-bit Windows (it displays but "Add" button has no effect). I was already turning off WOW64 redirection in my RunDLL solution on 64-bit platforms, and that worked fine, but you can't load a 64-bit library in a 32-bit app so I had to spawn a new process to do this.

In summary:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文