Category Archives: Installations

Traipsing through MSI files with SuperOrca

Filed under Installations, Utilities

I’ve done a number of installs over the years (somehow, I seem to always end up with the installation project for whatever product I’m working on/with). It started way back when with a home grown solution, then on to a few minor products I can’t even recall now, then to Wise Installation System (back before Wise spoke MSI), then the little MSI setup project in Visual Studio, and eventually to InstallShield (oh how I miss Wise!).

MSI files are nice. They’re fairly well supported, powerful, capable.

But they can be god-awful difficult to get right sometimes.

And often, when things get tough, it’s often handy to be able to snoop directly into the MSI itself. Microsoft provides a tool called ORCA to do just that.


It’s decent. But, you can only get it via the SDK, which is a pretty hefty install. And it’s not great.

But then I happened upon a nifty little tool from the guys at, SuperOrca.


It’s a tiny download and fast install. It’s lightweight, but it’s got all the Orca goodness and then some, like an MSI compare function, and a nice search all function.

Now, InstallShield, and I’m guessing Wise also at this point, has a similar “raw MSI” mode, but, if you don’t have the scratch for those apps, SuperOrca might just be the ticket to shedding some light on your next vexing MSI problem.

Configuring Log4Net in a .net VSTO Word Addin

Filed under Code Garage, Installations, log4net, VB Feng Shui

VSTO (Visual Studio Tools for Office) is a great way to put together addins for the various MS Office applications (especially Word, Excel, and Outlook).

And Log4Net is a fantastic and unbelievably flexible logging framework for .net applications.

So naturally, I wanted to use them together.

And doing so is not bad at all, till it came to configuration…

A Disclaimer (with a note of Encouragement)

Log4Net is not the most straightforward package out there. It’s extremely flexible, and very easy to work with once you’ve gotten used to it, but getting into the Tao of the thing took a few days, for me, anyway.

Don’t let that discourage you. It really is a spectacular framework for handling virtually any aspect of logging in your applications. And it really doesn’t take much “setup code” at all to get it operational.

The Super Highway

The easiest way to configure log4net in a .net application (VSTO addins included) is to simply call Configure on the XMLConfigurator object:


That’ll work, but unfortunately, since your VSTO addin is a DLL, log4net will, by default, look in the current app.config file, which, if you’re running in Word, for instance, will be WinWord.exe.config in the folder where WinWord.exe lives.

Since WinWord.exe.config is Word’s config file, it’s probably not the best idea in the world to go shoe-horning your own (or log4net’s) config stuff in there as well. Not to mention how do you get your config information easily into that file during installation (or properly remove it during an uninstall).

The Scenic Byway

What you really want is for your VSTO addin DLL to have it’s own config file. Something that lives in the same folder as your DLL itself, and can easily be installed and removed.

Sure enough, that Configure method has an overload that accepts a FileInfo structure for an arbitrary XML Config file. So you can just do this:

Dim MyConfigFile = Me.GetType.Assembly.ManifestModule.Name & ".config"
If My.Computer.FileSystem.FileExists(MyConfigFile) Then
    Dim fi = My.Computer.FileSystem.GetFileInfo(MyConfigFile)
End If

What this does effectively is construct a filename based on the name of whatever assembly the current code is defined within, but with a “.config” extension.

It then checks for the existence of that file. Since there’s no path on the file, it only looks in the current directory, but that’s fine, since the config file will always be located in the same folder as it’s DLL.

And finally, if the file is found, it retrieves a FILEINFO object for it and configures Log4Net with that file.

Bumps along the Road

Unfortunately, that will get you farther, but not by much.

There are two problems.

  1. In debug mode in the IDE, the “current directory” is, indeed, the same folder as the one with your addin DLL in it. But, when running in release mode, in production, with Visual Studio completely out of the picture, the current directory is very likely the folder where WinWord.exe is located. Not good.
  2. Worse, in production, VSTO addins are generally copied to a “shadow cache” folder by the .net framework, so that the original files can be upgraded in place easily while the application is in use.

Unfortunately, your config will will not get copied to the shadow cache.

This means that for determining where to look for your config file, using something like:

  • Me.GetType.Assembly.CodeBase or
  • Me.GetType.Assembly.Location

won’t work, because often times, they’ll point you off into the wilds of the assembly cache folder and not  the \Program Files\MyCompany\MyProduct\ folder where you installed your addin and where you most likely would prefer your MyProduct.dll.config file to live.

Happy Trails

In the end, I found the best solution to be:

  1. Look in the “current directory” for your config file.
  2. If you find it, use it from there. This accommodated easy debugging while in the IDE because you can easily get to and edit your config file.
  3. If you don’t find it, construct the path to the app’s \Program Files\ folder and check there.
  4. If it’s not there either, just fall back to the default and call XMLConfigurator.Configure() with no parameters and let it default everything.

A routine that puts all that together looks like this:

Private Sub ConfigureLog4Net()
        Dim MyConfig = Me.GetType.Assembly.ManifestModule.Name & ".config"
        If Not My.Computer.FileSystem.FileExists(MyConfig) Then
            '---- not in current dir, so check in our Program Files folder
            Dim pth = Path.Combine(My.Computer.FileSystem.SpecialDirectories.ProgramFiles, My.Application.Info.CompanyName)
            pth = Path.Combinepth, My.Application.Info.ProductName)
            MyConfig = System.IO.Path.Combine(pth, MyConfig)
        End If
        If My.Computer.FileSystem.FileExists(MyConfig) Then
            Dim fi = My.Computer.FileSystem.GetFileInfo(MyConfig)
        End If
End Sub

To use this, you’ll need to make sure that your installation package installs your addin DLL and it’s config file into the \Program Files\Company Name\Product Name folder.

This is the pretty typical case, though, so that shouldn’t be a worry.

Later on Down the Road

This obviously begs the next question. What about other application settings? Log4Net reads stuff out of an arbtrary config file  you specify, but the My.Settings object does not. It’ll still end up looking in the default place, which is the host application’s config file (again, WinWord.exe.config, or Excel.exe.config, etc).

I hope to cover a decent solution to that in a later post.

Installing SQL Express 2008 Silently

Filed under Installations, SQL

I was recently upgrading an app from shipping SQL Express 2005 to 2008 and ran into a few surprises.

First, the command lines for the two installers are about as different as you can get.

The good news: The command line to extract files from the Self Extracting archive remains the same.

So, for SQL 2005 Express, you use this:

SQLEXPR32.EXE /Q /X:”{path to extract all SQL Installer files to}”

and for 2008 you use this

SQLEXPR_x86_ENU.EXE /Q /X:”{path to extract all SQL Installer files to}”

Typically, your install will drop the SQLEXPR32.EXE or SQLEXPR_x86_ENU.EXE files somewhere during the install, and then execute the above command line to extract all the necessary files to install SQL Express.

Then, you’ll use the command line discussed below to actually install SQL Express.

And finally, you’ll clean things up by deleting the EXE file above and all the extracted files used for the install.

The Bad News

Unfortunately, once you get the installation extracted, the command line to actually perform the installation is completely different.

For 2008, there are a huge number of command line parameters. Luckily, not all of them need to be specified to perform an unattended, nested install (ie an install of SQL Express 2008 from your own install). See here for a complete list of all the command line parameters available.

Obviously, your needs are going to dictate what options you have to specify. In my case, I needed a very bare bones installation, no fulltext search, reporting services, etc, and definitely no network support; this instance of SQL Express is intended to be accessed ONLY from the machine onto which it’s installed.

Given that, the command line is (all on one line):

{path to the SQL installation fileset you extracted above}setup.exe

Now, granted, that’s one gargantuan command line! Remember, the whole thing is executed as a single command. I’ve just put line breaks in so it’s readable. Also, keep in mind that you CAN specify all these parameters in a “response file” and then just pass it to the Setup.exe via the /CONFIGURATIONFILE parameter, like this:


But, that requires creating a separate text file, and potentially deleting or dealing with it afterward, so the command line route tends to work better for nested installations.

The key parameters to be concerned with are:

ACTION This has to be install.

INDICATEPROGRESS If the console window is shown during the install, this will cause a very verbose log of what is happening to be echoed to the console window as well as the install log file. If you hid the console window, this parameter doesn’t appear to have any effect.

QS This stands for Quiet Simple. In other words, the install will show a progress box but no other ui to the user. And no prompting.

FEATURES Determines what elements of SQL Express you want installed. Review the help page above for options, but the main thing to install is SQLENGINE.

HIDECONSOLE Very important. Without this switch, you’ll see a DOS box console window open up during the install. Very disconcerting and not even remotely appropriate for a user facing installation.

INSTANCEID and INSTANCENAME Usually, this should be SQLEXPRESS, though you may want to use a non-standard instance name in some cases.

SECURITYMODE and SAPWD You must provide a System Admin Password (the SAPWD) if you set SECURITYMODE to SQL. Also, keep in my that there may be group security policies in place on the machine that regulate the strength of the password (in other words, the SA password you choose, or that you allow your installer to choose, may need to be a certain length, contains numbers AND letters, etc).

TCPENABLED and NPENABLED These options enable or disable support network connections (TCP or Named Pipes). A 0 disables them, which is generally a good idea unless you have a reason to allow network connections into this SQL Express instance. In those cases, it’s usually best to require the installer to install SQL separately.

ADDCURRENTUSERASSQLADMIN This may or may not be appropriate depending on who is likely to be installing your package.

SQLSVCACCOUNT Actually all of the *SVCACCOUNT” options. These control the domain credentials to use for the various SQL Express services that are installed. You would either need to use the local SYSTEM account, as my example shows, or you’d need to prompt the user during the install to get the required domain login name and password. From a simplicity standpoint, using the local SYSTEM account is the most straightforward. But how you assign service account credentials will really depend on the app you’re installing.

So there you have it. Not hard, but not the same as SQL 2005 either.

New Debugging Option For InstallShield 2009

Filed under Installations, Troubleshooting

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, .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,,,, — 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}, .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.


But that DEBUGLOG switch definitely helped point the way.

Chained MSIs in InstallShield 2009

Filed under Installations

One of the big features new to Windows Installer 4.5 and InstallShield 2009 is the ability to chain MSI files. If you’re not familiar with the concept, MSI chaining is the ability for your installation to seamlessly install other installation packages without resorting to special case merge modules or other trickery.

Say your application needs to install SQL Express 2005. Set SQL Express up as a chained MSI and it will be seamlessly installed when your app is installed.

Now, at least some of this was possible under older versions of Windows Installer, but it wasn’t particularly pretty, or seamless.

However, start playing with it and the shine quickly wears off to reveal that, as usual, it’s a half-implemented feature.

The biggest problem I’ve run into so far? VSTO3.0.

Microsoft released VSTO 3.0 as a single SETUP.EXE. You can’t chain a SETUP.EXE though.

Strike one.

But, you CAN start the VSTO 3.0 installation, wait till it gets to it’s first screen, then grab all the contents of the installation that get dumped to a temp folder on the C: drive. In that bunch of files is the actual MSI that gets installed.

That MSI, you can chain just fine.

Ah, first base.

Try and deploy though and you’ll likely get messages about an interface having to do with SmartTags being missing. Come to find out, that was a big oops in the first release of VSTO 3.0, so Microsoft released VSTO 3.0 SP1. It also is a SETUP.EXE, but, upon extracting it, it actually consists of an MSP file (a PATCH) and not an MSI file.

And you cannot  chain a patch file.

Strike 2.

Now, normally, patches can be applied to an MSI as a transform to create a new MSI, complete with the patch. But it appears that the VSTO 3.0 SP1 patch wasn’t authored with that in mind, as I could never, even with the help of Accresso support, actually apply the patch to my VSTO 3.0 MSI file.

Strike 3. Game over.

In the end, I had to resort to InstallShield Prerequisites, workable, but not near as clean as chained MSI installations.

Getting InstallShield Prerequisite Conditions to Function Properly

Filed under Installations

Here’s the “Prerequisite condition editor” dialog from InstallShield 2009:


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.

.NET Interop and InstallShield

Filed under .NET, Installations

I’ve got a VSTO Com Addin for Word that I’m building an installation for. In the past, the addin had been handled via a DOT file, which is effective, but isn’t really the best way to build addins for Word, especially not now with VSTO.

At any rate, the product is working great, so I was putting an installation together.

I marked the particular assembly as .NET Interop, and when I built, IS complained that it couldn’t get the interop info from the assembly.


Huh? After some digging, turns out that InstallShield runs REGASM.EXE with the /REGFILE: switch to extract the COM registry information from the assembly, and then saves that in the MSI.

So, I tried running REGASM on my dev machine with the assembly.

REGASM MyName.MyAsm.dll /REGFILE:TestFile.reg

Worked perfectly.

So I tried it on my IS2009 box with the same assembly.

RegAsm : error RA0000 : Could not load file or assembly ‘Extensibility, Version=
7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ or one of its depe
ndencies. The system cannot find the file specified.


After scratching my head for a bit, I realized that my assemblies were compiled with .NET Framework 3.5, and that they definitely use some of the 3.5 specific features. It’d make sense that not having .NET 3.5 on the IS box could cause this.

So, a painstakingly lengthy .NET 3.5 install later, and I try the same regasm on my IS box.

No joy. Grrr.

So, I do what I should have done in the first place, open the project in Visual Studio and check the references. Sure enough, it points to an Extensibility.dll from the VSTO installation. Duh.

So, I go and install VSTO (to the InstallShield box, another grrr…)

No problems there, but still no joy.

Another look in the project and this Extensibility.dll lives with the VSTO V9.0 stuff. If I’m not mistaken, that means it’s an Office 2007 thing, not 2003 (which just happens to be the version of Office on the IS box).

Ok, maybe if I install the Office 2007 Primary Interop Assemblies?


More Grrr…

At this point, things are just irritating. I don’t want to install Office 2007 on what should ideally remain a more or less pristine dev box for doing install builds, so what next.

I know where this Extensibility.dll lives on my dev machine, I’m just not sure how REGASM looks for it, the GAC maybe, a search path (not likely), or some other arcana?

Screw it, I grab a copy of Extensibility.dll off my dev machine and copy it to the same folder as the DLL I’m trying to run regasm on.

RegAsm : error RA0000 : Could not load file or assembly ‘Microsoft.VisualStudio.
Tools.Applications.Runtime.v9.0, Version=, Culture=neutral, PublicKeyToke
n=b03f5f7f11d50a3a’ or one of its dependencies. The system cannot find the file

Aha! Similar message, different DLL! Now we’re getting somewhere.

Grab a copy of this “‘Microsoft.VisualStudio.Tools.Applications.Runtime.v9.0.dll” file off my dev machine, copy it to the same place and regasm again.

Repeat for another two dlls and REGASM will finally run through with no errors.

I’ve already had to pull TLBs and OLBs from Office installs for reference purposes in the application (for use on some dev boxes that don’t have either Office 2003 or 2007 installed), so grabbing a few more dlls for referencing purposes isn’t a big deal; they don’t have to be shipped with the application (they come with either VSTO or Office itself), and they can be checked into version control just like anything else.

In the end, I’m still not entirely convinced VSTO is a good way to build commercial addins for Office applications. It’s fine for quick and dirty internal projects, but it just seems to add a lot of additional complexity to releasing a commercial app. It’s harder to build a non-VSTO addin, but the end results may justify the extra effort.

Your mileage may vary.

Chained MSIs and Installation Order

Filed under Installations

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.


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:


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

Chained MSI Packages With InstallShield 2009

Filed under Installations

So, I’m attempting to upgrade an installation built with InstallShield 11.5, converting to the latest IS2009.

Things are clicking right along until a try and perform a build.



Yep, that’s the “correct” spelling.

Epic Fail.

Searching online didn’t yield much. Basically, all the posts I could find indicated that the problem was with the length of an Icon name in the ShortCuts table, but that didn’t apply here.

I’d just added several chained MSI packages (that’s just about the only reason to bother upgrading, virtually everything else about IS2009 is identical to 11.5, at least superficially, but that’s another story), so I was guessing that that had something to do with it.


I went back and removed my chained MSI. Recompiled. Worked!

Hmm. So I started re-adding them one by one.

Eventually, I got the the Office2007PIA msi. These are the Programmability Interop Files for Office 2007 (basically they make it easy for .NET apps to talk to the COM interfaces in Office apps).


After some headscratching, on a whim, I renamed the chained item (not the msi file itself, just the name of the item in InstallShield), and… back in business!

I had changed the name from Office2007PIA to O2007PIA.

Hmm, more experimenting and it looks like the limit is 9 characters.

This name appears to only be used internally, so it really doesn’t matter what it is.

I’m guessing this is an MSI bug, but IS should catch this sort of thing and prevent you from making this mistake. After all, that’s why you use it vs Orca, right? <sigh>

Being a Good Windows Citizen

Filed under Installations, Rants, VB Feng Shui

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:


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?