|
hi
i want to include sql server express in prequisites of my deployment project, but i need it to be installed automatically when the installer run on the target machine. what should i do? | | AfCSharpLearner Tuesday, July 21, 2009 7:12 AM | when execute the setup.exe file it automatically installs the prerequisite (if not already not present on that machine)and then install the application.
If you install using the MSI file then the pre-resuisites are not installed.
:: Learning .NET ::- Marked As Answer byAfCSharpLearner Tuesday, July 21, 2009 9:09 AM
-
| | Prasant Swain Tuesday, July 21, 2009 8:17 AM | Create a deployment project and goto property of that project and click on the prerequisitebutton and add the SQL Express as pre-requisite (select the second option i.e download prerequisite from the same location as my application). :: Learning .NET :: | | Prasant Swain Tuesday, July 21, 2009 7:31 AM | it creates a folder including an .exe file. should i pre-install it or it will automatically installs it in only one wizard? | | AfCSharpLearner Tuesday, July 21, 2009 8:07 AM | when execute the setup.exe file it automatically installs the prerequisite (if not already not present on that machine)and then install the application.
If you install using the MSI file then the pre-resuisites are not installed.
:: Learning .NET ::- Marked As Answer byAfCSharpLearner Tuesday, July 21, 2009 9:09 AM
-
| | Prasant Swain Tuesday, July 21, 2009 8:17 AM | if i have done the above and also added my db backup using this: http://www.codeproject.com/KB/database/Deploy_your_database.aspxhow can i define a function in my packaged application that enables the users to backup their db every time they need to re-install the package? (inside my c# code). and also how can they restore it when they re-installed the application? thank you very much | | AfCSharpLearner Tuesday, July 21, 2009 8:29 AM | Why backup and restore? Why not just leave it? I don't know if this will help but here's how you can programmatically attach, detach and move a database. So if you want to,on install you can check if the database is on the computer, and if it's not you copy it from the install CD and attach it. If it's already there do nothing. Edit: If you want to do this during install you'll have to make it a Custom Action, search google for "visual studio custom install action" and there's a lot of information.
private void AttachDb(string filepath, bool detachMoveReattach)
{
try
{
string missingFiles = string.Empty;
foreach (string database in DB_NAMES)
foreach (string extension in EXTENSIONS)
{
string path = Path.Combine(filepath, database + extension);
if (!File.Exists(path))
{
if (missingFiles != string.Empty)
missingFiles += Environment.NewLine;
missingFiles += database + extension;
}
}
if (missingFiles != string.Empty)
throw new Exception("The following database files are missing:" + Environment.NewLine + missingFiles);
using (SqlConnection sqlConnection = new SqlConnection(GetConnectionString(MASTER_DB_NAME)))
{
sqlConnection.Open();
foreach (string database in DB_NAMES)
{
string mdfFilepath = Path.Combine(filepath, database + EXT_DATA);
string ldfFilepath = Path.Combine(filepath, database + EXT_LOG);
SqlCommand attachCmd = new SqlCommand(SQL_ATTACH, sqlConnection);
attachCmd.Parameters.Add(new SqlParameter("@Database", database));
attachCmd.Parameters.Add(new SqlParameter("@MdfFilepath", mdfFilepath));
attachCmd.Parameters.Add(new SqlParameter("@LdfFilepath", ldfFilepath));
attachCmd.ExecuteNonQuery();
}
// Gets rid of error
SqlConnection.ClearAllPools();
}
string successMessage = string.Empty;
if (detachMoveReattach)
successMessage = "Detach, move, and reattach successful.";
else
successMessage = "Attach successful.";
MessageBox.Show(successMessage, "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
btnAttachDb.Enabled = false;
btnDetachDb.Enabled = true;
btnDetachMove.Enabled = true;
btnDetachMoveReattach.Enabled = true;
}
catch (Exception ex)
{
MessageBox.Show("Error attaching databases." + Environment.NewLine + ex.Message);
}
}
private List<string> DetachDb(bool startOfChain)
{
try
{
List<string> filepaths = GetDbPaths();
using (SqlConnection sqlConnection = new SqlConnection(GetConnectionString(MASTER_DB_NAME)))
{
sqlConnection.Open();
foreach (string database in DB_NAMES)
{
SqlCommand singleUserCmd = new SqlCommand(string.Format(SQL_SINGLE_USER, database), sqlConnection);
singleUserCmd.ExecuteNonQuery();
SqlCommand detachCmd = new SqlCommand(SQL_DETACH, sqlConnection);
detachCmd.Parameters.Add(new SqlParameter("@Database", database));
detachCmd.ExecuteNonQuery();
}
}
string locationString = string.Empty;
if (filepaths.Count == 1)
locationString = "Folder containing database files:" + Environment.NewLine + filepaths[0];
else
{
locationString = "Locations of database files:";
foreach (string filepath in filepaths)
locationString += Environment.NewLine + filepath;
}
if (!startOfChain)
MessageBox.Show("Detach successful. " + locationString, "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
btnAttachDb.Enabled = true;
btnDetachDb.Enabled = false;
btnDetachMove.Enabled = false;
btnDetachMoveReattach.Enabled = false;
return filepaths;
}
catch (Exception ex)
{
MessageBox.Show("Error detaching databases." + Environment.NewLine + ex.Message);
}
return null;
}
private bool MoveDb(List<string> srcFilepaths, string destFilepath, bool detachAndMove, bool detachMoveReattach)
{
try
{
if (srcFilepaths.Count == 1)
{
string justPath = srcFilepaths[0];
srcFilepaths = new List<string>();
foreach (string database in DB_NAMES)
foreach (string extension in EXTENSIONS)
srcFilepaths.Add(Path.Combine(justPath, database + extension));
}
foreach (string filepath in srcFilepaths)
{
string destFilename = Path.Combine(destFilepath, Path.GetFileName(filepath));
File.Move(filepath, destFilename);
}
if (!detachMoveReattach)
{
string successMessage = string.Empty;
if (detachAndMove)
successMessage = "Detach and move successful.";
else
successMessage = "Move successful.";
MessageBox.Show(successMessage, "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
return true;
}
catch (Exception ex)
{
MessageBox.Show("Error copying databases." + Environment.NewLine + ex.Message);
}
return false;
}
- Edited byScottyDoesKnow Tuesday, July 21, 2009 2:29 PM
-
| | ScottyDoesKnow Tuesday, July 21, 2009 2:10 PM | ScottyDoesKnow, This is what I'm trying to do programmatically -- detach a SQLExpress database, move it, and reattach it -- from within a Windows Forms application, not as a prerequisite. This looks like it came from inside a Form. Can you share the source of DB_NAMES, EXTENSIONS, GetConnectionString, EXT_DATA, EXT_LOG, SQL_ATTACH, SQL_DETACH, GetDBPaths(), and MASTER_DB_NAME? Thx, RobinDotNet Click here to visit my ClickOnce blog! | | RobinDotNet Sunday, September 27, 2009 8:39 PM | Here they are, the stars are for privacy, they're obviously not in the code. The switch statement in GetDbPaths may be confusing, and to be honest it was a while ago I don't know why it only checks 1 and 4, 4 is because with 2 DBs there should be two mdf files and two ldf files, I don't know when 1 happens. Anyways, enjoy.
private const string CONNECTION_STRING = "Data Source=.\\SQLEXPRESS;Initial Catalog={0};Trusted_Connection=Yes;";
private const string MASTER_DB_NAME = "master";
private const string ****_DB_NAME = "****Data";
private const string ***_DB_NAME = "***Data";
private readonly string[] DB_NAMES = new string[] { ****_DB_NAME, ***_DB_NAME };
private const string EXT_DATA = ".mdf";
private const string EXT_LOG = "_log.ldf";
private readonly string[] EXTENSIONS = new string[] { EXT_DATA, EXT_LOG };
private const string SQL_DB_EXISTS = "SELECT * FROM sys.databases WHERE name = @Database";
private const string SQL_SINGLE_USER = "ALTER DATABASE {0} SET SINGLE_USER WITH ROLLBACK IMMEDIATE";
private const string SQL_DETACH = "EXEC sp_detach_db @Database";
private const string SQL_ATTACH = "EXEC sp_attach_db @Database, @MdfFilepath, @LdfFilepath";
private string GetConnectionString(string dbName)
{
return string.Format(CONNECTION_STRING, dbName);
}
private List<string> GetDbPaths()
{
List<string> filepaths = new List<string>();
foreach (string database in DB_NAMES)
using (SqlConnection sqlConnection = new SqlConnection(GetConnectionString(database)))
{
sqlConnection.Open();
SqlCommand getPathCmd = new SqlCommand("select physical_name from sys.database_files", sqlConnection);
using (SqlDataReader dataReader = getPathCmd.ExecuteReader())
while (dataReader.Read())
filepaths.Add(dataReader["physical_name"] as string);
}
List<string> filesToFind = new List<string>();
foreach (string database in DB_NAMES)
foreach (string extension in EXTENSIONS)
filesToFind.Add((database + extension).ToLower());
List<string> justPaths = new List<string>();
foreach (string filepath in filepaths)
if (filesToFind.Contains(Path.GetFileName(filepath).ToLower()))
justPaths.Add(Path.GetDirectoryName(filepath));
List<string> singlePath = justPaths.Distinct().ToList();
switch (singlePath.Count)
{
default:
case 0:
return null;
case 1:
return singlePath;
case 4:
return filepaths;
}
}
| | ScottyDoesKnow Monday, September 28, 2009 1:34 PM |
|