using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.SqlClient; using System.Windows.Forms; using System.Text.RegularExpressions; using System.Management; using log4net; using System.Security.Principal; using AnywhereTS.DBSupport; namespace AnywhereTS { class DatabaseSupport { enum VersionCheck { Failed = 0, Equal, DatabaseIsMoreNew, DatabaseIsOlder, //DatabaseNotFound, DatabaseCreated, }; //private SqlConnection sqlCon = new SqlConnection(); //private SqlCommand sqlCmd = new SqlCommand(); const string SQL_BROWSER_SERVICE_NAME = "SQLBrowser"; public static string InstanceName { get { return AnywhereTS.DBSupport.Properties.Settings.Default.DBInstance; } } public bool SetupDatabase() { Exception ErrorInfo = null; try { bool bContinue = false; // Create a connection to SQL Server Logging.ATSAdminLog.Debug("SetupDatabase() called "); #region comment-code #region Database Creation support using (MsSqlConnector conn = new MsSqlConnector(ProSupport.strDatabaseServer, ProSupport.strDatabaseInstance, ATSGlobals.strDatabaseName)) { try { conn.CreateConnection(out ErrorInfo); conn.OpenConnection(out ErrorInfo); } catch (Exception ex) { try { conn.Dispose(); using (MsSqlConnector conn1 = new MsSqlConnector(ProSupport.strDatabaseServer, ProSupport.strDatabaseInstance, "master")) { try { conn1.CreateConnection(out ErrorInfo); conn1.OpenConnection(out ErrorInfo); // create datagbase Logging.ATSAdminLog.Info(string.Format("Creating Database {0}", ATSGlobals.strDatabaseName)); RunScript(SQLServerResources.CreateDatabase, conn1, out ErrorInfo); Logging.ATSAdminLog.Info(string.Format("Created Database {0}", ATSGlobals.strDatabaseName)); // create tables Logging.ATSAdminLog.Info(string.Format("Creating Tables in {0} Database", ATSGlobals.strDatabaseName)); RunScript(SQLServerResources.CreateTables, conn1, out ErrorInfo); Logging.ATSAdminLog.Info(string.Format("Created Tables in {0} Database", ATSGlobals.strDatabaseName)); } catch (Exception ex1) { if (ErrorInfo == null) { ErrorInfo = new Exception(ex1.Message, ex); throw ErrorInfo; } } } } catch (Exception ex1) { if (ErrorInfo == null) { ErrorInfo = new Exception(ex1.Message, ex); } throw ErrorInfo; } throw ErrorInfo; } } if (ErrorInfo != null) { throw ErrorInfo; } #endregion #region Database version check // Now that you are connected to Express, check the database versions Version databaseVersion; // The current version of the database int chkVer = CheckVersion(out databaseVersion); VersionCheck verChk = (VersionCheck)chkVer; //MessageBox.Show(string.Format("Version Check: {0} Version: {1}", verChk.ToString(), databaseVersion.ToString())); Logging.ATSAdminLog.InfoFormat("Database Version Check: {0} .... Database Version: {1}", verChk.ToString(), databaseVersion.ToString()); switch (chkVer) { case (int)VersionCheck.Equal: { bContinue = true; break; } case (int)VersionCheck.Failed: { bContinue = false; break; } case (int)VersionCheck.DatabaseIsOlder: { using (MsSqlConnector conn = new MsSqlConnector(ProSupport.strDatabaseServer, ProSupport.strDatabaseInstance, ATSGlobals.strDatabaseName)) { try { conn.CreateConnection(out ErrorInfo); conn.OpenConnection(out ErrorInfo); #region database upggrade scripts switch (databaseVersion.ToString()) { // Run the apropriate upgdrade script(s) case "1.0.0.0": { // Current database is version 1.0.0.0, update to 1.0.0.1 Logging.ATSAdminLog.InfoFormat("Upgrading Database from version: {0} to version: {1}", "1.0.0.0", "1.0.0.1"); bContinue = RunScript(SQLServerResources.UpdateDatabase1, conn, out ErrorInfo); Logging.ATSAdminLog.InfoFormat("Upgraded Database from version: {0} to version: {1}", "1.0.0.0", "1.0.0.1"); goto case "1.0.0.1"; // Continue and upgrade one more step } case "1.0.0.1": { // Current database is version 1.0.0.1, update to 1.0.0.2 Logging.ATSAdminLog.InfoFormat("Upgrading Database from version: {0} to version: {1}", "1.0.0.1", "1.0.0.2"); bContinue = RunScript(SQLServerResources.UpdateDatabase2, conn, out ErrorInfo); Logging.ATSAdminLog.InfoFormat("Upgraded Database from version: {0} to version: {1}", "1.0.0.2", "1.0.0.2"); goto case "1.0.0.2"; // Continue and upgrade one more step } case "1.0.0.2": { // Current database is version 1.0.0.2, update to 1.0.0.3 Logging.ATSAdminLog.InfoFormat("Upgrading Database from version: {0} to version: {1}", "1.0.0.2", "1.0.0.3"); bContinue = RunScript(SQLServerResources.UpdateDatabase3, conn, out ErrorInfo); Logging.ATSAdminLog.InfoFormat("Upgraded Database from version: {0} to version: {1}", "1.0.0.2", "1.0.0.3"); goto case "1.0.0.3"; // Continue and upgrade one more step } case "1.0.0.3": { // Current database is version 1.0.0.3, update to 1.0.0.4 Logging.ATSAdminLog.InfoFormat("Upgrading Database from version: {0} to version: {1}", "1.0.0.3", "1.0.0.4"); bContinue = RunScript(SQLServerResources.UpdateDatabase4, conn, out ErrorInfo); Logging.ATSAdminLog.InfoFormat("Upgraded Database from version: {0} to version: {1}", "1.0.0.4", "1.0.0.4"); break; } default: { //MessageBox.Show("Error: Not able to upgrade database (51188)"); if (databaseVersion == new Version(0, 0, 0, 0)) { string format = string.Format("Database version is {0}, this should have been auto upgraded to {1}", databaseVersion.ToString(), ATSGlobals.strDatabaseVersion); Logging.ATSAdminLog.Fatal(format); MessageBox.Show(format); } else { string format = string.Format("Failed to upgrade Database from version: {0} to version: {1}", databaseVersion.ToString(), ATSGlobals.strDatabaseVersion); Logging.ATSAdminLog.Fatal(format); MessageBox.Show(format); } break; } } #endregion } catch (Exception ex) { if (ErrorInfo == null) { ErrorInfo = ex; } throw ErrorInfo; } } break; } case (int)VersionCheck.DatabaseIsMoreNew: { bContinue = false; break; } default: { bContinue = false; break; } } #endregion #endregion return bContinue; } catch (Exception ex) { //if (ErrorInfo == null) //{ // ErrorInfo = ex; // using (log4net.NDC.Push(string.Format("{0}: MESSAGE={1}{2}Diagnostics:{2}{3}", ex.GetType().Name, ex.Message, System.Environment.NewLine, ex.ToString()))) // { // Logging.ATSAdminLog.Error(string.Format("Failed to setup database: {0}", ATSGlobals.strDatabaseName)); // } // throw ErrorInfo; //} //else //{ // using (log4net.NDC.Push(string.Format("{0}: MESSAGE={1}{2}Diagnostics:{2}{3}", ErrorInfo.GetType().Name, ErrorInfo.Message, System.Environment.NewLine, ErrorInfo.ToString()))) // { // Logging.ATSAdminLog.Error(string.Format("Failed to setup database: {0}", ATSGlobals.strDatabaseName)); // } // throw ErrorInfo; //} throw ex; } } public bool RunScript(string strFile, MsSqlConnector con, out Exception ErrorInfo) { ErrorInfo = null; string cmd = strFile.Replace("[DataDir]", ProSupport.strDatabasePath); con.RunScript(cmd, out ErrorInfo); return false; } // Check the version of the datbase public int CheckVersion(out Version vDb) { Exception ErrorInfo = null; //Get Version information from application Version v=new Version(ATSGlobals.strDatabaseVersion); vDb = new Version("0.0.0.0"); // Assign a default value for version try { //string strResult; int db_count = -1; //Verify that the AnywhereTS database exists #region Get Database Count using (MsSqlConnector conn = new MsSqlConnector(ProSupport.strDatabaseServer, ProSupport.strDatabaseInstance, ATSGlobals.strDatabaseName)) { try { conn.CreateConnection(out ErrorInfo); conn.OpenConnection(out ErrorInfo); //Logging.ATSAdminLog.Debug(string.Format("Getting Coount of {0} databases", ATSGlobals.strDatabaseName)); SqlCommand cmd = conn.CreateCommandInstance(string.Format("select count(*) from master..sysdatabases where name='{0}'", ATSGlobals.strDatabaseName), new List(), out ErrorInfo); db_count = Convert.ToInt32(cmd.ExecuteScalar()); Logging.ATSAdminLog.Info(string.Format("Found {0} databases named {1}", db_count, ATSGlobals.strDatabaseName)); } catch (Exception ex) { if (ErrorInfo == null) { ErrorInfo = ex; using (log4net.NDC.Push(string.Format("{0}: MESSAGE={1}{2}Diagnostics:{2}{3}", ex.GetType().Name, ex.Message, System.Environment.NewLine, ex.ToString()))) { Logging.ATSAdminLog.Error(string.Format("Failed to get count of databases named: {0}{1}", System.Environment.NewLine, ATSGlobals.strDatabaseName)); } throw ErrorInfo; } else { ErrorInfo = ex.GetBaseException(); using (log4net.NDC.Push(string.Format("{0}: MESSAGE={1}{2}Diagnostics:{2}{3}", ErrorInfo.GetType().Name, ErrorInfo.Message, System.Environment.NewLine, ErrorInfo.ToString()))) { Logging.ATSAdminLog.Error(string.Format("Failed to get count of databases named: {0}{1}", System.Environment.NewLine, ATSGlobals.strDatabaseName)); } throw ErrorInfo; } } } #endregion if (db_count == -1) { return (int)VersionCheck.Failed; } else if (db_count == 0) { #region Database Creation support using (MsSqlConnector conn = new MsSqlConnector(ProSupport.strDatabaseServer, ProSupport.strDatabaseInstance, ATSGlobals.strDatabaseName)) { try { conn.CreateConnection(out ErrorInfo); conn.OpenConnection(out ErrorInfo); } catch (Exception ex) { try { conn.Dispose(); using (MsSqlConnector conn1 = new MsSqlConnector(ProSupport.strDatabaseServer, ProSupport.strDatabaseInstance, "master")) { try { conn1.CreateConnection(out ErrorInfo); conn1.OpenConnection(out ErrorInfo); // create datagbase Logging.ATSAdminLog.Info(string.Format("Creating Database {0}", ATSGlobals.strDatabaseName)); RunScript(SQLServerResources.CreateDatabase, conn1, out ErrorInfo); Logging.ATSAdminLog.Info(string.Format("Created Database {0}", ATSGlobals.strDatabaseName)); // create tables Logging.ATSAdminLog.Info(string.Format("Creating Tables in {0} Database", ATSGlobals.strDatabaseName)); RunScript(SQLServerResources.CreateTables, conn1, out ErrorInfo); Logging.ATSAdminLog.Info(string.Format("Created Tables in {0} Database", ATSGlobals.strDatabaseName)); } catch (Exception ex1) { if (ErrorInfo == null) { ErrorInfo = new Exception(ex1.Message, ex); } throw ErrorInfo; } throw ErrorInfo; } } catch (Exception ex1) { if (ErrorInfo == null) { ErrorInfo = new Exception(ex1.Message, ex); } throw ErrorInfo; } } } if (ErrorInfo != null) { return (int)VersionCheck.Failed; } #endregion } #region Get Database Version using (MsSqlConnector conn = new MsSqlConnector(ProSupport.strDatabaseServer, ProSupport.strDatabaseInstance, ATSGlobals.strDatabaseName)) { try { conn.CreateConnection(out ErrorInfo); conn.OpenConnection(out ErrorInfo); //Logging.ATSAdminLog.Debug(string.Format("Getting Coount of {0} databases", ATSGlobals.strDatabaseName)); SqlCommand cmd = conn.CreateCommandInstance(string.Format("SELECT value from {0}..AppInfo where property='version'", ATSGlobals.strDatabaseName), new List(), out ErrorInfo); string version = (string)cmd.ExecuteScalar(); vDb = new Version(version); Logging.ATSAdminLog.Info(string.Format("Database {0} is at Version: {1}", ATSGlobals.strDatabaseName, version)); } catch (Exception ex) { if (ErrorInfo == null) { ErrorInfo = ex; using (log4net.NDC.Push(string.Format("{0}: MESSAGE={1}{2}Diagnostics:{2}{3}", ex.GetType().Name, ex.Message, System.Environment.NewLine, ex.ToString()))) { Logging.ATSAdminLog.Error(string.Format("Failed to get count of databases named: {0}{1}", System.Environment.NewLine, ATSGlobals.strDatabaseName)); } throw ErrorInfo; } else { ErrorInfo = ex.GetBaseException(); using (log4net.NDC.Push(string.Format("{0}: MESSAGE={1}{2}Diagnostics:{2}{3}", ErrorInfo.GetType().Name, ErrorInfo.Message, System.Environment.NewLine, ErrorInfo.ToString()))) { Logging.ATSAdminLog.Error(string.Format("Failed to get count of databases named: {0}{1}", System.Environment.NewLine, ATSGlobals.strDatabaseName)); } throw ErrorInfo; } } } #endregion #region old-code might still need //try //{ // //using (log4net.NDC.Push(string.Format("SQL Statment={0}", "SELECT value from {0}..AppInfo where property='version'", ATSGlobals.strDatabaseName))) // //{ // Logging.ATSAdminLog.Debug(string.Format("Getting {0} Database Version#1", ATSGlobals.strDatabaseName)); // sqlCon = new SqlConnection(Properties.Settings.Default.atsConnectionString.Replace(ATSGlobals.strDatabaseName, "master")); // if (sqlCon.State != ConnectionState.Open) sqlCon.Open(); // sqlCmd = new SqlCommand(string.Format("SELECT value from {0}..AppInfo where property='version'",ATSGlobals.strDatabaseName), sqlCon); // strResult = (string)sqlCmd.ExecuteScalar(); // sqlCon.Close(); // //} // Logging.ATSAdminLog.DebugFormat("{0} database version={1}",ATSGlobals.strDatabaseName, strResult); //} //catch(SqlException ex) //{ // // the database exists, but one or more tables are missing // using (log4net.NDC.Push(string.Format("SqlException: ID={0} MESSAGE={1}{2}Diagnostics:{2}{3}", ex.Number.ToString(), ex.Message, System.Environment.NewLine, ex.ToString()))) // { // Logging.ATSAdminLog.Error("Failed to get database version"); // } // try // { // //using (log4net.NDC.Push(string.Format("SQL Statment={0}", SQLServerResources.CreateTables))) // //{ // Logging.ATSAdminLog.Debug(string.Format("Creating Tables in {0} Database in CheckVersion()", ATSGlobals.strDatabaseName)); // sqlCon = new SqlConnection(Properties.Settings.Default.atsConnectionString.Replace(ATSGlobals.strDatabaseName, "master")); // if (sqlCon.State != ConnectionState.Open) sqlCon.Open(); // RunScript(SQLServerResources.CreateTables); // sqlCon.Close(); // //} // Logging.ATSAdminLog.Debug(string.Format("Created Tables in {0} Database in CheckVersion()", ATSGlobals.strDatabaseName)); // using (log4net.NDC.Push(string.Format("SQL Statment={0}", string.Format("SELECT value from {0}..AppInfo where property='version'", ATSGlobals.strDatabaseName)))) // { // Logging.ATSAdminLog.Debug(string.Format("Getting {0} Database Version#2", ATSGlobals.strDatabaseName)); // sqlCon = new SqlConnection(Properties.Settings.Default.atsConnectionString.Replace(ATSGlobals.strDatabaseName, "master")); // if (sqlCon.State != ConnectionState.Open) sqlCon.Open(); // sqlCmd = new SqlCommand(string.Format("SELECT value from {0}..AppInfo where property='version'", ATSGlobals.strDatabaseName), sqlCon); // strResult = (string)sqlCmd.ExecuteScalar(); // sqlCon.Close(); // } // Logging.ATSAdminLog.DebugFormat("{0} database version={1}",ATSGlobals.strDatabaseName, strResult); // } // catch(SqlException ex1) // { // using (log4net.NDC.Push(string.Format("SqlException: ID={0} MESSAGE={1}{2}Diagnostics:{2}{3}", ex1.Number.ToString(), ex1.Message, System.Environment.NewLine, ex1.ToString()))) // { // Logging.ATSAdminLog.Error("Failed to get database version"); // } // return (int)VersionCheck.Failed; // } //} #endregion //sqlCon.Close(); if (vDb == v) return (int)VersionCheck.Equal; if (vDb > v) return (int)VersionCheck.DatabaseIsMoreNew; else return (int)VersionCheck.DatabaseIsOlder; } catch (SqlException sql_ex) { MessageBox.Show(sql_ex.Number.ToString() + " " + sql_ex.Message.ToString()); using (log4net.NDC.Push(string.Format("SqlException: ID={0} MESSAGE={1}{2}Diagnostics:{2}{3}", sql_ex.Number.ToString(), sql_ex.Message, System.Environment.NewLine, sql_ex.ToString()))) { Logging.ATSAdminLog.Error("Failed to check database version"); } return (int)VersionCheck.Failed; } catch (Exception system_ex) { MessageBox.Show(system_ex.Message.ToString()); using (log4net.NDC.Push(string.Format("SqlException: MESSAGE={0}{1}Diagnostics:{1}{2}", system_ex.Message, System.Environment.NewLine, system_ex.ToString()))) { Logging.ATSAdminLog.Error("Failed to check database version"); } return (int)VersionCheck.Failed; } } [Obsolete("SetDatabaseRights() has been deperecated - user rights are assigned via SQL Server")] public static void SetDatabaseRights() { try { // Add an access control entry to the database file. ProSupport.GrantRWaccessForRemoteDesktopUsers(ProSupport.strDatabasePath + @"\" + ProSupport.strDatabaseFilename); ProSupport.GrantRWaccessForRemoteDesktopUsers(ProSupport.strDatabasePath + @"\" + ProSupport.strDatabaseFilename2); } catch (Exception e) { MessageBox.Show("Cannot set access rights for users to the database. Do you have the sufficient rights? Application will abort. Error: " + e.Message); using (log4net.NDC.Push(string.Format("SqlException: MESSAGE={0}{1}Diagnostics:{1}{2}", e.Message, System.Environment.NewLine, e.ToString()))) { Logging.ATSAdminLog.Fatal("Cannot set access rights for users to the database."); } Application.Exit(); return; } } public static void StartSQLbrowserService() { System.ServiceProcess.ServiceController srvController = new System.ServiceProcess.ServiceController(SQL_BROWSER_SERVICE_NAME); try { // Check that the SQL browser service is not already running if (srvController.Status != System.ServiceProcess.ServiceControllerStatus.Running) { // Service not running, start it. srvController.Start(); srvController.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running, TimeSpan.FromSeconds(50)); } } catch (Exception e) { MessageBox.Show("Could not start the SQL Browser service (13078). Error:" + e.Message); using (log4net.NDC.Push(string.Format("SqlException: MESSAGE={0}{1}Diagnostics:{1}{2}", e.Message, System.Environment.NewLine, e.ToString()))) { Logging.ATSAdminLog.Error("Could not start the SQL Browser service (13078)."); } } } // Configure the SQL browser service to autostart public static void AutostartSQLbrowserService() { try { //construct the management path string path = "Win32_Service.Name='" + SQL_BROWSER_SERVICE_NAME + "'"; using (ManagementObject service = new ManagementObject(new ManagementPath(path))) { object[] parameters = new object[1]; parameters[0] = "Automatic"; service.InvokeMethod("ChangeStartMode", parameters); } } catch(Exception e) { MessageBox.Show("Error, could not configure SQL Browser service (24888). Please check that SQL Server is intalled and that you are logged in with sufficient rights to configure services. Then retry the operation."); using (log4net.NDC.Push(string.Format("SqlException: MESSAGE={0}{1}Diagnostics:{1}{2}", e.Message, System.Environment.NewLine, e.ToString()))) { Logging.ATSAdminLog.Fatal("Could not configure SQL Browser service (24888). Please check that SQL Server is intalled and that you are logged in with sufficient rights to configure services. Then retry the operation."); } } } // Enable named pipes on the SQL Express server public static bool EnableNamedPipes() { ManagementScope manScope = new ManagementScope(@"\\.\root\Microsoft\SqlServer\ComputerManagement"); ManagementClass sqlServicesMan = new ManagementClass(manScope, new ManagementPath("SqlService"), null); ManagementClass serverProtocolsMan = new ManagementClass(manScope, new ManagementPath("ServerNetworkProtocol"), null); bool restarted = false; // Indicating if restart of SQL server was performed sqlServicesMan.Get(); serverProtocolsMan.Get(); foreach (ManagementObject prot in serverProtocolsMan.GetInstances()) { prot.Get(); if ((string)prot.GetPropertyValue("ProtocolName") == "Np" && //Named pipes (string)prot.GetPropertyValue("InstanceName") == InstanceName) { // We found the named pipes protocol if (!(bool)prot.GetPropertyValue("Enabled")) { // Named pipes not activated prot.InvokeMethod("SetEnable", null); // Activate named pipes // Check if user wants to restart SQL server DialogResult resultRights; resultRights = MessageBox.Show(string.Format("In order for users to use the AnywhereTS control panel, the {0} service on this computer need to be restarted. This operation might take up to 60 seconds. Do you want restart the {0} service now?", InstanceName), string.Format("AnywhereTS - Restart {0} (This operation might take up to 60 seconds!)", InstanceName), MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (resultRights == DialogResult.Yes) { // Restart the SQL server const uint sqlServerService = 1; const uint sqlServiceStopped = 1; foreach (ManagementObject svc in sqlServicesMan.GetInstances()) { if ((uint)svc.GetPropertyValue("SqlServiceType") == sqlServerService && (string)svc.GetPropertyValue("ServiceName") == string.Format("MSSQL${0}", InstanceName)) { svc.Get(); if ((uint)svc.GetPropertyValue("State") != sqlServiceStopped) { svc.InvokeMethod("StopService", null); } svc.InvokeMethod("StartService", null); restarted = true; } // end if } } } // end if 'named pipes protool' } } // foreach return restarted; } } }