|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionIf you made an application that is using an SQL Server database that needs to be located on the client server, VS.NET Setup Project doesn't help too much, you could go for InstallShild or other product that will make things easy but the costs will get higher. So searching for a free solution I've found an article on MSDN about using the < sessionState
mode ="SQLServer"
stateConnectionString ="tcpip=127.0.0.1:42424"
sqlConnectionString ="data source=aleph;User ID=ASPsession;Password=ASPsession;"
cookieless ="false"
timeout ="60"
/>
For my web application to work on a client server, I need to make a MSI with my app and the SQL script. To run the script at install time I've made a .dll named Installer Class CodeFirst we declare a string conStr="packet size=4096;integrated security=SSPI;"+
"data source=\"(local)\";persist security info=False;"+
"initial catalog=master";
I use two functions that will return the connection string and the script content: private static string GetScript(string name)
{
Assembly asm = Assembly.GetExecutingAssembly();
Stream str = asm.GetManifestResourceStream(
asm.GetName().Name+ "." + name);
StreamReader reader = new StreamReader(str);
return reader.ReadToEnd();
}
private static string GetLogin(string databaseServer,
string userName,string userPass,string database)
{
return "server=" + databaseServer +
";database="+database+";User ID=" + userName +
";Password=" + userPass;
}
Then I use two functions that will run the install.txt and uninstall.txt onto the SQL server. The private static void ExecuteSql(SqlConnection sqlCon)
{
string[] SqlLine;
Regex regex = new Regex("^GO",RegexOptions.IgnoreCase | RegexOptions.Multiline);
string txtSQL = GetScript("install.txt");
SqlLine = regex.Split(txtSQL);
SqlCommand cmd = sqlCon.CreateCommand();
cmd.Connection = sqlCon;
foreach(string line in SqlLine)
{
if(line.Length>0)
{
cmd.CommandText = line;
cmd.CommandType = CommandType.Text;
try
{
cmd.ExecuteNonQuery();
}
catch(SqlException)
{
//rollback
ExecuteDrop(sqlCon);
break;
}
}
}
}
private static void ExecuteDrop(SqlConnection sqlCon)
{
if(sqlCon.State!=ConnectionState.Closed)sqlCon.Close();
sqlCon.Open();
SqlCommand cmd = sqlCon.CreateCommand();
cmd.Connection = sqlCon;
cmd.CommandText = GetScript("uninstall.txt");
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
sqlCon.Close();
}
Having the functions now we can override the public override void Install(IDictionary stateSaver)
{
base.Install (stateSaver);
if(Context.Parameters["databaseServer"].Length>0 &&
Context.Parameters["userName"].Length>0 &&
Context.Parameters["userPass"].Length>0)
{
conStr = GetLogin(
Context.Parameters["databaseServer"],
Context.Parameters["userName"],
Context.Parameters["userPass"],
"master");
RijndaelCryptography rijndael = new RijndaelCryptography();
rijndael.GenKey();
rijndael.Encrypt(conStr);
//save information in the state-saver IDictionary
//to be used in the Uninstall method
stateSaver.Add("key",rijndael.Key);
stateSaver.Add("IV",rijndael.IV);
stateSaver.Add("conStr",rijndael.Encrypted);
}
SqlConnection sqlCon = new SqlConnection(conStr);
sqlCon.Open();
ExecuteSql(sqlCon);
if(sqlCon.State!=ConnectionState.Closed)sqlCon.Close();
}
public override void Uninstall(IDictionary savedState)
{
base.Uninstall (savedState);
if(savedState.Contains("conStr"))
{
RijndaelCryptography rijndael = new RijndaelCryptography();
rijndael.Key = (byte[])savedState["key"];
rijndael.IV = (byte[])savedState["IV"];
conStr = rijndael.Decrypt((byte[])savedState["conStr"]);
}
SqlConnection sqlCon = new SqlConnection(conStr);
ExecuteDrop(sqlCon);
}
Setup ProjectNow that the installer class is done I can make a Setup project and add the primary output. In the User Interface Editor, select the Start node under Install. On the Action menu, choose Add Dialog. In the Add Dialog dialog box, select the Textboxes (A) dialog, then click OK to close the dialog box. On the Action menu, choose Move Up. Repeat until the Textboxes(A) dialog is above the Installation Folder node. Edit the properties of the Textboxes(A) form like this:
Go to the Custom Actions Editor and add the Primary output to the install and uninstall nodes. Click on the Primary output at the Install node and edit the properties. In the CustomActionData, type this: /databaseServer=[EDITA1] /userName=[EDITA2] /userPass=[EDITA3]
I am getting the values of the Text Boxes in the conStr = GetLogin(
Context.Parameters["databaseServer"],
Context.Parameters["userName"],
Context.Parameters["userPass"],
"master");
All is done now. Just build the two projects and you are ready to install the database. I hope you'll find this code useful, there are a lot of things that can be added to the code like storing safer the Key and IV of the History
|
||||||||||||||||||||||