4

I'm testing on Delphi 2007 and my groupproject is composed by 2 packages.

enter image description here

PackageRun.bpl

It's marked as "runtime only" and contains a unit named "uMyTestRun.pas" in which is defined an empty TFrame descendant:

unit uMyTestRun;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs;

type
  TMyTest = class(TFrame)
  private
    { Private declarations }
  public
    { Public declarations }
  end;

implementation

{$R *.dfm}

end.

PackageDes.bpl

It requires PackageRun.bpl, it's marked as "designtime only" and contains a unit named "uMyTestDes.pas" in which I wrote the following code:

unit uMyTestDes;

interface

uses
  Classes,
  uMyTestRun;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('MyComponents', [TMyTest]);
end;

end.

Output directories of both packages are in Library paths (Inside there are bpl, dcp and dcu).


Trying to install PackageDes.bpl (Component, Install Packages..., Add...), I'm getting the following error:

Can't load package C:\<...>\PackageDes.bpl. Impossibile trovare il modulo specificato.

The last part of the message is in my OS's language, in english it should be something like "Can't find specified module". (My OS is Windows 10 Pro 64bit).

PackageDes.bpl is exactly in the same path shown in the error message (C:\<...>\PackageDes.bpl). After some tests, I found that the error disappear by removing the following line from uMyTestDes.pas unit:

RegisterComponents('MyComponents', [TMyTest]);

Is there something wrong in my code/projects/environment?

Fabrizio
  • 7,603
  • 6
  • 44
  • 104
  • 2
    Is the runtime package reachable and "findable" by the design time package? This means it should be in a directory in the system path variable. And the package should be findable by the IDE too. – Rudy Velthuis Sep 27 '16 at 14:26
  • Where is defined de component TMyTest? How is defined? – Germán Estévez -Neftalí- Sep 27 '16 at 14:26
  • @GermánEstévez-Neftalí- I've updated my question by adding uMyTestRun.pas unit – Fabrizio Sep 27 '16 at 14:29
  • @RudyVelthuis: You're right, the error disappeared after moving PackageRun.bpl to a folder which is in system path variable. Could you please tell me why it's needed? I was thinking that putting the path in the library path was sufficient.. I'm a little bit confused. – Fabrizio Sep 27 '16 at 14:42
  • Delphi installation should had added its default BPL output directory to system PATH, seem either it did not, or you overridden Delphi option of BPL output folder – Arioch 'The Sep 27 '16 at 14:52
  • 1
    EXE/DLL/BPL loading is what the Windows manages, not the Delphi. See MSDN for LoadModule function. If Windows can not find related DLL - BPL being a specific case of DLL - then it can not. Windows knows nothing about Delphi and cannot hook into it to check if there are some non-standard places for ne BPLs to be. Windows only knows about Windows settings, not Delphi settings. – Arioch 'The Sep 27 '16 at 14:54
  • 2
    The library path is for the IDE, but the designtime BPL needs the runtime BPL to load, and that is like loading a DLL. That is why the runtime BPL must be in the path. – Rudy Velthuis Sep 27 '16 at 15:02
  • I had a similar problem when trying to build and install the Graphics32 package in Release mode. The solution was to compile and install the package in Debug mode. – Gabriel Jul 10 '21 at 12:51

5 Answers5

15

Run Process Monitor from http://SysInternals.com and set the filters to intercept only file operations ( toolbar rightmost buttons ) of your Delphi IDE process (check the process name in TaskManager or shortcut properties (it is bds.exe for Delphi XE2), then add the filter similar to Include / Process Name / Ends With / bds.exe ).

Then clear the log in PM, switch to Delphi and try to load the package, then as soon as error pops up switch back to PM and stop capturing events. Try to do it fast as you can, for example do not waste your time closing error box.

Now you would get a trace of file I/O activity of Delphi loading the package of yours (and some other background activity noise - the faster you do the less noise there'd be). In that trace look for all the errors and see where and which package Delphi tries to find.

You can also try Microsoft Dependency Walker or similar tools to se if your Design-Time BPL has all the DLL-dependency tree resolvable. Personally I usually use Unreal/Total commander with FileInfo plugin or ntCore CFF Explorer.

Arioch 'The
  • 15,799
  • 35
  • 62
  • 1
    Even if I've already resolved my problem by reading the comments, I tried your solution and I can say it would have worked. ProcessMonitor shows a lot of operations trying to find "PackageRun.bpl" in all system path variable paths, for each of these operation the result is "NAME NOT FOUND". I think ProcessMonitor will save me other times in the future, thanks! – Fabrizio Sep 29 '16 at 07:04
  • That is exactly why I mentioned it - while you already caught this specific fish, but having a fishing rod for all similar future troubles is never bad :) – Arioch 'The Sep 29 '16 at 08:32
  • Damm, this helped. The thing in my case it was failing every single time I open D7, couldn't find the SynEdit_D7 bpl, even tough it was loading it from the right path. I think what delphi does is output the error with the main package name, but the problem was that it was trying to load SynEdit_R7 from another folder, but the message spit out SynEdit_D7 not R7. Looking at the monitor log, I saw some "not found" in some delphi folders for the SynEdit_R7, I just copy the all files and put them at that folder. Problem solved. – P. Waksman Mar 17 '21 at 17:03
  • 1
    @P.Waksman Delphi can do little about it. Delphi calls Windows to load DLL, and Windows tries to load all the required statically linked DLLs as well, the whole dependencie tree. If Windows fails to load requirements, then the whole top-level load fails too, and that is what Delphi can see. You can use Dependency Walker tools, standalone from Jedi CodeLib, Visual C++. Or plugins like FileInfo and PEViewer VLXs for Total Commander and Unreal Commander. – Arioch 'The Mar 18 '21 at 09:21
1

Easy way to solve this issue is to add a post build action to your run time project:

copy "$(OUTPUTDIR)\$(OUTPUTFILENAME)" "$(BDSCOMMONDIR)\Bpl"

The command above copies your run time file to the default IDE Bpl location.

mas_oz2k1
  • 2,851
  • 3
  • 34
  • 41
1

I had a similar issue. In my case I had the same library name in a different Delphi version BPL path. I found out the solution for my issue looking at the comments above, so this is only a reminder for basic things to check:

  • BPL path have to be included in your OS path variable;
  • Search for a BPL module with the same name in other OS path before the right one (mutiple Delphi version installations).
0

For me, the problem was in the DProj file. The underscore was not accepted in this field:

 <DllSuffix>_$(Auto)</DllSuffix>

Setting that field manually in the IDE, in Project Options will not help. I had to set that field to a random value ('x'), save the project, then open again the Project Options and put the field back to $(Auto). Then it worked.


Update: It seems that when you set that field to 'x', the IDE fixes a broken entry in

      <Excluded_Packages>
      </Excluded_Packages>

So, if you have problems with a BPL, search the Excluded_Packages section and remove your own package from there.


Update:
It looks like it is enought to open the Project Options and go to the "Excluded packages" tab. Then simply close the project options without doing any changes. That will do the trick.

Misterious are Embarcadero's ways!

Gabriel
  • 20,797
  • 27
  • 159
  • 293
-4

Try to change the register procedure to uMyTestRun unit.

unit UMyTestRun;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs;

type
  TMyTest = class(TFrame)
  private
    { Private declarations }
  public
    { Public declarations }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('MyComponents', [TMyTest]);
end;
end.

Now, the package will install correctly.

Regards.