如何使用Rundll32执行DLL函数?

32

使用ShellExecute文档作为参考:

我从命令行中运行以下内容:

C:\>RUNDLL32.EXE SHELL32.DLL,ShellExecute handle,"open","C:\Documents and Settings\admin\Desktop\tmp",NULL,NULL,SW_SHOWNORMAL

这会导致异常错误。

我不知道这是什么意思:

HINSTANCE ShellExecute(
  __in_opt  HWND hwnd,
  __in_opt  LPCTSTR lpOperation,
  __in      LPCTSTR lpFile,
  __in_opt  LPCTSTR lpParameters,
  __in_opt  LPCTSTR lpDirectory,
  __in      INT nShowCmd
);

但是在描述中提到了一个句柄(HWND)和一个指向以空字符结尾的字符串的指针(LPCTSTR),这很令人困惑。

任何帮助都将不胜感激。我也想学习更多知识,因此任何参考资料(书籍、网页链接等)也将非常有用!


如果您解释一下您想要实现的目标,那么将会很有帮助,因为可能会有比使用RUNDLL32更好的方法。无论如何,您没有正确地调用RUNDLL32。例如,参数必须用空格分隔(逗号只分隔入口点和DLL),hwnd和nShowCmd需要整数值等。请参阅http://support.microsoft.com/kb/164787获取更多信息。 - Alek Davis
我是一个好奇的头脑。我阅读了这篇文章:http://vlaurie.com/computers2/Articles/rundll32.htm。然后我开始查看不同的dll文件,并发现了这个:http://msdn.microsoft.com/en-us/library/bb776426%28v=VS.85%29.aspx。我开始查看各个函数,并想知道它们是否可以与rundll32.exe一起使用。我选择了ShellExecute函数,因为我知道它的作用(打开文件夹)。我主要是想学习这些东西在MSDN中是如何工作的。我甚至不知道它是C、C++、C#等哪种语言。 - mike
1个回答

33

Rundll32仅支持运行带有以下签名的DLL导出项:

void CALLBACK
  EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);

它不支持运行任意入口点。由于ShellExecute没有这个标志,很明显会发生糟糕的事情。

INFO: Windows Rundll and Rundll32 Interface有关rundll32接口的更多信息。

如果你想从命令行执行与ShellExecute相等的操作,请使用start:

C:\>start "C:\Documents and Settings\admin\Desktop\tmp"

我要如何知道哪些 DLL 函数导出具有正确的签名? - mike
6
你不应该使用随机函数调用Rundll32。要么是文档说明可以使用Rundll32(例如安装InstallHinfSection),要么就自己提供导出。 - Michael
2
如果你勇敢的话,你可以调用其他函数 - 这些函数将通过 cdecl 调用约定接受这 4 个参数。对于一些无需参数的函数或者只需要一个或两个无意义句柄作为参数的函数,这是可能的。你也可以轻松地编写自己的 DLL,其入口点(=dll 导出)遵循此签名,并使用 rundll32 调用它们。WinAPI 中的函数在 MSDN 中有文档记录。你会发现真正可以直接使用 rundll32 的函数非常少... - Tomasz Gandor
1
似乎不一定非得是void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)。 我用extern "C" void Example()编译了自己的DLL,它正常运行(加上extern "C"是为了获得一个干净的函数名,void Example()同样有效,只要使用Dependency Walker找到函数名即可)。所以看起来只需要是void就可以工作。但是,我并不一定鼓励您这样做。 - FluorescentGreen5
3
如果您只有extern "C" void Example(),那么它很可能是__cdecl调用约定(默认的调用约定,调用方负责清理堆栈)。 CALLBACK是__stdcall调用约定,在这个调用约定中被调用者负责清理堆栈。您的函数将忽略4个参数,这是可以接受的,但它不会清理堆栈,这意味着在函数返回时,堆栈可能会被破坏,从而导致rundll32进程崩溃。 - Sergiy Migdalskiy
1
FYI C:\> rundll32 user32.dll, MessageBeep -MB_ICONEXCLAMATION 会播放一个声音。 - Mike Nakis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接