Get DLL subscriber information in Delphi

In the Delphi DLL, the caller needs to be installed - it can be a simple ".exe" or a DBMS runtime module, which means it needs to receive a command that is executed in the process.

I know that CmdLine is not working and possibly ParamStr (0) , and cannot use methods based on the main window as the caller will sometimes not have a window.I suspect GetModuleHandle is a starting point, but this requires help. to execute the command from there.

+3


source to share


2 answers


I created a test DLL:

library Project2;

uses
  System.SysUtils, System.Classes, Vcl.Forms, Vcl.Dialogs, Winapi.Windows;

{$R *.res}

procedure DoStuff; stdcall;
begin
    ShowMessage(
            'ParamStr(0): '+ParamStr(0)+#13#10+
            'GetCommandLine: : '+GetCommandLine);
end;

exports
    DoStuff;
begin
end.

      

And then call it from your test app:

procedure TForm1.Button1Click(Sender: TObject);
var
    module: HMODULE;
    doStuff: procedure; stdcall;
begin
    module := LoadLibrary('D:\Temp\Win32\Debug\Project2.dll');
    if module = 0 then
        RaiseLastOSError;
    try
        doStuff := GetProcAddress(module, 'DoStuff');

        if @doStuff = nil then
            raise Exception.Create('Could not find export "DoStuff"');

        DoStuff;
    finally
        FreeLibrary(module);
    end;
end;

      



And he sees the command line using both:

  • ParamStr(0)

  • GetCommandLine

enter image description here

GetCommandLine

, obviously, shows the entire command line, but ParamStr(0)

- this is (by definition) only the path of the process.

+4


source


ParamStr(0)

Will actually work fine. It is on Windows that the API function call is implemented GetModuleFileName

, passing a value 0

as a module descriptor. This returns the filename associated with the main executable. This works the same regardless of whether the call is from a DLL or from the main executable.

We really don't need to delve into the implementation if we trust the Delphi documentation. Admittedly, this can be risky business sometimes! The documentation for ParamStr

says:

ParamStr (0) returns the path and filename of the executable program (for example C:\TEST\MYPROG.EXE

).

If you need to know the arguments that were passed to the executable, you can use ParamStr

it by passing indices greater than zero. Or you can invoke GetCommandLine

and parse the command line yourself.



Beware of GetCommandLine

not always specifying the same executable name as GetModuleFileName

. The documentation says:

The name of the executable on the command line that the operating system provides to the process does not necessarily match the name on the command line that the calling process provides to the CreateProcess function. The operating system can provide the full path to the executable name, which is provided without the full path.

It all feels a little messy. It might be easier to export the initialization function from the DLL and require the callers to pass in whatever information you need.

+1


source







All Articles