在Delphi中获取DLL调用者信息

时间:2014-12-15 20:59:27

标签: windows delphi dll

在Delphi DLL中需要建立调用者 - 这可能是一个简单的“.exe”或DBMS运行时模块 - 这意味着它必须获取正在运行的命令。

我知道 CmdLine 不起作用,可能 ParamStr(0),并且不能使用“主窗口”技术,因为调用者有时候没有窗口。我怀疑 GetModuleHandle 是起点,但需要帮助才能从那里获得执行命令。

2 个答案:

答案 0 :(得分:4)

我创建了一个测试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.

然后从测试应用程序中调用它:

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;

它看到了命令行,使用了两个:

  • ParamStr(0)
  • GetCommandLine

enter image description here

GetCommandLine显然显示整个命令行,而ParamStr(0)(根据定义)只是流程可执行路径。

答案 1 :(得分:1)

实际上ParamStr(0)会正常工作。在Windows上,通过调用API函数GetModuleFileName实现它,传递值0作为模块句柄。这将检索与主可执行模块关联的文件名。无论是从DLL还是主可执行文件调用,这都是一样的。

如果我们信任Delphi文档,我们真的不需要深入了解实现。诚然,这有时可能是一项冒险的业务! ParamStr的文档说:

  

ParamStr(0)返回正在执行的程序的路径和文件名(例如,C:\TEST\MYPROG.EXE)。

如果您需要知道传递给可执行进程的参数,可以使用ParamStr传递大于零的索引。或者你可以调用GetCommandLine并自己解析命令行。

请注意GetCommandLine并不总是提供与GetModuleFileName相同的可执行文件名。 documentation说:

  

操作系统为进程提供的命令行中的可执行文件的名称不一定与调用进程为CreateProcess函数提供的命令行中的名称相同。操作系统可以在没有完全限定路径的情况下提供可执行名称的完全限定路径。

但这一切感觉有点脏。从DLL导出初始化函数并要求调用者传递您需要的任何信息可能更简洁。