What is the best way to install components? - delphi

Installing components under Delphi XE3 is a nightmare.
First I need to add source files to
Tools -> Options -> Library
then I need to find a normal package and compile it
finally I need to find design time package and install it.
This is just quite tedious and error prone. Is there a nicer way to install components?
I have found Delphi Package Installer. Unfortunately it doesn't support Delphi XE3 or above.
I have heard that there is something similar which produces exe packages that install themselves (something like Inno Setup) but I can't find such thing.

No. The steps above are required.
First, adding the file path to Tools->Options->Delphi Options->Library Path is so the compiler knows where to find the files to compile them. (Actually, it's not required - you can eliminate this step by making sure that the .dpk files are in the same folder as the .pas files, and that all .pas file names are listed in the includes section in the .dpk. If the .pas files are in a different location, you'll need to either use relative paths in the .dpk (eg., MyComponents in '..\Source\MyComponents.pas') or add the location of the .pas files to Project->Options->Delphi Compiler->Search Path.)
The next step (finding the "normal package") is in order to build the runtime package. It's required, because the design-time package (next step) requires the code that's in that package in order to function in the Form Designer. It's also needed when you decide to build your application with runtime packages, if you use the third-party components and want to distribute the runtime package for it.
The separate design-time package (the third step) is required because designtime code can only be used at design-time; there's nothing that can be distributed with an application if it's built with runtime packages and the package build in step 2 is one of them.
This has been the way components are installed since around Delphi 3 or so, and the requirement to separate out designtime code into it's own package started being advised in Delphi 5 and enforced in Delphi 6 (when they relocated much of the IDE designtime support into their own separate packages and stopped distributing the source for them).
There really are no other options, unless the vendor supplies pre-build designtime and runtime packages for you, or supplies an installer that will do all of the above steps. (Most don't.) But if you update your Delphi version, you'd still have to go through the steps above.

What about the built-in component installer? It is part of Delphi XE, XE2 and XE3 and a description can be found here (I wrote it). It will even install components in C++Builder. You can instal into an existing package or into a new one, which it will create for you.

I would say that the best way to install components is to use your build manager (for example FinalBuilder) and add each component to a manager-project file which sets the necessary paths, builds the DPK files, and 'installs' the component in the IDE by making a registry entry. That way you have a documented procedure which allows you reliably to set up or repair your complete, tested, Delphi development environment. You can simply re-run the project when a component has been updated and tested. It is also quite easy to tweak an existing project to handle a new Delphi version.
The big disadvantage of a vendor-supplied installer is that all the ones I have seen simply overwrite the previous version on updates. I prefer to control the install myself, so that I have previous component source versions archived and available for comparison, in case testing reveals a problem with an upgrade. The 'one-click install' sounds fine, until a minor component upgrade suddenly causes your application to stop working.

Take a look at "Lazy Delphi Builder". It was created to simplify build/installation of many components at once. It resolves packages dependencies automatically. Free to use.
Link to some old tutorial

Related

Delphi - How to build a package for distribution

Using Embarcadero RAD Studio XE7, I wrote a runtime package containing a VCL component (it's a TGraphic descendent). Now I want to distribute this component, but only the compiled package without his source code. I cannot include it in the distribution because I wrote this package for a company that want to sell it and keep the control on his sources, so distributing the source code isn't an alternative in this case.
The component package depends on 2 other packages I also wrote. All of these packages are runtime, however a graphic filter is registered. After the package is installed, this filter allows me to open a new kind of image file from several native VCL components like TImage on my development computer. This behavior is very important and I want to keep it on the target IDEs.
Ideally I want my package to be installed on all RAD Studio platforms between XE and 10.2 Berlin. However I recently tried to compile my package in release on my devel computer and deploy it manually on another computer installed with RAD Studio XE4. The result was unconvincing:
Trying to install the .bpl file using the Component->Install packages... failed with a "The specified module could not be found" error. When opening the .bpl file with the Dependency Walker tool, I noticed that several dependencies like RTL210.bpl were missing
I also read somewhere that only design time package may be installed this way, it is exact?
Putting all the files (.bpl, .lib, .hpp, ...) of one of my package manually in the XE4 common dirs, I was able to compile a test project successfully. However several functions in my package were unavailable (resulting to an unresolved external when trying to use them)
Although I have several past experience about software and package distribution, I must confess that I have absolutely no idea about how to build a such package for deployment. In all my past scenarios I always distributed the package projects and source codes, and let the user install them on their own IDE.
I searched information about that in the past days but I found nothing. So if somebody can explain how to achieve a such package, or can point me to a document or website describing the process, or eventually give the name of a tool that can do the job, I would be very grateful to him.
Regards
If you don't want to to distribute the source files, you then need to provide the .dcu and bpl files. As Uwe says, you need different packages for each Delphi distribution.
What I have done in the past is to create an installer which builds and registers the packages. You can find the full description here:
http://www.kouraklis.com/2016/10/build-and-install-packages-in-delphi-ide-using-innosetup/
I think you can modify the script to skip the call to MSBuild.
Hope this helps.

Error Loading a Form

I am a .Net programmer and I'm currently debugging a Delphi application and as I go along
I encountered the following error:
Could you explain to me what is this error, and how I can resolve it?
I am new to using Delphi.
Error Explanation
The error that is been presented to you is telling you that a component on that form is not registered in the IDE, in this case TsStatusBar which is from the AlphaControls library: http://www.alphaskins.com/
The form would have been saved at some point with TsStatusBar placed on the form. When any component is added onto a form they leave references to the component in both the forms source file (*.pas) and the inside the forms dfm. This is why you are getting this error, because the component cannot be found, yet the references linking to it still remain.
Option 1 - Install the AlphaControls packge
The best option would be to install the components that are missing, this will solve your error problem as shown in your question.
Option 2 - Convert Project
AlphaControls provides a tool to convert a project from standard VCL to AlphaControls and vice versa, this may be an easier option then installing the AlphaControls package or manually editing source files, the convert tool is free. Just remember to make a backup before converting should anything go wrong.
Option 3 - Manually Editing the Source Files
You could manually remove these references yourself. Do note though, if you remove the references then Delphi will no longer know that the TsStatusBar was ever there, and without a doubt there will be code somewhere that would have interacted with this component which will create compiler errors.
As an alternative to removing the references, you could rename them from TsStatusBar to TStatusBar, which is a standard statusbar from the VCL. At worst there may be some small syntax errors that may need correcting. If you do decide to edit the forms source and dfm files then I would suggest you do it before loading the form into the IDE.
Option 4 - GExperts
You can also install an IDE Expert such as GExperts which can automate the process of renaming/converting component references.
I would however advise against removing or renaming the references in this circumstance as it seems the project is reliant on the AlphaControls package.
Summary
I can see there are more components from the AlphaControls package been used, so fixing the TsStatusBar error manually will only fix part of the problem.
If the project must remain in its current state then Installing the AlphaControls package is the way to go, if you are able to edit it then I would also suggest the project convert option, this way you won't even need the AlphaControls package.
If you do chose to install the package, it is important to realise that once you install the package Delphi knows where the source files are to be able to compile. After installing the packages, goto Menu > Tools > Options from the IDE, then you need to go to Library and add the folder for the AlphaControls source to the library path. The source folder will be the one containing the most .pas files, but you could add all folders if you are unsure. If you don't add to the Library path then Delphi will not be able compile when using the new components.
Your IDE does not have the package which contains TsStatusBar installed. Find that package, build it, and install it.
Design time components need their code to be integrated into the IDE. This is done using what are called packages. The package project has extension .dpk. You should find this package project in your revision control system. Load the .dpk file in Delphi, click Build from the package manager, and finally, when built, click Install. Now that the package with your component is known to the IDE, your form will load. Whoever maintains this code in your organisation will be able to help with all the details.

Custom component dependency hell

I'm trying to make a package for a custom component I made. It's based on several libraries, including Graphics32, GraphicEx and CCR.Exif.
I created a Package project, wrote the unit including its Register procedure, added some extra references Delphi notified me about to the requires section (including dbrtl.dcp, inet.dcp, soaprtl.dcp, vclimg.dcp, xmlrtl.dcp and dclGraphicEx140.dcp) and added many units to the contains section to avoid warnings about it happening implicitly. The project compiles and can be installed and used on my own machine without issues. However, when I want to install it on another machine, the troubles begin. In the end, I had to copy about all DCUs from all 3rd party components I used, plus both the DCP and BPL from GraphicEx, which I had to install even.
Supplying a lot of files is a bummer, yet surmountable, but having to install other packages as well is a no go. I could get rid of that DCP and BPL by putting even more units in the contains section, but that resulted in error messages on my own machine where GraphicEx is actually installed. This is confusing to me, because with Graphics32 nothing like that occurs...
Anyway, how do I keep my distribution to a minimum and avoid such situations? I want other developers on my team to be able to use the package without worrying about what I used to build it. For a start, can't all the 3rd party units be compiled into my own DCU?
What you experienced is an usual thing to the ones who write components. The distribution is always like that. Packages do not carry other packages, insted they reference them. It´s in their nature.
In order to overcome such a situation I always treat my components in the same way I would if they were a product to sell: I build a setup wizard that distributes and registers everything the package needs.
In my case InnoSetup works very well (http://www.jrsoftware.org/isinfo.php).
Summary
Haven't use Delphi for a while, but, did develop my custom visual controls (Last version I work was Delphi 6).
There are 2 issues when dealing with packages dependencies. One is installing at the Delphi enviroment, making controls appear on the component palette, plus, component editors & property editors.
And another when distributing the compiled packages into customers machines.
It also depends, on which version on Delphi you are running.
Design Time
When developing a custom package, there is a tab for package options, that indicates the destination folders.
The manuals usually tell the developers to leave those textboxes empty. That sometimes works, sometimes doesn't. I explicity write each folder path, in the respective textbox.
There is a textbox path for the ".dcp" files, other for the ".dcu", and so on.
If you have visual controls and stuff like property editors or component editors, its better to split the code in 2 packages ("Runtime" & "Designtime").
I usually put the delphi (packages) projects outside the delphi installation folder.
Run Time
Usually, the quick way is to put the "*.bpl" ".dcp" files in the Windows (32) / system folder, or similar "DLL" windows folder.
Packages folder structure source code suggestion
Managing packages can be difficult. I don't know how much the installation process has changed with Embarcadero, and the newer versions of Delphi. The following chart,is an example on how organize the source code. Hope it helps.
[-]--+--c:
.....|
.....+--[-]--+--software
.............|
.............+--[+]-----java
.............|
.............+--[+]-----php
.............|
.............+--[-]--+--delphi (not the delphi folder in program files)
.....................|
.....................+--[+]-----apps (source code for delphi programs)
.....................|
.....................+--[+]-----other
.....................|
.....................+--[-]--+--packages (all delphi packages source code here)
.............................|
.............................+--[+]-----lib (a single package for non visual controls, libraries)
.............................|
.............................+--[+]-----tools (package pair for non visual tcomponent descendants)
.............................|
.............................+--[+]-----json (example)
.............................|
.............................+--[+]-----xml (example)
.............................|
.............................+--[-]--+--mycontrols (folder custom visual controls)
.............................|.......|
.............................|.......+--[-]--+--delphi40 (folder for delphi40 version of "mycontrols")
.............................|.......|.......|
.............................|.......|.......+----------dsgvclctrls40.dpk (design-time package "mycontrols")
.............................|.......|.......|
.............................|.......|.......+----------runvclctrls40.dpk (run-time package "mycontrols")
.............................|.......|.......|
.............................|.......|.......+--[+]--+--demos (individual example for each "mycontrol")
.............................|.......|.......|
.............................|.......|.......+--[+]--+--design ("*.pas" component editors destination folder)
.............................|.......|.......|
.............................|.......|.......+--[+]--+--sources ("*.pas" source code destination folder)
.............................|.......|.......|
.............................|.......|.......+--[+]--+--bin ("*.dcu" destination folder)
.............................|.......|........
.............................|.......+--[+]--+--delphi50 (folder for delphi50 version of "mycontrols")
.............................|.......|........
.............................|.......+--[+]--+--delphi60 (folder for delphi60 version of "mycontrols")
.............................|.......|........
.............................|.......+--[+]--+--delphi70 (folder for delphi70 version of "mycontrols")
.............................|................
.............................+--[-]-----etc...
Cheers.
Thijs, you simply cannot do that with only a package. The target developer will require almost everything you added to the package. But there is an alternate way of doing what you want: Build a DLL with all the components/libraries you are using in your own component and wrap all those external components/libraries into some code you will export from the DLL. Then build your component without using the external components directly but the DLL you've built. You cannot in you component "use" any unit of the other external components/Libraries. You have to build a new unit with all the datatypes and required declaration for anything you export from your DLL. All this is perfectly working but will quickly becomes very complex for a large number of external components or libraries.
I think AlexSC has the best answer, but I think there might be an alternative if you ansolutely must have a custom component that has no dependencies.
I ran into the Delphi dependency frustrations a little while back trying to create an in-house component for our developers. My suggestion:
Uninstall all dependencies your component uses
In your component package, remove the above dcp from the requires section from your package.
Copy the source files of your dependencies to your components
When you distribute the component, you'll have to distibute it with the code of the required dependecies
You'll run into issues if you want to use the dependcies separately since Delphi won't allow you to have duplicate unit names in installed packages.
Also, the reason you don't want to use DCUs is the fact that the DCUs are compiled for a specific platform and compiler. So unless you are sure that all devolpers are on the same platform ad using the same version of Delphi, dependency code needs to be recompiled.
Again, AlexSC has the best answer and InnoStudio is a great little tool.

Moving to use of Delphi packages - best practice please?

I am trying to start making my own libraries avaialble as packages prior to compiling my Apps with these packages hence modularising my code. For years I've 'sort of' understood packages, breathing a sigh of relief when I load a component package and click on 'Install' and it does. I understand that the process of installing a component (or components) is via the creation of a BPL which is then registered with the IDE.
Where I begin to get lost is how to make files available so that I can compile with EITHER a package OR pre-compiled dcu's (like the third party vendors do) and without pointing my project at the source code all the time. I can create a package with the following settings:
where I've specified that all my output will go into 'c:\scratch\wow'. After a build I find TEST.BPL, TEST.DCP and lots of DUC's. Now, when I point another project at this folder to use the DCU's, I get a missing DFM error (one of the units is a form). Should I be manually copying needed DFM's into this output folder? The DPK knows about this form, so why do I not get the DFM copied for me? I presume that using TEST.BPL, that file contains everything, but I wish to work in the two modes. Of course I can get around this by including the source folder in my project search path to find the DFM but third party libraries seem to already have the DFM's in their output folder. Did they install them there using the installer?
Thanks
instead
As others say you could use post-build events to copy your DFM files into place. Other people use a one-time external batch file that copies the DFMs to the DCU folder.
Personally I see very little benefit to making packages for things which are not developed also as reusable components. I also see very little benefit in partitioning an existing application into packages, when you don't reasonably need to use the same subsection or package more than once, or at designtime.
Things I would put into packages:
Delphi visual and non-visual components.
Things which absolutely must be plugged in at runtime, or left out. For example, supposing I sell MetaWare Light and MetaWare Pro, and instead of using compiler IFDEFs to build a differnt binary, I preferred for some reason to simply not ship the ADVANCEDFEATURE.BPL with my systems.
Things to beware of with packages:
I have run into a lot of compiler bugs when combining packages with generics. I have also run into IDE crashes and lockups, in Delphi 2009, 2010, XE and XE2. (I believe XE3 is better)
You should learn a bit about BorlandMM.dll and shared memory management in the BPL world before you move to it. There are some subtleties.
Packages limits the ability of the linker to decide what to remove. In fact, it pretty much destroys it. Packages contain everything that is linked into them, and nothing publically accessible can be removed.
Once you've created a binary package and shipped it to even one customer, you have a pretty difficult to modify contract (this BPL contains a particular signature or application binary interface) you have to be careful in the future to never change them, or mix and match them. Beware of DLL hell, even among your own customers, and be prepared to use versioning on your packages. Just as delphi packages have a version suffix, I recommend you use version suffixes in your own packages right off the bat, and bump them whenever binary compatibility has changed.
Delphi handles build dependencies between packages about as well as could be hoped, which is less well than a single monolithic application. In applications that I have that make heavy use of packages, I find project groups that contain a bunch of packages that depend on each other are very difficult to manage and build quickly. In fact, I have experienced that both compiles and builds are slower and more frustrating than they would be in a singular 750Kline megaproject.
I really wonder if you're not that into the package area of Delphi (you breath a sigh of relief whenever a delphi component actually builds and installs without issue?) if you really want to move into the Packages World totally. By all means, you should experiment. But I wouldn't bet the farm on it yet. Learn some more first.
Yes, you should copy the .dfm to the directory with the compiled units (.dcus), if that is the only directory you want in your search path. The BPL will of course contain the .dfms, and you need a .dcp to be able to link a BPL with your app.
Third party tools must have put the .dfms together with the .dcus in the directory using their installer, indeed.
Instead of copying *.DFM manually you can use Post-Build Event (Project/Options/Build Event), ex:
copy “$(PROJECTDIR)\Unit1.DFM” “c:\Scratch\wow\Unit1.DFM”
I found a way to do this without moving .dfm files to the directory of .dcu files, so you can have a directory for .dcu files only one for .dcp files only and another for .bpl files only.
All you need to do is to create another directory on your good structure, as I do. The directory is called RES and in it should be placed all the resource files (.res files, not .dcr files) that are used by applications compiled using your packages (components). In the Delphi Library Path, you must include in addition to the DCU directory (you should already have) a directory named RES.
On your component (design time) do everything you want with the form (design it, put other components, etc). In the source code of the unit you replace {$R *.dfm} with {$R UnitName.dfm}. In doing so, save all and close the DPK. Now move the .dfm file (do not copy, move!) to the RES folder (the .dfm file is a resource file to the Delphi. The {$R} directive is proof!) and after that open the DPK again to understand what has changed.
First realize that you may not open the form (F12) from his unit, though no error was issued by Delphi about "DFM missing".
Now, do a Build on your package and then install it. Realized again? No errors displayed! This happened because you have indicated the location of .dfm file in the Delphi library search path (RES directory).
Done! You can use your component and dfm will be found when your component is included in an application.
Many of you can now say that this way I will not longer be able to visually edit a form in the component design time. Yes this is true, but if you think about it, why would I want to change so often a form into a component that, in practice, should only be used and slightly edited? Draw your own conclusions ;)

InstallAware problem with Delphi 2010

I am trying to create an installation disk with InstallAware Express for my Delphi 2010 application. I have selected (checked)
CodeGear Database Express12
CodeGear Visual Component Library 12
for Application Runtime.
When I try to build it, I will get an error message
Error during build: No files matching pattern "C:\Windows\system32\*120.bpl"
The message will go away if I un-check the above runtime but of coz the program will not run.
Can someone please tell me what I am doing wrong?
Also... I have use their scan file button to scan the dependent files base on my application.exe and installaware put a list of files in the $TARGETDIR$, should I leave them there or I am suppose to move them to various folder (e.g. some of the files are from the windows\system32 directory...)
Thanks a lot.
FWIW, one of the great things about Delphi is that you can pretty much install on any system without worry if you turn off the "build with packages" option. This would eliminate the need for these files, and solve your problem, and also make the application more robust against updates and changes. IMO packages are only needed if you are building multi-module applications which are more advanced, and in that case you wouldn't want to be using any Express installer.
You can manually add the files.
To find out which VCL packages your application uses, open the project in the IDE. Use the menu item Project->Build project to rebuild your entire application, and then use Project->Information to view the information dialog. The list of packages actually required by (and therefore needing to be distributed with) your application are listed there.
Where to install them on the destination system depends on why you're using packages in the first place. If you're using runtime packages simply to reduce the download size for your users, and the packages will only be used by this single application, put them in the same folder as your application ($TARGETDIR$). If you're using them because you've got several different applications, and they'll all be installed in different locations but use the same runtime packages, install them in the System32 folder ($SYSDIR$, if I remember correctly).
InnoSetup works fine with runtime packages manually added, btw, especially if you use the excellent (and also free) ISTool IDE. (Not affiliated in any way; just a happy customer.)
Did you have Delphi 2010 installed on this machine? If so, you should see several bpl files under C:\Windows\system32 folder.

Resources