Saturday, March 28, 2009

The new InstallShield supports a very handy command line argument for debugging the handling of prerequisites.

Often times, you'll have a prerequisite for your install that, for whatever reason, fails to run. When that happens, if you've properly set the launch conditions for your install to detect the installation of your prerequisites, your install will fail based on that launch condition.

This is a good thing, but it still begs the question; why did my prerequisite fail to install?

In my case, I had a preq for the .NET Framework 3.5. But my installation failed to run the prerequisite, so it failed at the launch condition because the 3.5 framework was not on the machine.

However, I had no idea why it didn't run the .NET installer.

Even turning on Verbose MSI Logging, didn't help, because IS runs prerequisites BEFORE the Windows Installer kicks in, so the verbose log won't include anything about what happens when the preqs are run.

With the new InstallShield 2009, though, your SETUP.EXE supports a new switch, /DEBUGLOG.

Use it like this:

MySetup.exe /DEBUGLOG"Path and file to debuglog"

note there's NO SPACE between DEBUGLOG and the ".

so you might use:

MySetup.exe /DEBUGLOG"c:\debug.log"

Doing so revealed that the bootstrapper was, indeed, attempting to run the .NET Framework installer, but that it was failing. Unfortunately, It did not indicate the reason for the failure. Here's the pertinent snippet from the log:

1-23-2009[01:10:15 PM]: Extracting 'Microsoft .NET Framework 3.5 SP1.prq' to C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\{D4907620-651C-4FA9-9B3F-FCE2FCADB41A}\Microsoft .NET Framework 3.5 SP1.prq
1-23-2009[01:10:15 PM]: PrereqEngine: condition,2,2,HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5,SP,,1 -- Successful
1-23-2009[01:10:15 PM]: PrereqEngine: operatingsystemcondition,5,1,2, -- Failed!,
1-23-2009[01:10:15 PM]: PrereqEngine: operatingsystemcondition,5,2, -- Failed!,
1-23-2009[01:10:15 PM]: PrereqEngine: operatingsystemcondition,5,2, -- Failed!,
1-23-2009[01:10:15 PM]: PrereqEngine: operatingsystemcondition,6, -- Failed!,
1-23-2009[01:10:15 PM]: PrereqEngine: operatingsystemcondition,6, -- Failed!,
1-23-2009[01:10:15 PM]: PrereqEngine: operatingsystemcondition,6, -- Failed!,
1-23-2009[01:10:15 PM]: PrereqEngine: file,AD29C3DEC8FB0CFDAFE8548371B0EE6D,<ISProductFolder>\SetupPrerequisites\Microsoft .net\3.5 SP1\Full\Helper.exe,http://saturn.installshield.com/devstudio/setuprequirements/Microsoft .net/3.5/Helper.exe,,, -- Successful,
1-23-2009[01:10:15 PM]: PrereqEngine: file,,<ISProductFolder>\SetupPrerequisites\Microsoft .net\3.5 SP1\Full\dotnetfx35.exe,http://download.microsoft.com/download/2/0/e/20e90413-712f-438c-988e-fdaa79a8ac3d/dotnetfx35.exe,,, -- Successful,
1-23-2009[01:10:15 PM]: PrereqEngine: execute,Helper.exe,/p dotnetfx35.exe /l 1033 /v "/q /norestart",/p dotnetfx35.exe /l 1033 /v "/q /norestart",1641,3010,, -- Successful
1-23-2009[01:10:15 PM]: PrereqEngine: Id,{074EE22F-2485-4FED-83D1-AAC36C3D9ED0},http://saturn.installshield.com/is/prerequisites/microsoft .net framework 3.5 sp1.prq, -- Successful
1-23-2009[01:10:15 PM]: PrereqEngine: behavior,Optional,,Reboot,2,Failure,
1-23-2009[01:10:15 PM]: PrereqEngine: Lua,
1-23-2009[01:10:15 PM]: PrereqEngine: Hidden,1
1-23-2009[01:10:15 PM]: PrereqEngine: MsiProgress,
1-23-2009[01:10:15 PM]: Skipping prerequisite 'Microsoft .NET Framework 3.5 SP1.prq' because it was installed before the reboot

Since things seemed to point to the .NET Installer, I ran it manually. Lo and behold, it failed because I didn't have SP2 installed on this virtual machine.

Duh!

But that DEBUGLOG switch definitely helped point the way.

posted on Saturday, March 28, 2009 8:15:26 AM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Friday, March 27, 2009

Here's the "Prerequisite condition editor" dialog from InstallShield 2009:

image

The first snag I ran into was determining what the difference was between a registry entry having a "specified value" and one having a "specified version value".

It's certainly not clear from this dialog, since both options show the same set of properties at the bottom of the screen.

It's also not in the help file or documentation online anywhere that I could find.

Come to find out, the former performs a "stringwise" comparison, whereas the latter performs a numeric comparison. Pretty important distinction.

Then there's that "Run this prerequisite if the specified registry value data has the following relationship to the existing data" frame. huhwha?

I had to read that one more than a few times to grok what it's actually trying to say, and that's never a good sign.

Top it off with the fact that a call to InstallShield support verified that the sentence logic itself is backwards. Even the developers couldn't read it right!

End result. Let's say you want to install your prerequisite if registry value x is non-existent or 1.

In that case, you'd need to set the condition as a "Registry entry has a specified version value" type condition, you'd set the registry key and value names appropriately, and finally you'd set a "value data" to 1 and set the relationship to "is less than", even though that is the opposite of what the dialog reads.

posted on Friday, March 27, 2009 4:09:16 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Wednesday, January 14, 2009

The new Windows Installer 4.5 has support for chained MSIs, which is fantastic. What that means is that you can finally have your install invoke one or more other MSI installations, and they all get installed as a single transaction, meaning, if any one of them fails for any reason, the entire install can be rolled back seamlessly.

This is a huge step up from the old days, especially for those complex fat client installations that require things like XML, SQL, ADO, VSTO, etc that may or may not be present on older OS's.

Anyway, one problem I ran into when experimenting with this functionality is that I had both the SQL Native Client Drivers and the SQL Server Management Objects as chained installs, but, when I tested my installation, the SQL SMO ended up getting installed first, and it failed, because it depends on the SQL Native Client Drivers to already be installed.

image

I thought that maybe the order of the items in the Chained MSI Packages list controlled the order, but no, apparently, that list is just alphabetic.

You can actually only control the order of chained MSIs by using the Direct Table Editor on the ISChainPackage table:

image

Just enter numbers from 1 to x in the order column to control which chained MSI is installed first, next, etc.

posted on Wednesday, January 14, 2009 11:08:20 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Tuesday, May 27, 2008

I'm constantly amazed by some of the goofy things that application installations do to my system without even giving me the option.

Obviously, there's the whole spyware/adware problem, but that's just blatant.

There's an entirely other, more subtle, level to the problem, where applications do little things that are difficult to undo, are annoying and that you aren't given the option of not "doing" in the first place.

Here's one example. Now, I like the CodeJock products, and I'm not really picking on them here, it's just that they give me a good example:

image

This is the "Right Click - New" menu that you get from Explorer when you right click in a folder and select "New".

Now, I'm a pretty busy developer, and I like a nice shortcut just as much as the next guy, but honestly, I can't imagine EVER creating so many "Command Bars Designer Documents" that I'd want an entry for it on my New Items menu like this. As you can see, there's already enough junk on this menu. I wonder how many people out there create a new contact, bitmap image or briefcase so regularly that it belongs on this menu. Hell, I've always created new Word docs by opening Word, starting my document and then "File-Save"-ing them wherever, never by the "New Office Word Document" menu, but then, maybe that's just me.

A few others:

  • Unrequested shortcuts on the QuickLaunch space or the Desktop.
  • Unrequested Tray Icons.
  • Adding Vista Sidebar gadgets without permission.
  • Stealing file extension associations without asking and not restoring them on uninstall.

Any other bits of application rudeness out there anyone has run into?

posted on Tuesday, May 27, 2008 8:21:51 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Saturday, November 03, 2007

I wrote about various troubles nesting SQL Express installations a few days ago here.

I just wanted to add a little more info for those interested.

Come to find out, it's still possible for SQL Express to end up requiring a reboot, which, if you're install was planning on performing DB tasks, puts a cold, wet, nasty damper on your fireworks quick.

But, from what I can tell so far, it's almost always going to be related to a file or files that the SQLExpress install needs to replace but can't because they're locked.

I'd had some difficulty finding any info on how you might determine exactly what file(s) it was that were locked when I came across this post on MS Technet.

Basically, immediately after you install, but BEFORE you actually reboot, fire up REGEDIT and check out:

HKLM\system\currentcontrolset\control\sessionmanager\pendingfilerenameoperations

The value should contain the names of any files that couldn't be replaced during the install and are queued for replacement.

At that point, it's just a matter of determining which process(es) have those files open, and making sure your install verifies that those processes are closed before allowing the installation to continue.

In my case, so far it's always been an issue with MSDE 2000 already installed a running on the machine. The SQLDMO.DLL is used and locked by the running MSDE process, but the SQLExpress install needs to replace it.

It's a royal pain to be sure, but at least there is something that can be done about it.

posted on Saturday, November 03, 2007 7:48:01 AM (Central Standard Time, UTC-06:00)   •  # •  Comments [2] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Tuesday, October 23, 2007

I recently had the pleasure of trying to get SQLExpress 2005 to install, on request, during my application's install, according to various parameters specified by the user during the UI portion of my install. Phew. Yeah, it's hard enough to say, much less code.

Anyway, the basic problem is that you can't nest MSI installs. And since an "MSI Install" is considered to be the portion of the install that runs during the EXECUTE sequence of the MSI logic, this means you can't just execute SQLEXPR32.EXE at some point during the EXECUTE sequence of your install.

This is normally what you'd want to do because then, that action would happen regardless of whether your installation was running silently (ie no UI) or not.

Ok, that's off the table. Hey, Microsoft! Believe it or not, nesting installs is something real world apps have to do in order to get all those nifty libraries of yours out there onto client machines! Sigh.

Fortunately, in my case (and in many others I'm guessing), not being able to run the SQL Express installer during a silent install is not a deal breaker. More than likely, if my installation is being rolled out silently, whoever's rolling it out is using some sort of automated rollout tool to do it, and it's likely they'll just automate the rollout of SQLExpress as well.

But, what about when a user is simply trying to run my installation to get the product on their machine. In this situation, you want a no fuss, no muss process that has a user up and running with a little decision-making as possible. The last thing I want a user being prompted for is the instance name to use for the SQL Server that's about to get installed. Sheesh.

Well, I can't nest MSIs, technically, but I can execute SQLEXPR32.EXE from the UI sequence of the install.

Aha! Success! Except that, as well documented by any number of posts online, it doesn't work consistently. Often, you'll get an MSI error 110 indicating that SQL can't access a file (usually sqlncli.msi) that it needs to complete the install.

            ******* CommandLine: **********
MSI (s) (18:00) [12:59:55:555]: Machine policy value 'DisableUserInstalls' is 0
MSI (s) (18:00) [12:59:55:575]: Note: 1: 1309 2: 5 3: C:\23661fc1e2705da3b45f5b05\setup\sqlncli.msi 
MSI (s) (18:00) [12:59:55:595]: MainEngineThread is returning 110
The system cannot open the device or file specified.

Trouble is, the file is there, exactly where the log says it isn't.

The problem is clearly an issue with the SQLExpress installer. I can say that pretty confidently because you can nest all of SQL's prerequisite installs just fine, including:

  • MSXML6.MSI (The XML 6.0 libraries)
  • SQLCNLI.MSI (SQL Native Client)
  • SQLServer2005_XMO.msi (SQL Server management objects installer)
  • And even VSTOR.EXE (the Visual Studio Tools for Office)

Just not the SQLEXPR32.EXE itself.

One possible solution that I found mentioned online was to extract all the SQLEXPR32.EXE files, then actually include them directly in your installation and at the end of your installation (in the UI sequence) launch the SETUP.EXE that starts the SQLExpress installation.

So I extracted them all:

SQLEXPR32.EXE /x:c:\SQLEXPR

Ouch. And I mean owwwwwwwwwchaaaaaa. 400+ files scattered over dozens of directories. The InstallShield Component Wizard choked trying to add them all as components and there was simply no way I was going to manually set up all that felgercarb in my install. Yeah, I went there\:\-\)

Then it struck me. The extraction process (that /x command line arg) isn't actually an msi install, so I should be able to nest it just fine. And if that's the case, then I could extract all the files from SQLEXPR.EXE dynamically after installing the exe, and then fire up SQL's setup.exe directly, just as I'd tried launching the SQLEXPR32.exe before (but that failed with the 110 error).

So, first, make sure you install the SQLEXPR32.EXE along with the rest of your application's files.

Then, set up a Custom Action in your MSI project, in the EXECUTE sequence, that extracts all the files from SQLEXPR32.EXE to some folder (usually inside your INSTALLDIR somewhere):

image

(note the use of /q; that will keep the extraction process quiet, including suppressing a rather bothersome "Extraction process done" message box when it finishes, Also note that this adds substantially to your app footprint so you may need to accommodate that in available space calculations).

Next, create another Custom Action to execute the SQL Express SETUP.EXE that was extracted in the previous step.

image

Set this CA to execute towards the end of the UI sequence (because this is an MSI setup and this action can't be started from the EXECUTE sequence of your installation, no getting around that one).

I set a command line of /qb to use the basic install ui for SQL Express, but you might also want to include other command line parameters, like:

  • ADDLOCAL
  • INSTANCENAME
  • SECURITYMODE
  • SAPWD
  • DISABLENETWORKPROTOCOLS

or any of the other options you can specify. More info about the command line options for SQLEXPR32 are pretty easy to find online.

And finally, to keep your installation from looking like it just hung during the extraction part above, be sure to author a row in the ACTIONTEXT table for that custom action, and give it some text, like "Extracting SQL Server files...". The text will show up over the progress bar that normally displays during an InstallShield-authored installation.

Let me know if this works for you, or if I've missed some esoteric combination in InstallShield that prevents it from working.

As always, YMMV.

posted on Tuesday, October 23, 2007 9:32:37 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [6] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Tuesday, September 25, 2007

Normally, when you want InstallShield to be able to perform a MAJOR UPGRADE on an install package, you have to change both the "package code" and the "product code", and of course, the product version. However, you'll normally leave the "Upgrade code" the same.

If you do this, InstallShield will install your new "version" as a new product, but it will also detect the existence of the previous version due to the Upgrade code, and force an uninstall of the previous version. I've actually blogged about this before here.

That's exactly what I was expecting when I started testing the latest version of our package (and the first that was intended to support upgrades), and I was a bit surprised and perplexed when it popped up into maintenance mode  of the previous version!

Somehow, I could start the install by dbl clicking on the MSI of the new version, but the maintenance mode of the previous, installed, version would get started?! What the hell?

I started digging through verbose logs, called Macrovision, the works, and nothing seemed to fix it.

Then, I happened to notice mention of a package code in the logs that I didn't recognize. I checked my new version's properties and the package code didn't match what was in the log.

image

Where the heck was it getting this other package code from?

So, I did a search through the project and it turned up here, under the releases screen!

image

Turns out, at some point in the past, this package code had been set, which overrides the package code defined in the Summary Info Stream screen above, when I build this particular release.

Since package codes should normally change with each build, everything was getting screwed up.

I set the "Generate Package Code" option to Yes, and cleared the package code from the releases screen, recompiled and all was well.

I suppose this is an easy mistake to make, but it's one that left me scratching my head for more than just a few minutes.

posted on Tuesday, September 25, 2007 9:22:35 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Thursday, August 23, 2007

Neeru Hundal has a pretty interesting and informative blog at http://msiblogger.com that's all about MSI issues.

A very good article there focuses on issues to look out for when creating MSI's for Vista (or that might end up on Vista, which means pretty much any MSI, I'm guessing).

One in particular hit me just a few days ago. Neeru indicates you need to set the ALLUSERS property to 1. He emphatically states you need to SET IT (not just leave it blank or not there at all). I've found that you definitely need to set it, but you should set it to 2, or you may end up getting UAC and "You don't have proper permissions" messages, even though you've created the install to specifically NOT require admin privileges. Originally, I had ALLUSERS set to 1 and was getting a "requires admin privs" message even though my installation shouldn't have required administrative privileges.

Another nugget:

  • Custom Actions
    1. Custom Actions in the UI Sequence will run with standard user privileges
    2. For Custom actions requiring admin rights, mark custom action as Deferred - No Impersonate

Anyway, he's got a few other articles there, too, which make for some good reading.

posted on Thursday, August 23, 2007 7:50:34 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Saturday, June 09, 2007

In my post here, I discussed a problem I'd run up against having to do with performing an ADMIN installation to a specific drive letter or network path, then unmapping that drive letter and remapping it to some other letter.

If you then attempt a client install, you'll get either at 1327 error (for mapped drives) or a 1606 error (if you used network UNC paths).

After further testing, it appears that the problem comes from assigning the TARGETDIR property to the AdminProperties property.

Some background:

The AdminProperties property is a ";" delimited list of property names that should be preserved when performing an admin install. The MSI engine stores those property values as they are at the time of the administrative install into the created Client Installation MSI (the MSI file that ends up in the admin install folder). Here's an example:

MSIRemoveTARGETDIR

and a little closer in...

MSIRemoveTARGETDIR

(Interesting bit of trivia: I have no idea how the MSI engine actually stores these properties in the MSI file, because opening the MSI file with ORCA, I couldn't find them anywhere. I'm guessing they're not stored as a normal table entry).

Normally, any properties you'd like to pass on to the client install (ie those collected via the User Interface during the Admin install), you would list as AdminProperties so the MSI engine will pass them on.

I had set the TARGETDIR property as an AdminProperty, because at one point, I believed it was necessary to preserve the path to the Admin installation, so the client installation could make use of it.

This turned out to be ill advised, however, because often, admin installations will be moved (for disk space reasons, reshuffling servers, etc), and preserving the TARGETDIR this way locked the Client install to always point back to the original administrative install. Instead, during a client install, I simply obtain the value of the current location of the MSI file (which, by necessity is the current location of the administrative install) and use it where needed.

At any rate, none of this should have mattered, because the documentation clearly states that the COSTFINALIZE MSI event checks the directory table for valid drive letters, not the Properties table.

However, directories stored in properties listed in the AdminProperties list are appearently special cases, and their validity is checked.

Moral of the story? Use InnoSetup\:\-\)

But, if ya gotta use InstallShield, make sure you do not:

  1. Store the Admin Installation folder or any folder that might end up getting remapped or disconnected, into a property during the Admin install.
  2. List that property in the AdminProperties property.

This goes for the TARGETDIR property (a common one), but also any other properties you might create.

posted on Saturday, June 09, 2007 8:28:53 AM (Central Standard Time, UTC-06:00)   •  # •  Comments [2] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Friday, June 08, 2007

Don't you just love strolling along merrily on a friday afternoon, thinking "My, the weekend is right around the corner, I believe I shall sup on crumpets and tea", when you step right through a soft spot on the ground in fall into a viper pit?

Ever seen this error before:

(The blackout is to protect the innocent \:\-\) )

It's an MSI 1327 Error Invalid Drive, indicating (surprise) that a specific drive is invalid.

Basically, I got it while testing the install of an application I'm working on.

Many Google searches and a call to MacroVision later, and I still didn't have much of an idea what was going on.

The drive letter in question WAS valid at the time I did the original administrative installation, but was no longer valid when I performed the client installation from the admin install.

To sum up:

  1. Map a folder to DRIVE X
  2. Perform an Administrative Install of your app to Drive X
  3. Unmap Drive X and remap the same folder to Drive Y
  4. Perform a client install from the administrative install that is now on Drive Y
  5. BOOM goes the dynamite

Even more interesting, I tried the same installation steps, but didn't use a mapped drive. Instead, I used a UNC network path name, and then forced that network share to become invalid. I got a 1606 "Could not access Network location" message. Different error, but the same problem.

I turned on verbose logging for MSI and it recorded that the error occurred during the CostFinalize event. That event validates all folder entries stored in the Directory table in the MSI, but a quick perusal of that table revealed no references to the (now invalid) drive letter.

Macrovision support suggested trying the client install on another machine, which I did and got the exact same error.

Then, on a whim, I simply mapped a folder to that drive letter (the one in the message). Any folder, some share out on the network, didn't matter what.

Viola! She workee!

Long story short, apparently MSI takes a snapshot of the drive (mapped or UNC) when you perform an administrative install. Then, when you attempt a client install from that admin install, if the drive that was in place at the time of the admin install doesn't exist, you get the 1327 error (or if you used a UNC path, an error 1606). From what I can tell, though, it doesn't actually use that drive for anything.

If you used a mapped drive, just creating a mapped drive with the same letter is enough to make MSI happy and continue with the client install.

If you used a UNC path, things aren't so rosy. In fact, I haven't found a recovery for this situation yet, though I suspect one is hiding under an MSI boulder somewhere.....waiting......

posted on Friday, June 08, 2007 6:44:27 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Friday, June 01, 2007

I've been hunting down an issue with an InstallShield Installation for almost a week now.

Very strange. I have a new installation that is a BASIC MSI install (meaning it contains no funky InstallScript at all, and is this fully MSI compliant).

It is intended to upgrade several previous installations, one of which is also a BASIC MSI, but the others are all InstallScript MSIs.

When I first started testing the upgrade process, I did the install of the old version, followed by an install of the new version. When I went to ADD REMOVE PROGRAMS, the new was there, but the old version was as well. The upgrade didn't work.

Grrr.

So I start digging. Eventually, I determined that the old version was actually being uninstalled (I paused the install midstream and sure enough, all the old files are one point are completely removed). However, for some reason, the entry in the Add Remove Programs list was not being removed.

More digging.

So I reset my test, installed the old version and at Macrovision's request, I searched the reg and found a key here:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{F1C8EEFE-8019-44AB-8AA9-D6F13E3BFAF0}]

that contained all the info about the old installation.

There's a value called NOREMOVE set to 1. Hmm, that sounds suspicious. So I set it to 0 and install my new version.

No joy, the old version is still listed in ARP. However, when I went back to the registry to check that key, it was gone! What the hell!? Ok, the entry in ARP must be coming from somewhere else. A few reg searches later turned up this key:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\InstallShield_{F1C8EEFE-8019-44AB-8AA9-D6F13E3BFAF0}]

Notice that the GUID there is the same as the other GUID, but this one has "InstallShield_" at the front of the key name.

Delete THAT key, and suddenly, the ARP entry is completely gone.

It would appear that upgrading an InstallScript based install with a BASIC MSI install unintentionally leaves behind a key that it shouldn't. Some searching the KBs with more specific keywords turned up exactly that.

An InstallScript based install created two entries in the Uninstall registry key, but one is 'hidden' from the ARP list view.

A Basic MSI install only creates one key. And if you upgrade an InstallScript based installation with a Basic MSI installation, that second key (the visible one) won't get removed properly.

You have to add an entry to the RemoveRegistry table in the MSI file and connect it to a component that will be installed by your new installation.

Didn't table-driven programming constructs die back in '91 with Magic. No, wait. Ack, they're still alive?!

Well, tried it then and hated it, still hate it today. To each his own.

posted on Friday, June 01, 2007 9:19:13 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [7] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Wednesday, May 23, 2007

So you've created an upgrade item with InstallShield (mine is 11.5), you've set everything up right as far as you can tell, and when you run in to upgrade a previous version, the installer pops up the "Modify/Repair/Uninstall" screen of the old version

Aha! You say. Forgot to change the Package code. So a GUID Generate and rebuild later, you try again and this time get this:

Another version of this product is already installed. Installation of this version cannot continue.

You got the Package Code different, Upgrade and Product Code the same in the two versions, and you've got a Major Upgrade item setup and configured to recognize the proper Old version number range.

What's up?

Come to find out, the IS help is a little confused on this topic. When you create a MAJOR UPGRADE to your installation (which, if my experience is any indication, almost EVERY upgrade is a major upgrade), you need to change both the Product Code and the Package Code! But here's the trick, the Upgrade Code stays the same.

Why? Because appearently, a Major Upgrade is considered an entirely new Product, even though it's not, because you intend it to upgrade older versions of the product.

But MSI doesn't use the Product Code for that, it uses the Upgrade Code for that purpose.

So, basic rule is:

When you create a new Version of your app's installation with InstallShield (or any MSI based Installer, I suspect), be sure to:

  1. Make sure you have an Upgrade Item setup to recognize the proper version range
  2. Make sure you generate a NEW PACKAGE CODE guid
  3. Make sure you generate a NEW PRODUCT CODE guid
  4. Make sure you DO NOT modify the UPGRADE CODE guid (basically, you almost never modify the Upgrade Code guid)
  5. Kneel before the holy altar and make an offering to the MSI gods.

Here's a handy table from a Macrovision support site article that also might help. Basically, it illustrates when a particular code needs to be changed (the X's), based on what kind of upgrade the new version of your install is.

Update Type Package Code Product Version Product Code Upgrade Code
Minor Upgrade without Patching X
Minor Upgrade with Patch X X
Major Upgrade X X X

You know, I whipped out an install in InnoSetup in, like, 5 minutes. And it's free.

posted on Wednesday, May 23, 2007 8:48:24 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [3] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Tuesday, May 15, 2007

Had an issue today where some automation code (basically VB that instantiates Word, Excel, or PowerPoint objects), started failing inexplicably.

The only thing the user could think of is that he'd just installed the lastest McAfee AntiVirus.

So, I tried a little test, opened Excel, opened the VB editor in it, then entered:

Sub Main
   Dim X as object
   Set x = CreateObject("Word.Application")
End sub

And that failed too!

After a few googles, I came up with this.

Appearently, McAfee includes a feature called HAWK (Hostle Activity Watch Kernel), that monitors things like CreateObject.

And the fun part is that even if you disable McAfee, HAWK still runs in the background. You have to turn it off seperately in the McAfee UI.

Yet another reason to use NOD32.

posted on Tuesday, May 15, 2007 10:22:41 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [4] • 
Kick it •  Add to del.icio.us •  View blog reactions; 
 Monday, May 07, 2007

We're switching a major project over to SQL Express 2005 from MSDE 2000, and in the process of doing so, I came to several discoveries.

  • MS Isn't releasing any MSI Merge Modules for 2005. Why? No idea. Appearently, that great MSI technology that they insist everyone else use isn't good enough for their own products.
  • With InstallShield anyway, there is no prerequisite support for Express 2005 in IS 11.5 and earlier. You must move to InstallShield 12. Joy.

I did, however find this article about sqlexpr32 command line switches which should allow you to perform the Express install from within a normal MSI install by just running the exe with the proper switches. Not ideal, but it's something.

posted on Monday, May 07, 2007 4:11:24 PM (Central Standard Time, UTC-06:00)   •  # •  Comments [0] • 
Kick it •  Add to del.icio.us •  View blog reactions;