Leaky Abstractions in Wise for Windows

I had just reported a bug with the Wise for Windows Installer (it can’t call the Install method on a service compiled under the .NET Framework 2.0) and I checked the Altiris support forum to see if there were any other surprises. One of the senior forum members reported something interesting with the MSI scripting. He had a block of code with the following logic:

If NOT Installed AND NOT ARG
..Do thing1
..Do thing2
..Do thing3
..Do thing4
..Do thing5
End If

At runtime, the first three actions inside the block were executed, but not the last two. This was a tricky one to figure out. Wise shows the actions as if they are running in a script, with an actual IF/END IF block. MSI technology is database driven. Instead of a script, you have each action as a row in a table, with the same IF condition defined for each action. Similiar in behavior to a script, but the condition is evaluated for each row. The thing3 action was changing the value of ARG, and when the condition was reevaluated for actions thing4 and thing5, the result of the IF condition had changed. This is another example of how Leaky Abstractions can bite you in the ass.

Programmers are used to seeing procedural code in a script. Wise does a pretty good job of abstracting out database rules to pseudo scripts, but it’s not a perfect abstraction. Unless you ran the installer through the debugger, and examine conditions at thing 3 and then at thing4, you would never see what was going on.

Samsung bans its own product

Samsung has a cell phone with a 8gb hard drive (form musinc playing) and they have banned it from their own premises. They don’t allow portable memory devices that can be used to smuggle out confidential information. Gizmode has the article here. It’s kind of funny, in an ironic sort of way.

Update: Techdirt has a better article here.

Rants against the machine: Are stored procedures inherently evil?

Jeremy MIller has a good rant against the use of stored procedures. He thinks prefers to keep his code in the application and use T-SQL sparingly. HIs view is that sprocs are harder to test and harder to understand. There’s a logical disconnect when you business logic is split between the application and the database.

I sort of agree with his viewpoint, but not completely. I think that using sprocs for most CRUD applications is a waste of time. Adhoc SQL is usually sufficient for that task. But there are plenty of times where a sproc is pretty handy. Our applications are a mixture of Win32 Delphi and C# and work in the same database space. Having some of the business logic at the database level is better reuse of shared code than duplicated code across development platforms.

But I do agree with Jeremy about the additional burdens that come with sprocs. You have to manage the versions. You have the additional burder of having multiple versions of the sproc if you support multiple database vendors (we do SQL Server and Sybase SQL Anywhere). Your programmers need to know more about SQL than “SELECT * FROM SomeTable”.

His complaint about the sprocs being out of sync with the code was a non-starter for me. We version our database schema changes with our application code. If the database version isn’t in sync with the application version, we force the user to update one or the other. I implemented a simple way to send out database changes with a point and click interface, each new version of our applications is bundled with the database update file that brings the database up to the current application version.

There are performance considerations to consider as well. Once you get past the CRUD, you can get your money out of SQL Server with well designed sprocs. I was able to get 10x improvement recently in one part of a service that I written be replacing a hideously over-complicated adhoc SQL statement with sproc that produced the same results. That sproc split the SELECT statement into multiple statements that stored the individual results into table variables and then combined the individual results into a single result that matched the output of the original SQL statement. Your mileage may vary.

I think we are seeing the swinging of the pendulum from everything must be in a sproc to “sprocs bad, code good”. As with most things, I think there’s some point in between that has your comfort zone. I’m quite content letting the database layer du jour (ADO/ADO.NET/Code generator) handle the CRUD tasks. When I feel the need for speed, I have no qualms against using “CREATE PROCEDURE”.

Delphi 2006 quirks

As I move over to Delphi 2006, I came across an odd new behavior.  In Delphi 7 and prior versions, it was very easy to view/edit the project (*.dpr) file.  Usually you let Delphi manage that file, but sometimes you want to edit it directly.    The “View Unit” button (or CTRL-F12) would include the .dpr file in the list of source code units that belonged to the project.  You would select that file and it would open up inside the Delphi IDE.

In Delphi 2006, it doesn’t work that way.  The only way you can get access to the .dpr file is to select “View Source” from the “Project” menu.  I wonder why they made that change in the behavior.  I don’t have to directly edit the .dpr files that often, but there are times where I do need to do so.

The other oddity is the lack of the support for the SCC API fo using your preference for source control.  It’s 2006 people, there’s no reason why you can’t pick your own SCC provider for use from within the Delphi IDE.  I have no interest in the StarTeam source control bundled with Delphi.  We dumped VSS for SourceGear‘s Vault and we have been very pleased it.  And I want to use if within Delphi like I can with Visual Studio.  While there’s no mysterious force preventing me from running the Vault IDE along side the Delphi IDE, it’s a concentration killer to leave the coding IDE just to check out the file I need to work on.  On small projects that I am the sole owner, I’ll just check all of the code out, but on the team projects, you just don’t do that.  VS spoiled me by prompting me to check a file out as soon as I started editing it.

I’ve been playing with the 30 trial of EPocalipse‘s SourceConnXion 3 for that last few days.  It provides source control integration for Delphi 2005/2006 and so far, so good.   I’ve added it to the list things for the boss to buy as part of our migration to Delphi 2006.

Using Cache in Your WinForms Applications

Here’s a decent article about using ASP.NET cache (System.Web.Caching.Cache) in WinForms applications (or services).  This would be handy in service application, I can’t see how much use it would be for an actual WinForms application.  Combined with the SqlCacheDependency class and SQL Server 2005, then you can cache frequently used rowsets and let the .NET invalidate them when the source data is updated on the server. It should be more efficient than periodically pinging the server for data changes.  It does require Windows 2000 or later.  That’s not a deal breaker for a service app, but it eliminates Windows 9X for a WinForms app.

Playing with Firefox again

As much as I am an Opera bigot, I still roll out Firefox from time to time. This is one of those times. There are enough web sites that still do not work with Opera, that I m forced to use on of the more mainstream browsers. I limit my usage to IE to Hotmail and Outlook Web Edition. As much as I prefer the raw speed advantage of Opera, FireFox does have more cool toys for it. I added the Performancing for FireFox extension and I’m using it right now to post this message. It seems a quick way to toss up a quick blog posting without having to run a stand-alone blogging tool, or worse, Blogger’s online tool.

Technorati Tags: , ,

Tao of the Windows Installer

There are some really good Windows Installer guidelines up on the Windows Installer Team BlogPart 1 went up yesterday and Part 2 went up today.  Most the rules I follow already, due to constant beating of the forehead against the wall experience that I call working with Windows Installer, but it was help to see the rest of them.  I listed them below, with my own comments.  Visit the links for Part 1 and Part 2 for the full text behind each rule.

Rule 1: Learn the Windows Installer Technology

This is key.  I picked up a lot from Wise’s support forums.  A really good book is The Definitive Guide to Windows Installer by Phil Wilson (ISBN: 1590592972)

Rule 2: Know Your Way Around the Installer SDK

I’m just starting to get under the hood with the SDK.  I wrote a console app in Delphi that allowed me to upgrade ProductCode and Package code of .msi/.wsi files.  It was part of a plan to heav each build of our application be able to upgrade from each previous build.  Other considerations led to me to shelf that plan, but it was interesting working in the SDK

Rule 3: Use the “Windows Logo” Program as a Basis For Good Practices
Rule 4: Always Use the Latest Version of the Installer

Both are common sense.

Rule 5: Build Setup Into Your Application Development from the Start

On my last project, I fought constantly with the project lead over this.  Having done several installer projects in the past, I knew what I was getting into and planned for the installers from the start.  This made life much easier.

Rule 6: Get to Know ORCA

Simply the best tool for diagnosing problems with a .msi file.  You can get from the Windows Server Software Development Kit.  The current version is the “Windows® Server 2003 R2 Platform SDK”.

Rule 7: Work On a Copy

More common sense.

Rule 8: Never Cancel a Package Build Before it Finishes

I never knew about that one.  With installer tool that I’m using (Wise), I don’t see that is being a real issue.

Rule 9: Use a Clean System for Repackaging
Rule 10: Do Not Repackage Microsoft Updates
Rule 11: Do Not Repackage MSI-Based Applications

Still more common sense.

Rule 12: Modify Vendor Packages Using Transforms

I may be doing this in the near future.  I haven’t had to do any package transforms, but I understand the basic concepts.

Rule 13: Be careful with Installer GUIDS

It took a while to sink into my head over the Gang of Three GUIDS, but it’s in my firmware now.

Rule 14: Use Consistent Package Naming Conventions
Rule 15: Do Not Try to Replace Protected System Files

Common sense again

Rule 16: Follow Component Rules

I need to study this more.

Rule 17: Understand File Versioning Rules

One of my pet peeves with Windows Installer.  Why does it ignore the last number of a version number?  If it could use all four parts of the version number, I could have my build to build upgrades and there would be much rejoicing in the land of Queue-ay.

Rule 18: Improve Performance by Limiting System Restore During Setup
Rule 19: Avoid Using the SelfReg Table

Good tips

Rule 20: Avoid Nested Installs

Having one .msi calling another .msi is something I seriously plan on avoiding.  Just follow Spengler’s warning and don’t cross the streams.

Rule 21: Avoid Using Configuration Data You Don’t Own
Rule 22: Differentiate Between User and Application Data
Rule 23: Don’t Use Resources You are Installing

Still more common sense.

Rule 24: Use Cabinet Files to Reduce Package Sizes

I need to look into that more.  I wonder how that would play with installers for web sites.  I could toss all of the .ascx files into a .cab file and the assemblys as separate files.  For Win32 executables, I usually pre-compress them using UPX as part of the build process, putting them into .cab files would gain nothing.

Rule 25: Follow Custom Action Rules

Some good tips.  I don’t use many custom actions, but it’s good know what not to do

Rule 26: Consider Storing User-specific Data in a File

This an interesting one.  Our .NET apps follow this methodology, but our Win32 apps use the registry for most user specific settings.   Something to consider going forward.

Rule 27: Consider Maintaining Setup in Text File Format

I would to be able to do this with Wise’s .wsi files.  The problem is that the .wsi is actually a .msi file, and I have yet to see a tool that will reliably convert a .wsi/.msi file to text and back again. I tried MSIDIFF, but something always gets mangled and when you convert a file from one to the other and back again, you don’t always get the same file back.  That’s not a good thing.

Rule 28: Think about Localisation

Something I don’t have to deal with…

Rule 29: Follow the Assembly Rules

Wise does a good job with this, I usually don’t have to worry about assemblies.