Solved

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

Posted on 2006-07-01
4
220 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
  • 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

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

760 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now