Monthly Archives: September 2009

Installing SQL Express 2008 Silently

2
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
/INSTANCEID=[SQLINSTANCENAME]
/ACTION=Install
/INDICATEPROGRESS=True
/HIDECONSOLE
/FEATURES=SQLENGINE
/QS
/INDICATEPROGRESS=False
/INSTANCENAME=[SQLINSTANCENAME]
/AGTSVCSTARTUPTYPE=Manual
/ISSVCSTARTUPTYPE=Automatic
/ISSVCACCOUNT=”NT AUTHORITY\NetworkService”
/ASSVCSTARTUPTYPE=Automatic
/SQLSVCSTARTUPTYPE=Automatic
/SQLSVCACCOUNT=”NT AUTHORITY\SYSTEM”
/SECURITYMODE=[SECURITYMODE]
/SAPWD=[SAPWD]
/ADDCURRENTUSERASSQLADMIN=True
/TCPENABLED=0
/NPENABLED=0
/BROWSERSVCSTARTUPTYPE=Disabled
/RSSVCSTARTUPTYPE=Disabled
/RSINSTALLMODE=FilesOnlyMode

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:

SETUP.EXE /CONFIGURATIONFILE=”myresponsefile.rsp”

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.

DataContractSerializer is Not Necessarily Wonderful

0
Filed under .NET, VB Feng Shui, XML

Serializing objects in .NET is surprisingly easy, and there are a number of different ways to go about the process.

One method that was recently brought to my attention is the DataContractSerializer.

To use it, you’ll need to:

Imports System.Runtime.Serialization

Then create an new instance of a DataContractSerializer and a stream and finally, use the Serializer object to write a serialized version of some other object to the stream. I won’t delve into that code here, there’s plenty of examples on the web; even the Microsoft Help page for that object has a decent example.

But what you won’t find mentioned is how incredibly brittle the serializer can be.

First off, it doesn’t round trip the serialized XML, at least not completely. Say you serialize an object to an XML file, then EDIT that file and add comments. If you then deserialize and reserialize the object, you loose all your comments.

While this is somewhat understandable, it is rather unfortunate. Too bad that’s only the lesser of the problems you’ll face.

Another issue is one that plagues XML in general. It’s CASE SENSITIVE. This makes hand editing the files tricky at best. Now, I know a lot of you might say “Jeez, stop hand editing your XML!” but, let’s be realistic. Sometimes, that’s just flat the fastest way to deal with certain issues.

But the real stumper for me was when I recently discovered that the DataContractSerializer is highly dependent on the ORDER of the XML elements in the serialized XML! That’s right, get elements out of the order that the serializer expects them in (and yet still have perfectly legal and reasonable XML) and the serializer fails. But what’s worse is that it fails silently. It just simply fails to deserialize certain property values if their xml elements aren’t in the “proper” order (which happens to be alphabetic, but still, XML should not be order dependent).

There’s a short write up on it here, but even the author, Aarron Skonnard, doesn’t comment on the fact that if elements are out of order, they won’t deserialize properly.

From what I’ve read, that order dependency is partly why the DataContractSerializer is up to 10% faster than some other serialization techniques. And, if you know that your serialized objects will ONLY ever be touched by code that is intended to work with them, that’s probably ok.

But it’s something to be very aware of if you intend on the serialized XML being visible to (or editable by) actual people.

Finding the True File Location of an Executing .NET DLL

0
Filed under .NET, VB Feng Shui

image Say you’ve written a .NET DLL and you need to know from what folder that DLL was loaded (so you can find resources, config files, whatever).

There are any number of ways to skin that cat, but unfortunately, most won’t work in the general case, but only under certain special circumstances.

Matthew Rowan does a really good job of explaining the differences here, so I’m not going to repeat his post, but the short version of the story is, it takes code that looks like this:

Dim assemblyUri As Uri = New Uri(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase))
Return assemblyUri.LocalPath

Note that this is the VB version of Matthew’s clip. There a a number of other methods, but they all seem to return bogus results under various conditions.