Programming Field

Rundll(32).exeについて

スポンサーリンク

Rundll(32).exeについて調査していた内容を記述しています。

※ Microsoft Learnの「rundll32」(英語)で紹介されています。

使い方

RundllとRundll32は標準でWindowsフォルダに入っており、「ファイル名を指定して実行」からフォルダ・パスを指定せずに実行できます。Rundll.exeは16ビット、Rundll32.exeは32ビットのDLLを実行します。ただし、Windows NT系はRundll32.exeのみ用意されており、Rundll.exeは使用できません。

※ 64ビット版Windowsでは「%SystemRoot%\System32」以下にあるrundll32.exeは64ビット、「%SystemRoot%\SysWOW64」以下にあるrundll32.exeは32ビットのDLLを実行します。なお、64ビット版rundll32.exeが32ビットのDLLを実行しようとした場合、内部で32ビット版rundll32.exeが実行されます。(2015/09/22追記)

コマンドライン

rundll[32] [<パス>\]<DLL 名>,<関数名> [文字列パラメータ]

[<パス>\]<DLL 名>
(パスは DLL の場所によって省略可) 実行する DLL を指定します。
<関数名>
実行する関数(下記参照)を指定します。DLL 名と関数名の間には必ずコンマ「,」を 入れ、スペースを入れてはいけません。
[文字列パラメータ]
パラメータを指定します。呼び出す DLL によって変わり、省略不可能な場合もあります。

例: rundll32.exe shell32.dll,OpenAs_RunDLL filename ─「ファイルを開くアプリケーションの選択」を実行します、

関数定義

Rundll[32] から呼び出せる関数を DLL に定義するには、以下の宣言を使います。(C/C++)

16 ビット:
void FAR PASCAL __loadds EntryPoint(HWND hWnd,
    HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow);

__loadds は DS セグメントに関連する特別な指定子で、16 ビット DLL によく使用されます。

32 ビット:
void CALLBACK EntryPoint(HWND hWnd,
    HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow);

─ または

void CALLBACK EntryPointW(HWND hWnd,
    HINSTANCE hInstance, LPWSTR lpszCmdLine, int nCmdShow); (unicode)

(EntryPoint、EntryPointW は任意の関数名で、コマンドラインの<関数名>に一致します。)

※ 上記の関数を定義したあと、その関数を装飾名がつかないようにエクスポートします。

引数
hWnd
Rundll[32] が作成した親ウィンドウです(使用しなくてもいい)。
hInstance
DLL のインスタンス ハンドルです。
lpszCmdLine
コマンドラインの [文字列パラメータ] に一致します。
nCmdShow
Rundll[32] が受け取った nCmdShow パラメータです。普通は SW_SHOWNORMAL(=1) です。

関数の呼び出され方

Windows NT/2000/XP では、呼び出す関数名に「W」を付けた(Unicode 版、という意味)「EntryPointW」を最初に探し、見つからなかった場合は「EntryPointA」、「EntryPoint」の順に探します。EntryPointW が呼び出せる場合、lpCmdLine パラメータはLPWSTR型になります。

Windows 95/98/Me ではこの動作は無く、「EntryPoint」を直接呼び出します(lpCmdLine は ANSI 文字列であるLPSTR型)。

まとめ

─ と、これだけなのですが、最初は「パラメータ無しの関数」を呼び出してくれるものだと思い込んでいたため、終了時に必ず例外(エラー)が起こって悩んでいました。

なお、hWnd パラメータで指定されるウィンドウは、サイズが約 4x4(pixel)、CW_USEDEFAULT で設定された既定の位置にある非表示のウィンドウです。DLL内でダイアログを作る場合はこのウィンドウを親にせずトップレベルウィンドウとして表示することを推奨します。