Monday, January 16, 2012

Install SQL Express from InstallShield Setup

InstallShield (assuming InstallShield 2010 for this post) has several project types for setup, such as Basic MSI project, InstallScript project, etc. Basically many setup programs can be implemented by using Basic MSI project. But if you want to more flexible handling in your setup program, pure InstallScript project might be better choice. One of tasks I did recently was to install SQL Express during product setup if user selects to install SQL Server Express.When I used Basic MSI project and created custom action to install SQL Express, I ran into SQL installation hang issue because SQL setup cannot acquire mutex . This is because MSI setup cannot call another MSI (nested MSI calls) during the run. Since product setup already got mutex, SQL setup couldn't acquire the mutex. One option I could use was to utilize Prerequistes. That is, if SQL Express is not installed on the machine, the SQL installation can be run as a setup prerequiste. This approach worked well without causing mutex error. But the problem was user might want to choose 'No SQL installation.' My conclusion is Basic MSI is not that flexible for this case.

So I went to use InstallScript project and I was able to call SQL Express setup by either calling custom action (that calls SQL setup.exe in C# DLL) or directly scripting SQL setup installation in InstallScript. The following code snippet is an example of calling SQL setup in InstallScript code.

function InstallSql()
    STRING szProgram, szCmdLine1, szCmdLine2;
begin  
    szProgram =  SRCDIR  ^ "SQLEXPR32_x86_ENU.exe";
    LongPathToQuote(szProgram,TRUE);
    szCmdLine1 = "/ACTION=Install /INSTANCENAME=SQLEXPRESS /FEATURES=SQLENGINE
 /QS /IACCEPTSQLSERVERLICENSETERMS=true /SQLSVCSTARTUPTYPE=Automatic /SQLSVCACCOUNT=\"NT AUTHORITY\\SYSTEM\" /BROWSERSVCSTARTUPTYPE=Disabled ";
    szCmdLine2 = "/ADDCURRENTUSERASSQLADMIN=true /TCPENABLED=1 /HIDECONSOLE";              
    LaunchAppAndWait(szProgram,szCmdLine1 ^ szCmdLine2,WAIT);
end;