Пример #1
0
        private ActivityResult RunSqlScript( InstallData installData, string sqlScriptFile, int consoleMessageReportFrequency, int progressbarEventFrequency, int percentOfStep, int startPercent )
        {
            ActivityResult result = new ActivityResult();
            result.Success = true;
            SqlConnection conn = null;

            string currentScript = string.Empty;

            try
            {
                string sql = System.IO.File.ReadAllText( sqlScriptFile );

                string connectionString = String.Format( "user id={0};password={1};server={2};Initial Catalog={3};connection timeout=10", installData.ConnectionString.Username, installData.ConnectionString.Password, installData.ConnectionString.Server, installData.ConnectionString.Database );
                conn = new SqlConnection( connectionString );
                conn.Open();

                RockScriptParser scriptParser = new RockScriptParser(sql);

                int sqlScriptCount = scriptParser.ScriptCount;
                int scriptsRun = 0;
                int scriptNextConsolePercentile = consoleMessageReportFrequency;
                int scriptNextProgressbarPercentile = progressbarEventFrequency;

                if ( consoleMessageReportFrequency != 0 )
                {
                    this.SendConsoleMessage( String.Format("There are {0} scripts to run.", sqlScriptCount) );
                }

                using ( SqlTransaction transaction = conn.BeginTransaction() )
                {
                    foreach ( var script in scriptParser.ScriptCollection )
                    {
                        currentScript = script;

                        if ( !string.IsNullOrWhiteSpace( script ) )
                        {
                            SqlCommand command = new SqlCommand( script, conn, transaction );
                            command.ExecuteNonQuery();
                        }

                        scriptsRun++;

                        // calculate current percentile
                        int currentPercentile = (int)(((double)scriptsRun / (double)sqlScriptCount) * 100);

                        // update console messages
                        if ( consoleMessageReportFrequency != 0 )
                        {
                            if ( sqlScriptCount == scriptsRun )
                            {
                                this.SendConsoleMessage( "100% of scripts run" );
                            }
                            else if ( currentPercentile >= scriptNextConsolePercentile )
                            {
                                this.SendConsoleMessage( currentPercentile + "% of scripts run" );
                                scriptNextConsolePercentile = currentPercentile + consoleMessageReportFrequency;
                            }
                        }

                        // update progress bar
                        if ( progressbarEventFrequency != 0 )
                        {
                            if ( sqlScriptCount == scriptsRun )
                            {
                                this.UpdateProgressBar( (int)(100 * (percentOfStep * .01)) + startPercent );
                            }
                            else if ( currentPercentile >= scriptNextProgressbarPercentile )
                            {
                                this.UpdateProgressBar( (int)(currentPercentile * (percentOfStep * .01)) + startPercent );
                                scriptNextProgressbarPercentile = currentPercentile + progressbarEventFrequency;
                            }
                        }
                    }

                    transaction.Commit();
                }
            }
            catch ( Exception ex )
            {
                result.Success = false;
                result.Message = ex.Message + " Current Script: " + currentScript;
            }
            finally
            {
                conn.Close();
                conn.Dispose();
            }

            return result;
        }
Пример #2
0
        private ActivityResult UnzipFile( string sourceFile, string destPath, int consoleMessageReportFrequency, int progressbarEventFrequency, int percentOfStep, int startPercent )
        {
            // consoleMessageReportFrequency - how often, in percents, should a console message be sent (0 = none)
            // progressbarEventFrequency - how often should a progress bar event be fired, in percents (0 = none)
            // percentOfStep - what percentage of this step is this unzip process
            // startPercent - what is the starting percentage to use for the progressbar

            ActivityResult result = new ActivityResult();
            result.Success = true;

            int zipFileCount = 0;
            int unzippedFiles = 0;
            int unzipNextConsolePercentile = consoleMessageReportFrequency;
            int unzipNextProgressbarPercentile = progressbarEventFrequency;

            try
            {
                using ( ZipFile zip = ZipFile.Read( sourceFile ) )
                {
                    zipFileCount = zip.Count;

                    // unzip each file updating console and progressbar
                    foreach ( ZipEntry e in zip )
                    {
                        e.Extract( destPath, ExtractExistingFileAction.OverwriteSilently );

                        unzippedFiles++;

                        // calculate current percentile
                        int currentPercentile = (int)(((double)unzippedFiles / (double)zipFileCount) * 100);

                        // update console messages
                        if ( consoleMessageReportFrequency != 0 )
                        {
                            if ( zipFileCount == unzippedFiles )
                            {
                                this.SendConsoleMessage( "100% unzipped" );
                            }
                            else if ( currentPercentile >= unzipNextConsolePercentile )
                            {
                                this.SendConsoleMessage( currentPercentile + "% unzipped" );
                                unzipNextConsolePercentile = currentPercentile + consoleMessageReportFrequency;
                            }
                        }

                        // update progress bar
                        if ( progressbarEventFrequency != 0 )
                        {
                            if ( zipFileCount == unzippedFiles )
                            {
                                this.UpdateProgressBar( (int)(100 * (percentOfStep * .01)) + startPercent );
                            }
                            else if ( currentPercentile >= unzipNextProgressbarPercentile )
                            {
                                int progressbarState = (int)(currentPercentile * (percentOfStep * .01)) + startPercent;
                                this.UpdateProgressBar( progressbarState );
                                unzipNextProgressbarPercentile = currentPercentile + progressbarEventFrequency;
                            }
                        }
                    }
                }
            }
            catch ( Exception ex )
            {
                result.Success = false;
                result.Message = ex.Message;
            }

            return result;
        }
Пример #3
0
        private ActivityResult InstallRockApp( InstallData installData )
        {
            ActivityResult result = new ActivityResult();
            result.Success = true;

            // if we're not in development unzip the file, otherwise we'll fake it... (for that full experience)
            if ( !installData.InstallerProperties.IsDebug )
            {
                this.SendConsoleMessage( "Preparing to unzip the rock application file." );

                // unzip the rock zip
                result = UnzipFile( serverPath + @"\" + rockSource, serverPath + @"\rock", 10, 1, 100, 0 );

                this.SendConsoleMessage( "Unzip complete." );
            }
            else
            {
                // fake it...
                for ( int i = 0; i <= 100; i++ )
                {
                    UpdateProgressBar( i );
                    Thread.Sleep( 100 ); // nap time...
                }
            }

            return result;
        }
Пример #4
0
        private ActivityResult RunSql( InstallData installData, string sqlFile )
        {
            ActivityResult result = new ActivityResult();
            result.Success = true;
            SqlConnection conn = null;

            try
            {
                string sql = System.IO.File.ReadAllText( sqlFile );

                string connectionString = String.Format( "user id={0};password={1};server={2};Initial Catalog={3};connection timeout=10", installData.ConnectionString.Username, installData.ConnectionString.Password, installData.ConnectionString.Server, installData.ConnectionString.Database );
                conn = new SqlConnection( connectionString );
                conn.Open();

                SqlCommand command = new SqlCommand( sql, conn );
                command.ExecuteNonQuery();

            }
            catch ( Exception ex )
            {
                result.Success = false;
                result.Message = ex.Message;
            }
            finally
            {
                conn.Close();
                conn.Dispose();
            }

            return result;
        }
Пример #5
0
        private ActivityResult DownloadRockStep( InstallData installData )
        {
            ActivityResult result = new ActivityResult();

            this.SendConsoleMessage( new ConsoleMessage( "--= Download Rock Step =--", ConsoleMessageType.Highlight ) );

            string rockURL = baseStorageUrl + installData.InstallerProperties.InstallVersion;
            this.SendConsoleMessage( "Downloading file: " + rockURL + "/Data/" + rockSource );

            result = DownloadFile( rockURL + "/Data/" + rockSource, serverPath + @"\" + rockSource, 10, 1 );

            if ( result.Success )
            {
                this.SendConsoleMessage( "File Download Complete!" );
            }

            return result;
        }
Пример #6
0
        private ActivityResult DownloadSqlStep(InstallData installData)
        {
            ActivityResult result = new ActivityResult();

            this.SendConsoleMessage( new ConsoleMessage( "--= Download SQL Step =--", ConsoleMessageType.Highlight ) );

            string serverDir = baseStorageUrl + installData.InstallerProperties.InstallVersion;
            this.SendConsoleMessage( "Downloading file: " + serverDir + "/Data/" + sqlScripts );

            result = DownloadFile( serverDir + "/Data/" + sqlScripts, serverPath + @"\" + sqlScripts, 10, 1 );

            this.SendConsoleMessage( "File Download Complete!" );

            return result;
        }
Пример #7
0
        private ActivityResult DownloadFile( string remoteFile, string localFile, int consoleMessageReportFrequency, int progressbarEventFrequency )
        {
            // solution from http://forums.xamarin.com/discussion/2022/threading-help

            // consoleMessageReportFrequency - how often, in percents, should a console message be sent (0 = none)
            // progressbarEventFrequency - how often should a progress bar event be fired, in percents (0 = none)

            ActivityResult result = new ActivityResult();
            result.Success = true;

            try
            {
                Uri url = new Uri( remoteFile );

                // Get the total size of the file
                System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create( url );
                System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse();
                response.Close();
                double dTotal = (double)response.ContentLength;

                // keeps track of the total bytes downloaded so we can update the progress bar
                Int64 iRunningByteTotal = 0;

                int nextProgressbarPercentToNotify = progressbarEventFrequency;
                int nextConsolePercentToNotify = consoleMessageReportFrequency;

                // use the webclient object to download the file
                using ( System.Net.WebClient client = new System.Net.WebClient() )
                {
                    // open the file at the remote URL for reading
                    using ( System.IO.Stream streamRemote = client.OpenRead( url ) )
                    {
                        // using the FileStream object, we can write the downloaded bytes to the file system
                        using ( Stream streamLocal = new FileStream( localFile, FileMode.Create, FileAccess.Write, FileShare.None ) )
                        {
                            // loop the stream and get the file into the byte buffer
                            int iByteSize = 0;
                            int bufferSize = 65536;
                            byte[] byteBuffer = new byte[bufferSize];

                            while ( (iByteSize = streamRemote.Read( byteBuffer, 0, byteBuffer.Length )) > 0 )
                            {
                                // write the bytes to the file system at the file path specified
                                streamLocal.Write( byteBuffer, 0, iByteSize );
                                iRunningByteTotal += iByteSize;

                                // calculate the progress out of a base "100"
                                double dIndex = (double)(iRunningByteTotal);
                                double dProgressPercentage = (dIndex / dTotal);
                                int iProgressPercentage = (int)(dProgressPercentage * 100);

                                // send console notifications
                                if ( consoleMessageReportFrequency != 0 )
                                {
                                    if ( iProgressPercentage == 100 )
                                    {
                                        this.SendConsoleMessage( "100% downloaded" );
                                    } else if ( iProgressPercentage >= nextConsolePercentToNotify )
                                    {
                                        this.SendConsoleMessage( nextConsolePercentToNotify.ToString() + "% downloaded" );
                                        nextConsolePercentToNotify += consoleMessageReportFrequency;
                                    }
                                }

                                // send progress bar notifications
                                if ( progressbarEventFrequency != 0 )
                                {
                                    if ( iProgressPercentage == 100 )
                                    {
                                        this.UpdateProgressBar( 100 );
                                    } else if ( iProgressPercentage >= nextProgressbarPercentToNotify )
                                    {
                                        this.UpdateProgressBar( iProgressPercentage );
                                        nextProgressbarPercentToNotify += progressbarEventFrequency;
                                    }
                                }
                            } // while..
                            streamLocal.Close();
                            streamLocal.Dispose();
                        }
                        streamRemote.Close();
                        streamRemote.Dispose();
                    }
                    client.Dispose();
                }
            }
            catch ( OutOfMemoryException mex )
            {
                result.Success = false;
                result.Message = @"The server ran out of memory while downloading Rock. You may want to consider using a server with more available resources or
                                    try installing again.";
            }
            catch ( Exception ex )
            {
                result.Success = false;
                result.Message = ex.Message;
            }

            return result;
        }
Пример #8
0
        private ActivityResult CreateDatabase( InstallData installData )
        {
            ActivityResult result = new ActivityResult();
            result.Success = true;

            this.SendConsoleMessage( new ConsoleMessage( "--= Creating Database =--", ConsoleMessageType.Highlight ) );

            // create database if needed
            if ( !RockEnvironmentChecks.CheckSqlDatabaseExists( installData.ConnectionString.Server, installData.ConnectionString.Username, installData.ConnectionString.Password, installData.ConnectionString.Database ) )
            {
                this.SendConsoleMessage( String.Format("Database {0} does not exist creating it.", installData.ConnectionString.Database) );

                string sql = String.Format("CREATE DATABASE [{0}]", installData.ConnectionString.Database);

                string connectionString = String.Format( "user id={0};password={1};server={2};connection timeout=10", installData.ConnectionString.Username, installData.ConnectionString.Password, installData.ConnectionString.Server );
                SqlConnection conn = new SqlConnection( connectionString );

                try
                {
                    conn.Open();
                    SqlCommand command = new SqlCommand( sql, conn );
                    command.ExecuteNonQuery();
                    this.SendConsoleMessage( String.Format("Database {0} created successfully.", installData.ConnectionString.Database) );
                }
                catch ( Exception ex )
                {
                    result.Success = false;
                    result.Message = ex.Message;
                }
                finally
                {
                    conn.Close();
                    conn.Dispose();
                }
            }
            else
            {
                this.SendConsoleMessage( String.Format( "Database {0} exists, will attempt to install using it.", installData.ConnectionString.Database ) );
            }

            // tease the user with a little progress
            this.UpdateProgressBar( 10 );

            // unzip sql files
            if ( result.Success )
            {
                this.SendConsoleMessage( "Unziping file: " + sqlScripts );
                string sqlZipFile = serverPath + @"\" + sqlScripts;
                result = UnzipFile( sqlZipFile, serverPath, 10, 1, 30, 10 );

                if ( result.Success )
                {
                    this.SendConsoleMessage( String.Format( "{0} sucessfully unzipped.", sqlScripts ) );
                }
            }

            // run sql install
            if ( result.Success )
            {
                this.SendConsoleMessage( "Preparing to run sql-install.sql" );

                result = RunSqlScript( installData, serverPath + @"\sql-install.sql", 10, 1, 60, 40 );

                if ( result.Success )
                {
                    this.SendConsoleMessage( String.Format( "Successfully ran sql-install.sql." ) );
                }
            }

            return result;
        }
Пример #9
0
        private ActivityResult ConfigureRock( InstallData installData )
        {
            ActivityResult result = new ActivityResult();
            result.Success = true;

            string tempWebConfig = serverPath + @"\webconfig.xml";

            this.SendConsoleMessage( new ConsoleMessage( "--= Configuring Rock =--", ConsoleMessageType.Highlight ) );

            string passwordKey = RockInstallUtilities.GeneratePasswordKey();

            // write connection string file
            result = WriteConnectionStringFile( installData.ConnectionString.Server, installData.ConnectionString.Database, installData.ConnectionString.Username, installData.ConnectionString.Password );
            if ( result.Success )
            {
                this.UpdateProgressBar( 20 );
                this.SendConsoleMessage( String.Format( "Successfully created web.ConnectionString.config." ) );
            }

            // create and run custom sql config
            if ( result.Success )
            {
                // download configure script
                string urlSqlConfigScript = baseStorageUrl + installData.InstallerProperties.InstallVersion + "/Data/" + sqlConfigureScript;
                string localSqlConfigScript = serverPath + @"\" + sqlConfigureScript;

                this.SendConsoleMessage( "Downloading SQL configuration script." );
                result = this.DownloadFile( urlSqlConfigScript, localSqlConfigScript, 0, 0 );

                if ( result.Success )
                {
                    this.SendConsoleMessage( "SQL configuration script downloaded." );

                    // merge settings
                    this.SendConsoleMessage( "Merging values into SQL config script." );
                    string sqlScript = System.IO.File.ReadAllText( localSqlConfigScript );
                    sqlScript = sqlScript.Replace( "{AdminPassword}", RockInstallUtilities.EncodePassword( installData.AdminUser.Password, "7E10A764-EF6B-431F-87C7-861053C84131", passwordKey ) );
                    sqlScript = sqlScript.Replace( "{AdminUsername}", SqlClean(installData.AdminUser.Username) );
                    sqlScript = sqlScript.Replace( "{PublicAppRoot}", RockInstallUtilities.CleanBaseAddress( installData.HostingInfo.ExternalUrl ) );
                    sqlScript = sqlScript.Replace( "{PublicAppSite}", RockInstallUtilities.GetDomainFromString( installData.HostingInfo.ExternalUrl ) );
                    sqlScript = sqlScript.Replace( "{InternalAppRoot}", RockInstallUtilities.CleanBaseAddress( installData.HostingInfo.InternalUrl ) );
                    sqlScript = sqlScript.Replace( "{InternalAppSite}", RockInstallUtilities.GetDomainFromString( installData.HostingInfo.InternalUrl ) );
                    sqlScript = sqlScript.Replace( "{OrgName}", SqlClean(installData.Organization.Name ));
                    sqlScript = sqlScript.Replace( "{OrgPhone}", SqlClean(installData.Organization.Phone ));
                    sqlScript = sqlScript.Replace( "{OrgEmail}", SqlClean(installData.Organization.Email ));
                    sqlScript = sqlScript.Replace( "{OrgWebsite}", SqlClean(installData.Organization.Website ));
                    sqlScript = sqlScript.Replace( "{SafeSender}", RockInstallUtilities.GetDomainFromEmail( installData.Organization.Email ) );
                    sqlScript = sqlScript.Replace( "{EmailException}", SqlClean(installData.Organization.Email ));
                    sqlScript = sqlScript.Replace( "{SmtpServer}", SqlClean(installData.EmailSettings.Server) );
                    sqlScript = sqlScript.Replace( "{SmtpPort}", installData.EmailSettings.Port );
                    sqlScript = sqlScript.Replace( "{SmtpUser}", SqlClean(installData.EmailSettings.RelayUsername ));
                    sqlScript = sqlScript.Replace( "{SmtpPassword}", SqlClean( installData.EmailSettings.RelayPassword ) );
                    sqlScript = sqlScript.Replace( "{SmtpUseSsl}", installData.EmailSettings.UseSsl.ToString() );

                    System.IO.File.WriteAllText( localSqlConfigScript, sqlScript );

                    this.SendConsoleMessage( "Values merged into SQL config script." );

                    // run sql configure script
                    this.SendConsoleMessage( "Running SQL config script." );
                    result = this.RunSql( installData, localSqlConfigScript );

                    if ( result.Success )
                    {
                        this.SendConsoleMessage( "Successfully ran SQL config script." );
                        this.UpdateProgressBar( 40 );
                    }
                    else
                    {
                        return result;
                    }
                }
            }

            // extract web.config
            string rockZipFile = serverPath + @"\" + rockSource;
            if ( result.Success )
            {
                this.SendConsoleMessage( "Extracting web.config file for edits." );

                try
                {
                    using ( FileStream fsZipFile = File.Create( tempWebConfig ) )
                    {
                        using ( ZipFile zip = ZipFile.Read( rockZipFile ) )
                        {
                            ZipEntry webConfigEntry = zip["web.config"];
                            webConfigEntry.Extract( fsZipFile );

                            // remove file from zip
                            zip.RemoveEntry( "web.config" );
                            zip.Save();
                        }
                    }

                    this.SendConsoleMessage( "Extracted web.config to webconfig.xml." );
                    this.UpdateProgressBar( 60 );
                }
                catch ( Exception ex )
                {
                    result.Success = false;
                    result.Message = ex.Message;
                }
            }

            try
            {
                // edit web.config
                XDocument document = XDocument.Load( tempWebConfig );

                // update timezone
                var node = document.Descendants( "appSettings" ).Elements( "add" ).Where( e => e.Attribute( "key" ).Value == "OrgTimeZone" ).FirstOrDefault();
                node.SetAttributeValue( "value", installData.HostingInfo.Timezone );

                // update password key
                node = document.Descendants( "appSettings" ).Elements( "add" ).Where( e => e.Attribute( "key" ).Value == "PasswordKey" ).FirstOrDefault();
                node.SetAttributeValue( "value", passwordKey );

                // update data encryption key
                string dataEncryptionKey = RockInstallUtilities.GeneratePasswordKey( 128 );
                node = document.Descendants( "appSettings" ).Elements( "add" ).Where( e => e.Attribute( "key" ).Value == "DataEncryptionKey" ).FirstOrDefault();
                node.SetAttributeValue( "value", dataEncryptionKey );

                // update machine key
                string validationKey = RockInstallUtilities.GenerateMachineKey( 64 );
                string decryptionKey = RockInstallUtilities.GenerateMachineKey( 32 );
                node = document.Descendants( "system.web" ).Elements( "machineKey" ).FirstOrDefault();
                node.SetAttributeValue( "validationKey", validationKey );
                node.SetAttributeValue( "decryptionKey", decryptionKey );

                document.Save( tempWebConfig );
            }
            catch ( Exception ex )
            {
                result.Success = false;
                result.Message = "An error occurred while customizing the web.config file for Rock. " + ex.Message;
            }

            this.UpdateProgressBar( 100 );
            return result;
        }
Пример #10
0
        private ActivityResult WriteConnectionStringFile( string server, string database, string username, string password )
        {
            ActivityResult result = new ActivityResult();
            result.Success = true;

            try
            {
                string configContents = String.Format( @"<add name=""RockContext"" connectionString=""Data Source={0};Initial Catalog={1}; User Id={2}; password={3};MultipleActiveResultSets=true"" providerName=""System.Data.SqlClient""/>", server, database, username, password );

                StreamWriter configFile = new StreamWriter( serverPath + "/web.ConnectionStrings.config", false );
                configFile.WriteLine( @"<?xml version=""1.0""?>" );
                configFile.WriteLine( @"<connectionStrings>" );
                configFile.WriteLine( "\t" + configContents );
                configFile.WriteLine( "</connectionStrings>" );
                configFile.Flush();
                configFile.Close();
                configFile.Dispose();
            }
            catch ( Exception ex )
            {
                result.Success = false;
                result.Message = ex.Message;
            }

            return result;
        }
Пример #11
0
        private ActivityResult DeleteInstaller( InstallData installData )
        {
            ActivityResult result = new ActivityResult();
            result.Success = true;

            // let's not delete the installer if we're in development, source control is nice but no use pressing our luck...
            if ( !installData.InstallerProperties.IsDebug )
            {

                try
                {
                    File.Delete( serverPath + @"Start.aspx" );
                    File.Delete( serverPath + @"Install.aspx" );
                    File.Delete( serverPath + @"InstallController.cs" );
                    File.Delete( serverPath + @"Startup.cs" );

                    File.Delete( serverPath + @"bin\Microsoft.AspNet.SignalR.Core.dll" );
                    File.Delete( serverPath + @"bin\Microsoft.AspNet.SignalR.SystemWeb.dll" );
                    File.Delete( serverPath + @"bin\Microsoft.Owin.dll" );
                    File.Delete( serverPath + @"bin\Microsoft.Owin.Host.SystemWeb.dll" );
                    File.Delete( serverPath + @"bin\Microsoft.Owin.Security.dll" );
                    File.Delete( serverPath + @"bin\Owin.dll" );

                    File.Delete( serverPath + @"bin\Ionic.Zip.dll" );
                    File.Delete( serverPath + @"bin\Microsoft.ApplicationBlocks.Data.dll" );
                    File.Delete( serverPath + @"bin\RockInstaller.dll" );
                    File.Delete( serverPath + @"bin\RockInstallTools.dll" );
                    File.Delete( serverPath + @"bin\Subtext.Scripting.dll" );
                }
                catch ( Exception ex )
                {
                    result.Success = false;
                    result.Message = ex.Message;
                }
            }
            else
            {
                // if it is a debug session let's do delete the connection string file
                File.Delete( serverPath + @"web.ConnectionStrings.config" );
            }

            // these files should be deleted even in the developer environment
            try
            {
                File.Delete( serverPath + @"\rock-install-latest.zip" );
                File.Delete( serverPath + @"\sql-config.sql" );
                File.Delete( serverPath + @"\sql-install.sql" );
                File.Delete( serverPath + @"\sql-latest.zip" );
                File.Delete( serverPath + @"\webconfig.xml" );
            }
            catch ( Exception ex )
            {
                result.Success = false;
                result.Message = ex.Message;
            }

            return result;
        }