INFO:Windows Rundll 和 Rundll32 接口

本文来自MSDN,原文地址:http://support.microsoft.com/kb/164787/zh-cn

Microsoft Windows 95、Windows 98 和 Windows Millennium Edition (Me) 包含两个名为 Rundll.exe 和 Rundll32.exe 的命令行实用程序,通过这两个程序可调用从 16 位或 32 位 DLL 导出的函数。但是,使用 Rundll 和 Rundll32 程序并不能调用从任何 DLL 导出的任何函数。例如,不能使用这两个实用程序调用从系统 DLL 中导出的 Win32 API(应用程序编程接口)调用。这两个程序只允许您调用从 DLL 导出的、明确编写为供这两个程序调用的函数。本文详细介绍了 Rundll 和 Rundll32 程序在上面列出的 Windows 操作系统中的用法。

MIcrosoft Windows NT 4.0、Windows 2000 和 Windows XP 在发行时只附带 Rundll32。这些平台都不提供对 Rundll(Win16 实用程序)的支持。

Rundll 和 Rundll32 实用程序最初设计为仅供 Microsoft 内部使用。但是它们提供的功能非常通用,因此现在可供在一般情况下使用。请注意,Windows NT 4.0 发行时只随附 Rundll32 实用程序,并且只支持 Rundll32。

 

Rundll 与 Rundll32 之比较 Rundll 加载并运行 16 位 DLL,而 Rundll32 加载并运行 32 位 DLL。如果您向 Rundl...Rundll 与 Rundll32 之比较Rundll 加载并运行 16 位 DLL,而 Rundll32 加载并运行 32 位 DLL。如果您向 Rundll 或 Rundll32 传递了错误的 DLL 类型,它可能无法运行,并且不显示任何错误信息。  Rundll 命令行Rundll 的命令行如下所示: RUNDLL.EXE <dllname>,<entrypoint> <optional arguments> 示例如下: RUNDLL.EXE SETUPX.DLL,InstallHinfSection 132 C:\WINDOWS\INF\SHELL.INF 在上面的命令行中,有三个问题需要特别注意:Rundll 或 Rundll32 在标准位置搜索给定的 DLL 文件名(请参见有关 LoadLibrary() 函数的文档了解详细信息)。建议您提供 DLL 的完整路径以确保找到所需的 DLL。为获得最佳结果,请使用短文件名而不是长文件名,以确保不会出现非法字符。请特别注意,这意味着“C:\Program Files”文件夹中的 DLL 应转换为短名称。<dllname> 不能包含任何空格、逗号或引号。这是 Rundll 命令行分析器的局限。在上面的命令行中,<dllname> 和 <entrypont> 函数名称之间的逗号 (,) 极为重要。如果缺少这个逗号分隔符,Rundll 或 Rundll32 将失败,而且不显示任何错误。另外,在 <dllname>、逗号和 <entrypoint> 函数之间不能有任何空格。  Rundll 的工作方式Rundll 执行以下步骤:它分析命令行。它通过 LoadLibrary() 加载指定的 DLL。它通过 GetProcAddress() 获取 <entrypoint> 函数的地址。它调用 <entrypoint> 函数,并传递作为 <optional arguments> 的命令行尾。当 <entrypoint> 函数返回时,Rundll.exe 将卸载 DLL 并退出。  如何编写 DLL在您的 DLL 中,使用以下原型编写 <entrypoint> 函数:

16 位 DLL:

void FAR PASCAL __loadds EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow); 32 位 DLL: void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow); 同样,对于 EntryPoint 函数也有三个问题需要注意:很明显,“EntryPoint”名称应该替换为您的入口点函数的实际名称。请注意,Rundll32 的入口点与 32 位 DLL 中的 DllEntryPoint 函数完全无关,后者处理进程和线程的连接/分离通知。Rundll32 的入口点函数必须使用 _stdcall 调用约定定义(CALLBACK 默认情况下使用 _stdcall 属性)。如果缺少 _stdcall 属性,则函数默认使用 _cdecl 调用约定,然后 Rundll32 将在调用该函数后异常终止。由于您必须如上所述使用 _stdcall 调用约定声明该函数,因此如果 DLL 是用 C 语言编写的,Visual C++ 编译器会将该函数实际导出为 _EntryPoint@16;如果 DLL 是用 C++ 语言编写的,则 Visual C++ 编译器将进一步使用名称修饰。所以,请务必在 Rundll 或 Rundll32 的命令行中使用正确导出的名称。如果您想避免使用修饰名称,请使用 .def 文件,并按名称导出入口点函数。在使用 Visual C++ 编译器时,请参考产品文档和以下文章,以了解有关名称修饰的更多信息: 140485(http://support.microsoft.com/kb/140485/ ) 导出 32 位 DLL 中类似 PASCAL 的符号Rundll 入口点的参数如下所示: hwnd - 窗口句柄,它应该用作 DLL 创建的任何窗口的所有者窗口hinst - DLL 的实例句柄 lpszCmdLine - DLL 应分析的 ASCIIZ 命令行nCmdShow - 描述 DLL 的窗口应如何显示 在下面的示例中: RUNDLL.EXE SETUPX.DLL,InstallHinfSection 132 C:\WINDOWS\INF\SHELL.INF Rundll 将调用 Setupx.dll 中的 InstallHinfSection() EntryPoint 函数,并向其传递以下参数: hwnd =(父窗口句柄)hinst = SETUPX.DLL 的 HINSTANCE lpszCmdLine = "132 C:\WINDOWS\INF\SHELL.INF" nCmdShow =(传递给 CreateProcess 的任何 nCmdShow) 请注意,<entrypoint> 函数(在上例中为 InstallHinfSection())必须分析它自己的命令行(上面的 lpszCmdLine 参数),并在必要时使用个别参数。Rundll.exe 最多只分析到传递给它的命令行的可选参数。其余的分析工作则由 <entrypoint> 函数来完成。  有关 Windows 95 和 Windows NT 之间的区别的特别提示在 Windows NT、Windows 2000 和 Windows XP 中,Rundll32.exe 的行为稍有不同,目的是为了适应 UNICODE 命令行。

Windows NT 首先尝试对 <EntryPoint>W 调用 GetProcAddress 以获取其地址。如果找到该入口点,则假定原型为: void CALLBACK EntryPointW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow); 这与 ANSI EntryPoint 相同,只是 lpszCmdLine 参数现在是一个 UNICODE 字符串。

如果没有找到 <EntryPoint>W 入口点,Windows NT 就会对 <entrypoint>A 和 <entrypoint> 调用 GetProcAddress 以获取其地址。如果发现其中任何一个地址,则将其视为 ANSI 入口点,并像在 Windows 95/98/Me 中那样进行处理。因此,如果希望 DLL 在带 ANSI 支持的 Windows 95 中以及带 UNICODE 支持的 Windows NT/2000/XP 中运行,您应该导出以下两个函数:EntryPointW 和 EntryPoint。在 Windows NT/2000/Me 中,通过 UNICODE 命令行调用 EntryPointW 函数;在 Windows 95/98/Me 中,则通过 ANSI 命令行调用 EntryPoint 函数。  

有关 Rundll 的用法的示例,请参考以下有关如何使用 Rundll 命令行实用程序在 Windows 95 中启动“控制面板”小程序的文章: 135068(http://support.microsoft.com/kb/135068/ ) 如何在 Windows 95、98 或 WinNT 中启动“控制面板”小程序
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值