Create a DLL that can be run

Windows has the rundll32.exe utility, which can run its own dynamic link libraries as applications.

Say I have a code that prints "Hello World!" to the console. Is it possible to write a library in C ++ (preferably Visual C ++) that can be executed using rundll32.exe and will run this code? If so, how?

+4
source share
4 answers

Googling "rundll32", the third hit was a link to the documentation,

http://support.microsoft.com/kb/164787

According to this documentation, rundll32 calls a user-specified function with a signature of type wWinMain (in addition to the first argument, a window handle is used here instead of an instance handle),

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

So try this:

 // File [foo.def] EXPORTS sayHello 
 // File [foo.cpp] #include <iostream> namespace myCode { void sayHello() { using namespace std; cout << "Hello, world!" << endl; } } // namespace myCode #undef UNICODE #define UNICODE #include <windows.h> extern "C" __declspec( dllexport ) void CALLBACK sayHello( HWND, HINSTANCE, wchar_t const*, int ) { AllocConsole(); freopen( "CONIN$", "r", stdin ); freopen( "CONOUT$", "w", stdout ); freopen( "CONOUT$", "w", stderr ); DWORD const infoBoxOptions = MB_ICONINFORMATION | MB_SETFOREGROUND; MessageBox( 0, L"Before call...", L"DLL message:", infoBoxOptions ); myCode::sayHello(); MessageBox( 0, L"After call...", L"DLL message:", infoBoxOptions ); } 

Create and run:

  [d: \ dev \ test]
 > cl foo.cpp foo.def user32.lib / MD / LD / D _CRT_SECURE_NO_WARNINGS
 foo.cpp
    Creating library foo.lib and object foo.exp

 [d: \ dev \ test]
 > rundll32 foo.dll, sayHello

 [d: \ dev \ test]
 > _

The output is presented in the own console window created using AllocConsole , which is usually necessary, since rundll32 is a GUI subsystem program (this also causes freopen calls).

To present the output in an existing console window, you can simply omit calls to AllocConsole and freopen and redirect standard rundll32 output to the channel. For instance. standard output can be connected via Windows & rsquo; more when the output is just a few lines, or through some * nix cat utility for more lines. However, in the standard shell [cmd.exe], it does not work to simply redirect the output to con .

+8
source

http://support.microsoft.com/kb/164787

This MSDN article I believe is still accurate; you define an entry point as

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

Although you can use rundll32 to run a properly designed function in a DLL, this is not recommended. This means that your DLL is at the mercy of the rundll32 process settings (greater address awareness, terminal awareness, DPI awareness, register manifest, etc.) Even worse: if some other rundll32 process triggers application compatibility behavior (e.g. low fragmentation heap), then this will affect all rundll32 processes, including yours.

Just write a separate exe.

+2
source

As Joe and you said, use something like this:

  void CALLBACK func(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) { std::cout << "Hello world!" << std::endl; } 

However, CALLBACK = __stdcall, which, when your "func" is exported, will be changed to _func @ 16

You can change this name, http://support.microsoft.com/kb/140485

so you can try something like this:

 rundll32.exe DLLTest.dll, _func@16 
-1
source

All Articles