There Can Only Be One!

Handling Different Versions of Design Packages inside the IDE

Use Case

A standard Delphi installation contains three different versions of Microsoft Office Automation Server Wrapper Components packages: XP, 2000 and 2010. Only one of those packages can be loaded at a time because each tries to register the same named classes for design time.

Assume we want to create three new projects, each using a different version of these Automation Server components.

Current Behavior

The current IDE implementation makes this task hard to solve at least, if possible at all.

Let’s take a vanilla Delphi installation, no project loaded. Go to Components – Install Packages and make sure all three packages are registered (i.e. listed under the Known Packages registry key) and disabled. Here comes the first problem:

If you disable one of those packages in this dialog, close the dialog and restart the IDE, one expects that a disabled package stays disabled. It does not! When you restart the IDE that package is enabled again.

The only way to disable that package permanently is to add it to the Disabled Packages registry key. This can only be done by manually adding that entry into the registry.

We now have all of three packages listed in the Disabled Packages registry key. When we launch the IDE and check in Component – Install Packages all three are unchecked. Fine!

Now we create the first VCL Forms project and directly save it under the name ProjectXP. Then we go to Project – Options – Packages and enable that Office XP package. Save and close the project and restart the IDE. Here comes the second problem:

My expectation when enabling that package inside one project is, that this doesn’t influence the global settings for this package. Guess what: it actually does. It doesn’t make any difference if you enable a package in the global options (via Component – Install Packages) or inside the project options – the result is that the package is globally enabled again and you have to manually edit the registry to make it disappear again.

Mind: Even if you have set this straight again, simply opening ProjectXP will bring this package back into the enabled list and you later have to start again getting rid of it.

Conclusion

The current behavior of the IDE doesn’t let us just use a package on a per project base. The lack of a tool to permanently disable a package and the stubbornness of the IDE to keep a package enabled makes the whole process of project enabled packages a nightmare. Note that we didn’t even get to create the second or third project as the encountered barriers already acquired are simply too high.

Expected Behavior

IMHO, to get the basics right for project specific design time packages two things are mandatory:

  1. When no project is loaded and I disable a package in Component – Install Packages this setting should be saved (i.e. that package should be added to Disabled Packages).
  2. When I enable a package in project options this should yet load that package, but should not change the list in Disabled Packages. This setting must of course be reflected in the Excluded Packages entry of the project configuration (which means it should not appear there).
  3. When I close the project the IDE should revert to the default situation, where all packages in Known Packages are loaded except those listed in Disabled Packages.
  4. When I open a project the IDE should load all packages that are listed in Disabled Packages but not listed in the Excluded Packages configuration option.
  5. In addition when opening a project, any package that is listed in the Excluded Packages option should not be loaded either.

Expected Problems

Point 4 will mostly lead to problems which have to be addressed. Assume I have two mutually exclusive versions of my custom package registered in my IDE of which one or both are permanently disabled. Now we load a project from another co-worker that knows nothing of our packages. Obviously the project configuration has not listed our disabled packages in the Excluded Packages section. According to point 4 all versions of my custom package should be loaded which is going to fail.

How to solve this?

Let’s categorize a package in regard to a project as either required, forbidden or don’t care. Although one might be tempted to take the packages listed in the Excluded Packages option as forbidden, I suggest introducing two new options: Required Packages and Forbidden Packages. (I tend to name things after what they mean and not what should be done with them.) Given these new options the IDE should behave as follows.

  • When no project is loaded, the packages should be loaded as if the IDE were just started (i.e. load all packages in Known Packages except those listed in Disabled Packages).
  • When a project is opened the IDE should unload all packages from Forbidden Packages and load all packages from Required Packages.
  • When switching projects the IDE should act accordingly.
    1. Any required package of the old project that is not forbidden in the new project stays loaded.
    2. Any forbidden package of the old project that is not required in the new one stays unloaded.
      This reduces package unload/load overhead during project switching.
  • When closing a project the IDE should do either of the following:
    1. Restore the state from (1).
    2. Keep the current state as is and wait for the next project to load and act according to a project switch as in (3). (preferred)

What not to solve?

Be it a standalone project or a project group, nothing can hinder us to load a form, frame or data module from another project containing a component that requires a different version of any package or simply requires a package that is just forbidden in the current project. We can display a package selection dialog to load the missing packages (at least if this is allowed), but that won’t cover all possible collisions.

I have no idea how this could be overcome within the current limitations. To minimize impact we can put the affected files into read-only mode, so any changes caused by the wrong or missing package won’t ruin the file when saved accidentally.

That said, this behavior (allow to load packages when loading a form fails and retry or switch to read-only if this cannot be solved) might be a good thing anyway.

Author: Uwe Raabe

Addicted to Pascal/Delphi since the late 70's

4 thoughts on “There Can Only Be One!”

  1. The worst problems in Delphi are not even when you want to have multiple versions of one component. It’s when you want a project to tell the IDE that a component is required, before the DFM is opened, leading you to one of the most misanthropic ideas in all of Delphi; Let’s just delete your components from your DFMs, because you didn’t install the package. No attempt has ever been made to fix this problem, that I am aware of.

    Then lets add on top of the user’s reasonable desire that a project should be able to state “I require the entire TeeChart 2015 suite or later”, or “I require developer express component suite 2015.1 or later”, or even a simple “I require TSmiley version 3.3”, or later.

    Then on top of that you have the interesting problem you discuss here. It is interesting to me that the IDE can make no further attempt to solve this problem, unless the bad decisions taken earlier in the IDE design lifetime are reversed. Most strange of all, package requirements are globally registered, a curious design in 2015, and then a strangely limited exceptions mechanism is in place that has only ever hurt me, and never ever helped me. I speak of course of the rather mind-numbing awfulness that is the Excluded_Packages section in the .DPROJ file. WHo ever thought that could have been a good idea? What problem does it solve? I only know what problems it causes. As a user, Delphi 1 and Delphi 2 which lack these crude features, are better.

    Look at this QC article and ask yourself “what should the IDE do?”:
    http://qc.embarcadero.com/wc/qcmain.aspx?d=60832

    I complained in a comment in 2009 about this issue, and I still don’t have clarity on why there has been no progress in 15 years, on basics of relationship between a Project, and a Component. The IDE knows about packages, and has not got any idea what is inside the package until it loads. The IDE does not know what package ought to contain what component, and can make no attempt to help the user when she opens MainForm and it contains a TdxBarManager, and that name doesn’t look familiar. It’s a mess.

    Warren

Comments are closed.