Can Wix silently not overwrite a database - database

Wix can obviously prompt/tell the user that a database exists, and give them the choice to overwrite or to cancel the install. Unfortunately the user cannot specify to 'not overwrite' and carry on with the install.
Therefore, can Wix silently not overwrite a database? If the database is present, just ignore and carry onto the next instruction.
If not, is there another way to achieve the fact a reinstall needs to occur and the database is already in place?
Current my Wix fragment looks like this:
<Fragment>
<ComponentGroup Id="COMPG_MyProductDatabase" Directory="TARGETDIR">
<Component Id="COMPG_MyProductDatabase.sql" Guid="{...}">
<File Id="FILE_MyProductDatabase.sql" Source="..\MyProduct.Cache.Database\MyProduct.Deployment.sql" Name="MyProduct.Deployment.sql" KeyPath="yes" Checksum="yes"/>
</Component>
<Component Id='COMP_MyProductDatabase' Guid='{...}'>
<CreateFolder/>
<sql:SqlDatabase Id='DB_MyProductDatabase' Database='MyProduct' Server='[PROP_DATABASESERVERNAME]'
CreateOnInstall='yes' DropOnUninstall='no' ContinueOnError='yes' ConfirmOverwrite='yes'>
<sql:SqlScript Id='SQL_MyProductDatabase' BinaryKey='FILE_MyProductDatabase' ExecuteOnInstall='yes' />
</sql:SqlDatabase>
</Component>
</ComponentGroup>
<Binary Id='FILE_MyProductDatabase' SourceFile='..\MyProduct.Cache.Database\MyProduct.Deployment.sql' />
</Fragment>

Move the database creation into your SQL script then use SQL statements to do the conditional logic. Change the SqlDatabase elemnt to connect to 'master' for this to work.

Related

WiX: Installing to Multiple DB Targets

I have a set of DB scripts that I need to run during install. I have a UI screen that the user can select the server, provide credentials, and then select the target database. What I need to do is install the bulk of the scripts to the target database the user selected but some scripts need to go to the Master DB. I've tried searching the net for answers but I haven't really found anything that tells me how to do that. If someone has an article or suggestion on how this is accomplished, I would appreciate a little help.
Thanks
You can declare two SqlDatabase nodes, one for each database where the scripts have to be run:
<Binary Id="SqlScriptBinary1" SourceFile="script1.sql" />
<Binary Id="SqlScriptBinary2" SourceFile="script2.sql" />
<Component Id='SqlComponent.Sql1' Guid='YOUR-GUID-HERE' KeyPath='yes'>
<sql:SqlDatabase Id='Database1' Database='[DATABASE_NAME1]' Server='[DATABASE_SERVER]'
CreateOnInstall='no'
DropOnInstall='no' DropOnReinstall='no' DropOnUninstall='no'
ContinueOnError='no'>
<sql:SqlScript Id='SqlScript1' BinaryKey='SqlScriptBinary1' ExecuteOnInstall='yes' />
</sql:SqlDatabase>
</Component>
<Component Id='SqlComponent.Sql2' Guid='YOUR-GUID-HERE' KeyPath='yes'>
<sql:SqlDatabase Id='Database2' Database='[DATABASE_NAME2]' Server='[DATABASE_SERVER]' CreateOnInstall='no'
DropOnUninstall='no' DropOnInstall='no' DropOnReinstall='no' ContinueOnError='no'>
<sql:SqlScript Id='SqlScript2' BinaryKey='SqlScriptBinary2' ExecuteOnInstall='yes' />
</sql:SqlDatabase>
</Component>
Do a quick search and you'll find articles that may help you, such as this one for example.

Drop database from WiX installer

The properties [DATABASE_NAME] and [SERVER_NAME] are defined by the user at installation and it seems like unless they are hard coded then doing this fails:
<Component Id="Component.Sql.Database" Guid="*">
<sql:SqlDatabase
Id="Sql.Database"
Database="[DATABASE_NAME]"
Server="[SERVER_NAME]"
CreateOnInstall="yes"
DropOnUninstall="yes"
ContinueOnError="no"
ConfirmOverwrite="yes" />
</Component>
The bit that is supposed to drop the db is DropOnUninstall="yes"
I've found a post on the WiX user group suggesting the following approach to dropping the database on uninstall:
<Component Id="Component.Sql.DropDatabase" Guid="146CD264-1F6D-4E19-BFCC-E544F5BD2D6C">
<sql:SqlString
Id="Sql.DropDatabase"
SqlDb="Sql.Master"
Sequence="1000"
ExecuteOnInstall="no"
ExecuteOnUninstall="yes"
ExecuteOnReinstall="no"
ContinueOnError="no"
SQL="DROP DATABASE [\[][DATABASE_NAME]\[]]"/>
</Component>
<Fragment>
<sql:SqlDatabase Id="Sql.Master" Database="master" Server="[SERVER_NAME]" />
</Fragment>
The idea being that at uninstall the DROP DATABASE ... command is executed on the master database on the server. However this SQL statement never gets executed on the server.
The MSIEXEC log doesn't seem to give any information and I get no errors.
Has anyone successfully achieved this (before I write a custom action to do this)?
I've tried copying the database name and server to the registry to cache them, but this hasn't helped.
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" <!-- Need to import this -->
xmlns:sql="http://schemas.microsoft.com/wix/SqlExtension"><!-- Need to import this -->
<sql:SqlDatabase Id="SqlDatabase"
Database="TestDatabase"
Server="[SQLSERVER]"
DropOnUninstall="yes"
User="SQLUser">
This will definitely work.....

Wix: After move files from Component to another one - upgrade incorrect

I have 2 version of installer created by using wix. Old version differents of new version by files in components: some files from one component was moved to another one:
Was:
<!--OLD version-->
<Component Id="Component_1" Guid="{43E78920-7C99-412d-A69C-8017DA608D8D}">
<File DiskId='1' Name="File_1.dll"/>
<File DiskId='1' Name="File_2.dll"/>
</Component>
<Component Id="Component_2" Guid="{520261C3-0608-46d1-A284-6BED54DD525A}" KeyPath="yes">
<File DiskId='1' Name="File_3.dll"/>
</Component>
now:
<!--NEW version-->
<Component Id="Component_1" Guid="{43E78920-7C99-412d-A69C-8017DA608D8D}">
<File DiskId='1' Name="File_1.dll"/>
<File DiskId='1' Name="File_3.dll"/>
</Component>
<Component Id="Component_2" Guid="{520261C3-0608-46d1-A284-6BED54DD525A}" KeyPath="yes">
<File DiskId='1' Name="File_2.dll"/>
</Component>
File_3.dll move from "Component_2" to "Component_1" and File_2.dll move to "Component_2" from "Component_1".
All components included at the same Feature.
Now, after installation new version over old version result is next: File_3.dll is exist but other files has been deleted.
I wish new version only upgrade old version files.
How does resolve this problem?

Wix: Problem creating database with SqlFileSpec and SqlLogFileSpec Filename attribute set under c:\Program Files directory

I have a problem creating database with SqlFileSpec and SqlLogFileSpec Filename attribute set under c:\Program Files directory. I also checked that the folder (C:\Program Files\TestProject) already created. Does anyone know how to solve this?
This is the error:
Error 26201. Error -2147217900: failed to create SQL database: MyDatabase, error detail: CREATE DATABASE failed. Some file names listed could not be created. Check related errors..
<sql:SqlFileSpec Id="Mdf" Name="MyDatabase_Mdf" Filename="['INSTALLLOCATION']\MyDatabase.mdf" Size="3072KB" MaxSize="UNLIMITED" GrowthSize="1024KB"/>
<sql:SqlLogFileSpec Id="Ldf" Name="MyDatabase_log" Filename="['INSTALLLOCATION']\MyDatabase_log.ldf" Size="2048KB" MaxSize="2048GB" GrowthSize="10%"/>
...
<Property Id='INSTALLLOCATION'>C:\Program Files\TestProject</Property>
Thanks in advance.
The quotes around INSTALLLOCATION should be removed - use just [INSTALLLOCATION]. And make sure the mentioned files (mdf/ldf) are there by the time the action runs. Don't forget that the verbose log is your friend here.
Try this
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
xmlns:sql="http://schemas.microsoft.com/wix/SqlExtension">
<Product Name='SQL app 1.0' Id='DB501C18-86C7-4D14-AEC0-86416A69ABDE' Language='1033' Codepage='1252'
Version='1.0.0' Manufacturer='ABC Ltd.'>
<Package Id='????????-????-????-????-????????????' Keywords='Installer' Description="SQL App 1.0 Installer"
Comments='Comment.' Manufacturer='ABC Ltd.' InstallerVersion='100'
Languages='1033' Compressed='yes' SummaryCodepage='1252' />
<Media Id='1' Cabinet='Sample.cab' EmbedCab='yes' />
<User Id="MySQLUser" Name="[SQLUSER]" Password="[SQLUSERPASSWORD]"></User>
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder' Name='PFiles'>
<Directory Id='INSTALLDIR' Name='TestSQL'>
<Component Id="MySqlComponent" Guid="C50999A0-02FD-42d5-9F65-7375318DD328">
<SqlDatabase Id="MySqlDatabase" Database="MyDatabase" Server="[SQLSERVER]" Instance="[SQLINSTANCE]"
CreateOnInstall="yes" DropOnUninstall="yes" User="MySQLUser" ContinueOnError="yes">
<SqlScript Id="CreateDatabase" ExecuteOnInstall="yes" BinaryKey="CreateTablesBin"></SqlScript>
</SqlDatabase>
</Component>
</Directory>
</Directory>
</Directory>
<Binary Id="CreateTablesBin" src="CreateDatabase.sql"></Binary>
<Feature Id='Complete' Level='1' Description="Full" Title="Full Installation">
<ComponentRef Id='MySqlComponent' />
</Feature>
</Product>
</Wix>
CreateDatabase.sql file will contain the script to execute some script, create database, etc.
I've managed to fix my issue by using ".\SQLExpress2012" instead of "[MachineName]\SQLExpress2012" or "[ipAddress]\SQLExpress2012". I can only speculate that by doing the former, you might not be using TCP/IP method of connecting and using named pipes instead.
Also you might want to check your SQL Server Configuration and verify that your server instance support these connection methods.

Component Execution Order In Wix

Is there a way to ensure, either through specifying order or by specifying dependencies, that one component will execute before another in WiX?
Specifically, I'm trying to create a database, then, optionally, run a script on it. My Wix looks similar to this:
<ComponentGroup Id="SQLServerComponentGroup">
<Component Id="SQLServerIstallScriptWA" Guid="" >
<Condition>INSTALLDB</Condition>
<mssql:SqlDatabase Id="dbWA" Server="localhost" Database="[DATABASENAME]" CreateOnInstall="yes" ConfirmOverwrite="yes" DropOnReinstall="no" DropOnUninstall="yes">
<mssql:SqlScript Id="dbWAScript" ContinueOnError="no" ExecuteOnInstall="yes" ExecuteOnReinstall="no" Sequence="1" BinaryKey="MSSQLCreateDBBin" />
</mssql:SqlDatabase>
</Component>
<Component Id="SQLServerCreateUserWA" Guid="">
<Condition>INSTALLDB AND DBCREATEUSER = 1</Condition>
<mssql:SqlDatabase Id="dbWA" Server="localhost" Database="[DATABASENAME]">
<mssql:SqlString Id="dbWACreateUser" ContinueOnError="no" ExecuteOnInstall="yes" ExecuteOnReinstall="no" ExecuteOnUninstall="no" Sequence="1" SQL="" />
</mssql:SqlDatabase>
</Component>
</ComponentGroup>
I want to ensure that the SQLServerInstallScriptWA component is executed before SQLServerCreateUserWA component.
Components are not ordered. However, SqlScript and SqlString have Sequence attributes that can be used to impose order. The SqlScript and SqlString Sequence attributes happen to be ordered together to handle just this scenario.

Resources