SQL Server 2005 and ASP.NET

Does SQL Server 2005 Express Edition support features that are not supported by other editions, like Developer Edition?

I didn't know, but I ran into a problem today while trying out the Personal Web Site Starter Kit. In the web.config it had this connection string:

<add name="LocalSqlServer" connectionString="Data Source=.SQLExpress;Integrated Security=True;User Instance=True;AttachDBFilename=|DataDirectory|aspnetdb.mdf" />

Since my SQL Server 2005 Developer Edition instance is named SQL2005 I changed this to:

<add name="LocalSqlServer" connectionString="Data Source=.SQL2005;Integrated Security=True;User Instance=True;AttachDBFilename=|DataDirectory|aspnetdb.mdf" />

When trying to run the ASP.NET application, I got this exception:

[SqlException (0x80131904): The user instance login flag is not supported on this version of SQL Server. The connection will be closed.]

Googling for information gave me an answer in a forum by Scott Forsyth:

"The issue is that User Instancing, which allows the automatic creation of databases from code, isn't support on the full version of SQL 2005.  That is a function of SQL Express only.  The solution is to manually create the database in SQL Server 2005 and set a connection string to point to it.  You will also need to run aspnet_regsql.exe manually against the database if you will be using any of the new built-in database features of ASP.NET v2.0."

So I had to install Express Edition to get the application to work. It also means, the answer to the question in the first line is YES.

After the installation I had three instances of SQL Server running:

  • SQL Server 2000 Standard Edition
  • SQL Server 2005 Developer Edition
  • SQL Server 2005 Express Edition

These showed up in Process Explorer as three separate processes all running a version of sqlservr.exe. A little investigation, that involved comparing the digital signatures, showed that 2005 Developer and Express Edition have identical binaries for sqlservr.exe even though both are installed in a separate location. What was different is that the Developer instance was running under the local SYSTEM account whilst the Express instance was running under the local NETWORK SERVICE account.

Something interesting happened when I started the web application when connected to the Express Edition. A new sqlservr.exe process was fired up. This time running under the interactively logged-on account named Erwyn. When looking at the open handles I saw it had opened the master database in the Application Data directory for that user: P:Documents and SettingsErwynLocal SettingsApplication DataMicrosoftMicrosoft SQL Server DataSQLEXPRESSmaster.mdf. This explains what the User Instance=True part in the connection string does. I think it is supposed to increase security in a shared hosting environment to allow lower priviliged accounts to dynamically attach databases. In my case this dynamically created SQL Server instance actually got more rights than the normal one, because the Erwyn account has more rights than the NETWORK SERVICE account on my computer. This happened because the web application was running in the ASP.NET Development Server. This process runs under my interactively logged-on account and not under the ASPNET account. So I configured the ASP.NET application to run in IIS 5.1. When connecting to the application, another sqlservr.exe process was started. This process ran under the low-privileged ASPNET account.

Something I noticed is that the user instances of SQL Server Express did not spin down automatically when no longer in use. Also the user instances kept running when I restarted the SQL Server Express service.

The connection to the user instance from the process running the data-access code (aspnet_wp.exe or WebDev.WebServer.exe) is done using named pipes. Something like DeviceNamedPipe61A9EC07-5FDC-45tsqlquery.

The next thing I tried was to get Developer Edition to spin up a user instance. I copied the command-line parameters for a user instance spun up by Express Edition and changed the path to the Developer Edition binary. So I ran this from the command line:

"C:Program FilesMicrosoft SQL ServerMSSQL.2MSSQLBinnsqlservr.exe" -U"C:Program FilesMicrosoft SQL ServerMSSQL.3MSSQLTemplate Data" -d"P:Documents and SettingsErwynLocal SettingsApplication DataMicrosoftMicrosoft SQL Server DataSQLEXPRESS"master.mdf -l"P:Documents and SettingsErwynLocal SettingsApplication DataMicrosoftMicrosoft SQL Server DataSQLEXPRESS"mastlog.ldf -e"P:Documents and SettingsErwynLocal SettingsApplication DataMicrosoftMicrosoft SQL Server DataSQLEXPRESS"error.log -c -SSQLEXPRESS -s61A9EC07-5FDC-45 -w60

Notice how the value of the -s parameter is the name of the named pipe. This worked just fine. WebDev.WebServer.exe had troubles connecting to the broken named pipe, but the user instance was up-and-running.

So this still begged the question: what is the hidden flag to let Developer Edition refuse to start a user instance when asked to in the connection string. Remember, its binary is identical to that of SQL Server Express.

So I manually created a new service for the Developer Edition binary and started it:

sc create testsvc binpath= ""C:Program FilesMicrosoft SQL ServerMSSQL.2MSSQLBinnsqlservr.exe" -sSQLEXPRESS" type= own type= interact
net start testsvc

This indeed gave me an Express Edition-like instance capable of starting user instances. The key is the -sSQLEXPRESS command line argument. This tells SQL Server to use the SQLEXPRESS settings tree in the registry. Something in there tells sqlservr.exe how it should act.

Next I cloned the registry settings for the SQLEXPRESS instance to SQLEXPRESS2 and created another service for it. This amounts to manually creating another SQL Server instance. I also changed all the paths in that part of the registry to point to the Developer Edition installation. After changing the connection string in the ASP.NET application to SQLEXPRESS2, I connected to another Express Edition like instance, capable of starting user instances.

After some further experimentation I nailed it down to exactly one registry key: HKEY_LOCAL_MACHINESOFTWAREMicrosoftMicrosoft SQL ServerMSSQL.xSetupchecksum. Toggling its (binary) value between the Express Edition and Developer Edition values enables and disables the user instance feature for a Developer Edition installation.

The conclusion is: there is absolutely no technical reason why Developer Edition cannot support creating user instances, yet the Developer Edition refuses ;(

BTW: If you wonder what the point of all this is. I dunno. I was just inspired by Mark Russinovich's search that revealed the Sony Music Rootkit to go hunting on my machine.

One thought on “SQL Server 2005 and ASP.NET

Leave a Reply

Your email address will not be published. Required fields are marked *