Solved

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

Posted on 2006-07-01
4
226 Views
Last Modified: 2012-05-05
How can I program an application to load a non-hardcoded number/non-hardcoded filenames of dll's.
0
Comment
Question by:HKCU
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
4 Comments
 
LVL 10

Expert Comment

by:sakuya_su
ID: 17025018
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
 
LVL 26

Assisted Solution

by:Russell Libby
Russell Libby earned 125 total points
ID: 17025125

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
 

Author Comment

by:HKCU
ID: 17025356
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
 
LVL 10

Accepted Solution

by:
sakuya_su earned 125 total points
ID: 17025844
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

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In this video, viewers are given an introduction to using the Windows 10 Snipping Tool, how to quickly locate it when it's needed and also how make it always available with a single click of a mouse button, by pinning it to the Desktop Task Bar. Int…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
Suggested Courses
Course of the Month10 days, 13 hours left to enroll

631 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question