Making an app that loads all DLL's in a folder

How can I program an application to load a non-hardcoded number/non-hardcoded filenames of dll's.
HKCUAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
sakuya_suConnect With a Mentor Commented:
this code snipet:
http://www.swissdelphicenter.ch/torry/showcode.php?id=1745



*
--- english -------------------------------------------------------------------
These two functions allow to dynamically call DLL functions with dynamically
customizable parameters.
Also allow a programm to call a function with at design time unknown parameters
(you'll have to implement the dynamicall filling of the array of pointer).
--- german --------------------------------------------------------------------
Mit diesen Funktionen k├Ânnen Sie dynamische Aufrufe von DLL-Funktionen
realisieren.
Sie legen zur Laufzeit den Namen der Funktion und bestimmen ebenso welche
Parameter ├╝bergeben werden sollen und von welchem Typ diese sind (zu
Letzteres kann eine entsprechende Prozedur geschrieben werden).
*)

// Calls a function from a library.
// if it's not loaded yet, it will call LoadLibrary() to load it.
function DynamicDllCallName(Dll: String; const Name: String; HasResult: Boolean; var Returned: Cardinal; const Parameters: array of Pointer): Boolean;
var
  prc: Pointer;
  x, n: Integer;
  p: Pointer;
  dllh: THandle;
begin
  dllh := GetModuleHandle(PChar(Dll));
  if dllh = 0 then begin
    dllh := LoadLibrary(PChar(Dll));
  end;
  if dllh <> 0 then begin
    prc := GetProcAddress(dllh, PChar(Name));
    if Assigned(prc) then begin
      n := High(Parameters);
      if n > -1 then begin
        x := n;
        repeat
          p := Parameters[x];
          asm
            PUSH p
          end;
          Dec(x);
        until x = -1;
      end;
      asm
        CALL prc
      end;
      if HasResult then begin
        asm
          MOV p, EAX
        end;
        Returned := Cardinal(p);
      end else begin
        Returned := 0;
      end;
    end else begin
      Returned := 0;
    end;
    Result := Assigned(prc);
  end else begin
    Result := false;
  end;
end;

// Calls a function from a loaded library
function DynamicDllCall(hDll: THandle; const Name: String; HasResult: Boolean; var Returned: Cardinal; const Parameters: array of Pointer): Boolean;
var
  prc: Pointer;
  x, n: Integer;
  p: Pointer;
begin
  prc := GetProcAddress(hDll, PChar(Name));
  if Assigned(prc) then begin
    n := High(Parameters);
    if n > -1 then begin
      x := n;
      repeat
        p := Parameters[x];
        asm
          PUSH p
        end;
        Dec(x);
      until x = -1;
    end;
    asm
      CALL prc
    end;
    if HasResult then begin
      asm
        MOV p, EAX
      end;
      Returned := Cardinal(p);
    end else begin
      Returned := 0;
    end;
  end else begin
    Returned := 0;
  end;
  Result := Assigned(prc);
end;


(* --------- Sample (GetSystemDirectory) --------- *)

var
  parameters: array of Pointer;
  returned: Cardinal;
  Dir: String;
begin
  SetLength(parameters, 2);
  SetLength(Dir, MAX_PATH); // Set Buffer size
  parameters[0] := Pointer(@Dir[1]); // 1st parameter, buffer for path string
  parameters[1] := Pointer(MAX_PATH); // 2nd parameter, length of buffer
  if not DynamicDllCallName(kernel32, 'GetSystemDirectoryA', true, returned, parameters) then begin
    ShowMessage('Function could not be found!');
  end else begin
    SetLength(Dir, returned); // Cut String
    ShowMessage('GetSystemDirectoryA:'#13#10'Path: ' + Dir + #13#10'Length: ' + IntToStr(returned));
  end;
end;


(* --------- Sample (TextOut) --------- *)

const
  SampleText = 'test';
var
  parameters: array of Pointer;
  returned: Cardinal;
begin
  SetLength(parameters, 5);
  parameters[0] := Pointer(Canvas.Handle); // 1st parameter, handle to the form's canvas
  parameters[1] := Pointer(10); // 2nd parameter, left margin
  parameters[2] := Pointer(30); // 3rd parameter, top margin
  parameters[3] := @SampleText[1]; // 4th parameter, pointer to the sample string
  parameters[4] := Pointer(Length(SampleText)); // 5th parameter, length of the sample string
  if not DynamicDllCallName(gdi32, 'TextOutA', true, returned, parameters) then begin
    ShowMessage('Function could not be found!');
  end else begin
    if not BOOL(returned) then begin // function's result = false
      ShowMessage('TextOut() failed!');
    end;
  end;
end;


(* --------- Sample (LockWorkStation) --------- *)

var
  parameters: array of Pointer;
  returned: Cardinal;
begin
  // We don't have parameters, so we don't touch parameters
  if not DynamicDllCallName(user32, 'LockWorkStation', true, returned, parameters) then begin
    ShowMessage('Function could not be found!');
  end else begin
    if not BOOL(returned) then begin
      ShowMessage('LockWorkStation() failed!');
    end;
  end;
end;


as you can see the 1st parameter of DynamicDllCallName is the actual liberary name, so you can easily write a function that goes through everyfile in a directory, and then just pass the dll name to the parameter


EDIT:
If that does not work, try registering the dlls 1st
0
 
sakuya_suCommented:
what do you mean by loading the dlls? dlls are used when you call for a certain functions.. so unless you know the function names the dll has no use to you
0
 
Russell LibbyConnect With a Mentor Software Engineer, Advisory Commented:

That is, unless the dll's are to be used as resource libraries. Anyways, I have no idea what the desired usage is (for this q) for loading all the dll's in a path, but doing it is easy enough.

Regards,
Russell

// Load all libraries in a given path
function LoadPathLibraries(Path: String): Integer;
var  srFind:     TSearchRec;
     szPath:     String;
     dwFind:     Integer;
     hLib:       HMODULE;
begin

  // Result is the number of libraries loaded
  result:=0;

  // Cleanup the path
  szPath:=ExcludeTrailingBackslash(Path);

  // Start the find
  dwFind:=FindFirst(szPath+'\*.dll', faAnyFile, srFind);

  // Check find result
  if (dwFind = 0) then
  begin
     // Resource protection
     try
        // Check name
        if (Length(srFind.Name) > 0) and ((srFind.Attr and faDirectory) = 0) then
        begin
           // Load the library. If you only want the lib is a resource, then better to use
           // LoadLibraryEx, eg:
           //
           //    hLib:=LoadLibraryEx(PChar(szPath+'\'+srFind.Name), LOAD_LIBRARY_AS_DATAFILE);
           //
           hLib:=LoadLibrary(PChar(szPath+'\'+srFind.Name));
           // Check load
           if (hLib <> 0) then Inc(result);
        end;
        // Find next
        dwFind:=FindNext(srFind);
     finally
        // Close the find
        FindClose(srFind);
     end;
  end;

end;

procedure TForm1.Button1Click(Sender: TObject);
begin

 // Pass the path to load the libraries from
  LoadPathLibraries('c:\windows');

end;



0
 
HKCUAuthor Commented:
Well, In responce to sakuya_su, I plan to use this as a plugin, so I will have a known list of functions/procedures to call. IE when the program loads call a procedure in the DLL's called Initialize or something like that.

rllibby, how can I access/use the stuff that function loads?
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.