/// <summary>
			/// Searches for plugins in the application's startup path
			/// </summary>
			/// <param name="viewer"></param>
			/// <returns>null if no plugins were found</returns>
			private TypeCollection InternalSearchForPluginTypes(IProgressViewer progressViewer)
			{				
				TypeCollection types = null;
				
				// starting in the startup path
				DirectoryInfo directoryInfo = new DirectoryInfo(Application.StartupPath);
				
				// look for all the dlls
				FileInfo[] files = directoryInfo.GetFiles("*.dll");

				// see if we can find any plugins defined in each assembly
				foreach (FileInfo file in files)
				{
					// try and load the assembly
					Assembly assembly = this.LoadAssembly(file.FullName);					
					if (assembly != null)
					{
                        ProgressViewer.SetExtendedDescription(progressViewer, string.Format("Searching for plugins. Searching '{0}'...", assembly.GetName().Name));

						// see if the assembly has any plugins defined in it
						TypeCollection typesInAssembly = this.LoadPluginTypesFromAssembly(assembly);						
						if (typesInAssembly != null)
						{
							if (types == null)
								types = new TypeCollection();

							// add the types defined as plugins to the master list
							types.AddRange(typesInAssembly);
						}
					}
				}

				return types;
			}
		/// <summary>
		/// Executes a search and returns 
		/// </summary>
		/// <param name="search"></param>
		/// <returns></returns>
		public ArrayList SearchForTypes(Search search, Type type, IProgressViewer progressViewer)
		{			
			_array = new ArrayList();
			_progressViewer = progressViewer;

			try
			{
				if (search == null)
					throw new ArgumentNullException("search", "The search cannot be null.");

				if (type == null)
					throw new ArgumentNullException("type", "The type to search for cannot be null.");

				// save the type that we are searching for
				_type = type;

				// bind to the search's events
				search.FileFound += new SearchEventHandler(this.OnFileFound);

				// start the search
				search.FindFiles();				
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.WriteLine(systemException);
			}
			// return the array list of items found
			return _array;
		}
        /// <summary>
        /// Stops the specified plugin.
        /// </summary>
        /// <param name="progressViewer">The callback object implementing IProgressViewer that will be used to monitor progress.</param>
        /// <param name="descriptor">The descriptor that contains the plugin to stop.</param>
        private static void StopPlugin(IProgressViewer progressViewer, PluginDescriptor descriptor)
        {
            ProgressViewer.SetExtendedDescription(progressViewer, string.Format("Stopping Plugin: '{0}'.", descriptor.PluginName));

            // stop the plugin
            descriptor.PluginInstance.OnStop(PluginContext.Current, new PluginDescriptorEventArgs(descriptor));
        }
示例#4
0
        /// <summary>
        /// Creates a new progress watcher.
        /// </summary>
        /// <param name="pm">Progress monitor to watch. Should be threadsafe (for example, ConcurrentProgressReporter).</param>
        /// <param name="updateFrequency">Frequency to update this view.</param>
        /// <param name="callbackState">State object to pass to the <see cref="progressChanged"/> event if you want one.</param>
        public AsyncProgressViewer(IProgressViewer pm, TimeSpan?updateFrequency = null, object callbackState = null)
        {
            if (pm == null)
            {
                throw new ArgumentNullException("pm");
            }

            _pm          = pm;
            _state       = callbackState;
            _cancellable = pm.cancellable;
            workComplete = pm.workComplete;
            totalWork    = pm.totalWork;
            task         = pm.task ?? string.Empty;
            cancelled    = pm.cancelled;

            if (!cancelled && !completed)
            {
                _timer          = new DispatcherTimer(DispatcherPriority.Background, Dispatcher);
                _timer.Tick    += onTick;
                _timer.Interval = updateFrequency ?? TimeSpan.FromSeconds(DEFAULT_UPDATE_FREQUENCY);
                _timer.Start();
            }
            else
            {
                _isTimerStopped = 1;
            }
        }
示例#5
0
        /// <summary>
        /// Executes a search and returns
        /// </summary>
        /// <param name="search"></param>
        /// <returns></returns>
        public ArrayList SearchForTypes(Search search, Type type, IProgressViewer progressViewer)
        {
            _array          = new ArrayList();
            _progressViewer = progressViewer;

            try
            {
                if (search == null)
                {
                    throw new ArgumentNullException("search", "The search cannot be null.");
                }

                if (type == null)
                {
                    throw new ArgumentNullException("type", "The type to search for cannot be null.");
                }

                // save the type that we are searching for
                _type = type;

                // bind to the search's events
                search.FileFound += new SearchEventHandler(this.OnFileFound);

                // start the search
                search.FindFiles();
            }
            catch (System.Exception systemException)
            {
                System.Diagnostics.Trace.WriteLine(systemException);
            }
            // return the array list of items found
            return(_array);
        }
示例#6
0
        /// <summary>
        /// Raises the EnteringMainMessageLoop event.
        /// </summary>
        /// <param name="e"></param>
        internal void OnEnteringMainMessageLoop(PluginContextEventArgs e)
        {
            Log.WriteLine("Entering PluginContext Message Loop.");
            EventManager.Raise <PluginContextEventArgs>(this.EnteringMessageLoop, this, e);

            _isInMessageLoop = true;
            _progressViewer  = null;
        }
        /// <summary>
        /// Instructs the AutoUpdateDownloader to query for the latest version available
        /// </summary>
        /// <param name="progressViewer">The progress viewer by which progress should be displayed</param>
        /// <param name="options">The options that affect this downloader</param>
        /// <param name="productToUpdate">The product descriptor for the product that should be updated</param>
        /// <param name="updateAvailable">The download descriptor that describes the download that could potentially occur</param>
        /// <returns></returns>
        public virtual bool QueryLatestVersion(
            IProgressViewer progressViewer,
            AutoUpdateOptions options,
            AutoUpdateProductDescriptor productToUpdate,
            out AutoUpdateDownloadDescriptor updateAvailable)
        {
            updateAvailable = null;

            return(false);
        }
		/// <summary>
		/// Instructs the AutoUpdateDownloader to query for the latest version available 
		/// </summary>
		/// <param name="progressViewer">The progress viewer by which progress should be displayed</param>
		/// <param name="options">The options that affect this downloader</param>
		/// <param name="productToUpdate">The product descriptor for the product that should be updated</param>
		/// <param name="updateAvailable">The download descriptor that describes the download that could potentially occur</param>
		/// <returns></returns>
		public virtual bool QueryLatestVersion(
			IProgressViewer progressViewer,
			AutoUpdateOptions options,
			AutoUpdateProductDescriptor productToUpdate, 
			out AutoUpdateDownloadDescriptor updateAvailable)
		{			
			updateAvailable = null;

			return false;							
		}
        /// <summary>
        /// Validates the dependencies for each of the PluginDescriptors
        /// </summary>
        /// <param name="progressViewer">The callback object implementing IProgressViewer that will be used to monitor progress.</param>
        /// <param name="descriptors">The collection of PluginDescriptors that describe the Plugins to be loaded.</param>
        public static void ValidatePluginDependencies(IProgressViewer progressViewer, PluginDescriptorCollection descriptors)
        {
            /*
             * Validation Phases
             * Phase 1: Direct		(First level dependencies)
             * Phase 2: Indirect	(Second level dependencies. i.e., dependencies of dependencies. Requires that Phase 1 already executed)
             * Phase 3: Extended	(Provider Validation)
             * */

            // Phase 1: Checks descriptors for missing dependencies and circular references. (direct)
            foreach (PluginDescriptor descriptor in descriptors)
            {
                try
                {
                    // check for missing dependencies
//					MarkDescriptorIfMissingDependency(descriptor, descriptors);
                    if (!descriptor.IsMissingDependency)
                    {
                        // check for circular references between plugins (direct, does not check dependency chains)
                        MarkDescriptorIfCircularlyDependent(descriptor, descriptors);
                    }
                }
                catch (Exception ex)
                {
                    Log.WriteLine(ex);
                }
            }

            // Phase 2: Checks depencencies for missing dependencies and circular references. (indirect)
            foreach (PluginDescriptor descriptor in descriptors)
            {
                try
                {
                    //
                    if (!descriptor.IsMissingDependency && !descriptor.IsCircularlyDependent)
                    {
                        MarkDescriptorIfDependenciesAreMissingDependencyOrAreCircularlyDependent(descriptor, descriptors);
                    }
                }
                catch (Exception ex)
                {
                    Log.WriteLine(ex);
                }
            }

            // Phase 3: Allow for Provider based validation?

            /*
             * Here we have an extension point.
             * If we created another provider who's sole purpose was to validate a PluginDescriptor,
             * we could move this logic away from the core, and allow for validation to be extended.
             * Possible reasons for doing this would be to prevent Plugins from being loaded based
             * on some other criteria. We could provide descriptions of why a particular descriptor failed validation.
             * */
        }
		public static void SetDescription(IProgressViewer viewer, string text)
		{
			try
			{
				if (viewer != null)
					viewer.SetDescription(text);
			}
			catch(Exception ex)
			{
				Trace.WriteLine(ex);
			}
		}
        /// <summary>
        /// Updates the display of the specified progress dialog
        /// </summary>
        /// <param name="progressViewer"></param>
        /// <param name="bytesReceived"></param>
        /// <param name="bytesTotal"></param>
        public virtual void SetDownloadProgress(IProgressViewer progressViewer, long bytesReceived, long bytesTotal)
        {
            double p       = ((double)bytesReceived / (double)bytesTotal) * 100;
            int    percent = (int)p;

            string title       = string.Format("AutoUpdate Progress..." + "({0}% Completed)", percent.ToString());
            string received    = this.FormatFileLengthForDisplay(bytesReceived);
            string total       = this.FormatFileLengthForDisplay(bytesTotal);
            string description = string.Format("Progress: ({0} of {1} downloaded)", received, total);

            ProgressViewer.SetTitle(progressViewer, title);
            ProgressViewer.SetExtendedDescription(progressViewer, description);
        }
		/// <summary>
		/// Instructs the AutoUpdateDownloader to query for the latest version available 
		/// </summary>
		/// <param name="progressViewer">The progress viewer by which progress should be displayed</param>
		/// <param name="options">The options that affect this downloader</param>
		/// <param name="productToUpdate">The product descriptor for the product that should be updated</param>
		/// <param name="updateAvailable">The download descriptor that describes the download that could potentially occur</param>
		/// <returns></returns>
		public override bool QueryLatestVersion(IProgressViewer progressViewer, AutoUpdateOptions options, AutoUpdateProductDescriptor productToUpdate, out AutoUpdateDownloadDescriptor updateAvailable)
		{
			updateAvailable = null;
			
			try
			{
				// create a manual web service proxy based on the url specified in the options
				Debug.WriteLine(string.Format("Creating a web service proxy to the following url.\n\tThe web service url is '{0}'.", options.WebServiceUrl), MY_TRACE_CATEGORY);			
				AutoUpdateWebServiceProxy service = new AutoUpdateWebServiceProxy(options.WebServiceUrl);

				// use the web service to query for updates
				Debug.WriteLine(string.Format("Querying the web service for the latest version of '{0}'.\n\tThe current product's version is '{1}'.\n\tThe current product's id is '{2}'.\n\tThe web service url is '{3}'.", productToUpdate.Name, productToUpdate.Version.ToString(), productToUpdate.Id, options.WebServiceUrl), MY_TRACE_CATEGORY);			
				XmlNode node = service.QueryLatestVersion(productToUpdate.Name, productToUpdate.Version.ToString(), productToUpdate.Id);
				
				// if the service returned no results, then there is no update availabe
				if (node == null)
				{
					// bail out 
					Debug.WriteLine(string.Format("No updates are available from the web service at '{0}' for this product.", options.WebServiceUrl), MY_TRACE_CATEGORY);
					return false;
				}

				// otherwise create a reader and try and read the xml from the xml node returned from the web service
				XmlAutoUpdateManifestReader reader = new XmlAutoUpdateManifestReader(node);

				// using the reader we can recreate the manifeset from the xml
				AutoUpdateManifest manifest = reader.Read();	

				/*
				* now create a download descriptor that says, yes we have found an update.
				* we are capable of downloading it, according to these options.
				* the autoupdate manager will decide which downloader to use to download the update
				* */
				updateAvailable = new AutoUpdateDownloadDescriptor(manifest, this, options);
				
				// just to let everyone know that there is a version available
				Debug.WriteLine(string.Format("Version '{0}' of '{1}' is available for download.\n\tThe download url is '{2}'.\n\tThe size of the download is {3}.", updateAvailable.Manifest.Product.Version.ToString(), updateAvailable.Manifest.Product.Name, updateAvailable.Manifest.UrlOfUpdate, this.FormatFileLengthForDisplay(updateAvailable.Manifest.SizeOfUpdate)), MY_TRACE_CATEGORY);

				// we've successfully queried for the latest version of the product to update
				return true;
			}
			catch(ThreadAbortException)
			{

			}
			catch (WebException ex)
			{
                Debug.WriteLine(ex.Message, MY_TRACE_CATEGORY);
			}
			return false;
		}
示例#13
0
        /// <summary>
        /// Attempts to start the newest version of the executable named the same thing as the executing assembly
        /// </summary>
        /// <param name="versionedDirectories"></param>
        /// <param name="versionStarted"></param>
        /// <returns></returns>
        private bool StartNewestVersion(
            Assembly executable,
            VersionedDirectory[] versionedDirectories,
            out VersionedDirectory versionStarted,
            IProgressViewer progressViewer)
        {
            versionStarted = null;

            try
            {
                // get the name of this assembly which will be what we look for to start
                string assemblyName = string.Format("{0}.exe", executable.GetName().Name);

                // will start with the newest version because they are sorted
                foreach (VersionedDirectory versionToStart in versionedDirectories)
                {
                    // format the path to the version we are going to attempt to start
                    string path = Path.Combine(versionToStart.Directory.FullName, assemblyName);

                    bool started = false;

                    // if the file exists
                    if (File.Exists(path))
                    {
                        ProgressViewer.SetExtendedDescription(progressViewer, "Bootstrap: Starting version " + versionToStart.Version.ToString() + "...");

                        Process p = new Process();
                        p.StartInfo.FileName         = path;
                        p.StartInfo.Arguments        = System.Environment.CommandLine;
                        p.StartInfo.WorkingDirectory = versionToStart.Directory.FullName;
                        p.StartInfo.WindowStyle      = Process.GetCurrentProcess().StartInfo.WindowStyle;

                        // try to start this version
                        started = p.Start();
                    }

                    // if a version was started
                    if (started)
                    {
                        // keep track of which version we started
                        versionStarted = versionToStart;
                        return(true);
                    }
                }
            }
            catch (System.Exception systemException)
            {
                System.Diagnostics.Trace.WriteLine(systemException);
            }
            return(false);
        }
 public static void SetMargueeMoving(IProgressViewer viewer, bool moving, bool reset)
 {
     try
     {
         if (viewer != null)
         {
             viewer.SetMarqueeMoving(moving, reset);
         }
     }
     catch (Exception ex)
     {
         Trace.WriteLine(ex);
     }
 }
 public static void SetHeading(IProgressViewer viewer, string text)
 {
     try
     {
         if (viewer != null)
         {
             viewer.SetHeading(text);
         }
     }
     catch (Exception ex)
     {
         Trace.WriteLine(ex);
     }
 }
 public static void SetExtendedDescription(IProgressViewer viewer, string text)
 {
     try
     {
         if (viewer != null)
         {
             viewer.SetExtendedDescription(text);
         }
     }
     catch (Exception ex)
     {
         Trace.WriteLine(ex);
     }
 }
        /// <summary>
        /// Instructs the AutoUpdateDownloader to query for the latest version available
        /// </summary>
        /// <param name="progressViewer">The progress viewer by which progress should be displayed</param>
        /// <param name="options">The options that affect this downloader</param>
        /// <param name="productToUpdate">The product descriptor for the product that should be updated</param>
        /// <param name="updateAvailable">The download descriptor that describes the download that could potentially occur</param>
        /// <returns></returns>
        public override bool QueryLatestVersion(IProgressViewer progressViewer, AutoUpdateOptions options, AutoUpdateProductDescriptor productToUpdate, out AutoUpdateDownloadDescriptor updateAvailable)
        {
            updateAvailable = null;

            try
            {
                // create a manual web service proxy based on the url specified in the options
                Debug.WriteLine(string.Format("Creating a web service proxy to the following url.\n\tThe web service url is '{0}'.", options.WebServiceUrl), MY_TRACE_CATEGORY);
                AutoUpdateWebServiceProxy service = new AutoUpdateWebServiceProxy(options.WebServiceUrl);

                // use the web service to query for updates
                Debug.WriteLine(string.Format("Querying the web service for the latest version of '{0}'.\n\tThe current product's version is '{1}'.\n\tThe current product's id is '{2}'.\n\tThe web service url is '{3}'.", productToUpdate.Name, productToUpdate.Version.ToString(), productToUpdate.Id, options.WebServiceUrl), MY_TRACE_CATEGORY);
                XmlNode node = service.QueryLatestVersion(productToUpdate.Name, productToUpdate.Version.ToString(), productToUpdate.Id);

                // if the service returned no results, then there is no update availabe
                if (node == null)
                {
                    // bail out
                    Debug.WriteLine(string.Format("No updates are available from the web service at '{0}' for this product.", options.WebServiceUrl), MY_TRACE_CATEGORY);
                    return(false);
                }

                // otherwise create a reader and try and read the xml from the xml node returned from the web service
                XmlAutoUpdateManifestReader reader = new XmlAutoUpdateManifestReader(node);

                // using the reader we can recreate the manifeset from the xml
                AutoUpdateManifest manifest = reader.Read();

                /*
                 * now create a download descriptor that says, yes we have found an update.
                 * we are capable of downloading it, according to these options.
                 * the autoupdate manager will decide which downloader to use to download the update
                 * */
                updateAvailable = new AutoUpdateDownloadDescriptor(manifest, this, options);

                // just to let everyone know that there is a version available
                Debug.WriteLine(string.Format("Version '{0}' of '{1}' is available for download.\n\tThe download url is '{2}'.\n\tThe size of the download is {3}.", updateAvailable.Manifest.Product.Version.ToString(), updateAvailable.Manifest.Product.Name, updateAvailable.Manifest.UrlOfUpdate, this.FormatFileLengthForDisplay(updateAvailable.Manifest.SizeOfUpdate)), MY_TRACE_CATEGORY);

                // we've successfully queried for the latest version of the product to update
                return(true);
            }
            catch (ThreadAbortException)
            {
            }
            catch (WebException ex)
            {
                Debug.WriteLine(ex.Message, MY_TRACE_CATEGORY);
            }
            return(false);
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="progressViewer"></param>
 /// <param name="configurationProviders"></param>
 public static void InstructConfigurationProvidersToLoad(IProgressViewer progressViewer, ConfigurationProviderCollection configurationProviders)
 {
     foreach (ConfigurationProvider provider in configurationProviders)
     {
         try
         {
             provider.Load(progressViewer);
         }
         catch (Exception ex)
         {
             Log.WriteLine(ex);
         }
     }
 }
 public static void SetImage(IProgressViewer viewer, Image image)
 {
     try
     {
         if (viewer != null)
         {
             viewer.SetImage(image);
         }
     }
     catch (Exception ex)
     {
         Trace.WriteLine(ex);
     }
 }
示例#20
0
        /// <summary>
        /// Cleanup any managed resources
        /// </summary>
        protected override void DisposeOfManagedResources()
        {
            base.DisposeOfManagedResources();

            if (_configurationProviders != null)
            {
                _configurationProviders.Dispose();
                _configurationProviders = null;
            }

            //if (_encryptionProviders != null)
            //{
            //    _encryptionProviders.Dispose();
            //    _encryptionProviders = null;
            //}

            if (_pluginProviders != null)
            {
                _pluginProviders.Dispose();
                _pluginProviders = null;
            }

            if (_windowProviders != null)
            {
                _windowProviders.Dispose();
                _windowProviders = null;
            }

            if (_pluginDescriptors != null)
            {
                _pluginDescriptors.Dispose();
                _pluginDescriptors = null;
            }

            if (_instanceManager != null)
            {
                _instanceManager.Dispose();
                _instanceManager = null;
            }

            if (_gcTimer != null)
            {
                _gcTimer.Dispose();
                _gcTimer = null;
            }

            _commandLineArgs = null;
            _progressViewer  = null;
        }
        /// <summary>
        /// Creates instances of the Plugin type defined by each PluginDescriptor.
        /// </summary>
        /// <param name="progressViewer">The callback object implementing IProgressViewer that will be used to monitor progress.</param>
        /// <param name="descriptors">The collection of PluginDescriptors that describe the Plugins to be loaded.</param>
        public static void CreatePluginInstances(IProgressViewer progressViewer, PluginDescriptorCollection descriptors)
        {
            Log.WriteLine("Creating Plugins. # of Plugins: '{0}'.", descriptors.Count.ToString());

            foreach (PluginDescriptor descriptor in descriptors)
            {
                if (descriptor.IsStartable)
                {
                    if (AreDependenciesCreated(descriptor, descriptors))
                    {
                        CreatePluginInstance(progressViewer, descriptor);
                    }
                }
            }
        }
示例#22
0
//		/// <summary>
//		/// Finds and creates all SnapIn classes discovered using the specified search.
//		/// </summary>
//		/// <param name="search"></param>
//		/// <param name="outputWindow"></param>
//		/// <returns></returns>
//		public static SnapInInfoCollection FindAndCreateSnapIns(Search search, IProgressViewer progressViewer)
//		{
//			SnapInInfoCollection snapIns = new SnapInInfoCollection();
//			try
//			{
//				AppDomain domain = AppDomain.CreateDomain(Guid.NewGuid().ToString());
//				SnapInProvider provider = (SnapInProvider)domain.CreateInstanceFromAndUnwrap(System.Reflection.Assembly.GetExecutingAssembly().Location, typeof(SnapInProvider).FullName);
//				ArrayList array = provider.SearchForTypes(search, typeof(ISnapIn), progressViewer);
//				AppDomain.Unload(domain);
//
//				if (array != null)
//				{
//					foreach(RuntimeClassProviderEventArgs e in array)
//					{
//						object runTimeObject = SnapInProvider.CreateSnapInFrom(e.Assembly, e.Type, progressViewer);
//						if (runTimeObject != null)
//						{
//							snapIns.Add(e.Assembly, e.Type, (ISnapIn)runTimeObject);
//
////							if (outputWindow != null)
////								outputWindow.Write("Created SnapIn...Created SnapIn '" + e.Type.FullName + "'"); // from '" + e.Assembly.Location + "'");
////
////							System.Diagnostics.Trace.WriteLine("Created SnapIn '" + e.Type.FullName + "' from '" + e.Assembly.Location + "'", typeof(SnapInProvider).Name);
//						}
//					}
//				}
//			}
//			catch(System.Exception systemException)
//			{
//				System.Diagnostics.Trace.WriteLine(systemException);
//			}
//			return snapIns;
//		}

        public static ArrayList FindSnapIns(Search search, IProgressViewer progressViewer)
        {
            try
            {
                AppDomain      domain   = AppDomain.CreateDomain(Guid.NewGuid().ToString());
                SnapInProvider provider = (SnapInProvider)domain.CreateInstanceFromAndUnwrap(System.Reflection.Assembly.GetExecutingAssembly().Location, typeof(SnapInProvider).FullName);
                ArrayList      array    = provider.SearchForTypes(search, typeof(ISnapIn), progressViewer);
                AppDomain.Unload(domain);
                return(array);
            }
            catch (System.Exception systemException)
            {
                System.Diagnostics.Trace.WriteLine(systemException);
            }
            return(new ArrayList());
        }
            /// <summary>
            /// Searches for plugin types from assemblies in the application's startup path in a second AppDomain
            /// </summary>
            /// <param name="viewer"></param>
            /// <returns></returns>
            internal static TypeCollection SearchForPluginTypes(IProgressViewer progressViewer)
            {
                // create a new appdomain where we'll try and load the plugins
                AppDomain domain = AppDomain.CreateDomain(Guid.NewGuid().ToString());

                // create an instance of the plugin loader in the new appdomain
                TypeLoader loader = (TypeLoader)domain.CreateInstanceFromAndUnwrap(
                    Assembly.GetExecutingAssembly().Location,
                    typeof(TypeLoader).FullName);

                // use the loader to search for plugins inside the second appdomain
                TypeCollection types = loader.InternalSearchForPluginTypes(progressViewer);

                // unload the appdomain
                AppDomain.Unload(domain);

                // return the plugin descriptors that were found
                return(types);
            }
        /// <summary>
        /// Creates an instance of the Type described by the PluginDescriptor and asserts that it derives from Plugin.
        /// </summary>
        /// <param name="progressViewer">The callback object implementing IProgressViewer that will be used to monitor progress.</param>
        /// <param name="descriptor">The PluginDescriptor that contains the Type to create.</param>
        private static void CreatePluginInstance(IProgressViewer progressViewer, PluginDescriptor descriptor)
        {
            try
            {
                TypeUtilities.AssertTypeIsSubclassOfBaseType(descriptor.PluginType, typeof(Plugin));

                string message = string.Format("Creating Plugin: '{0}'.", descriptor.PluginName);
                ProgressViewer.SetExtendedDescription(progressViewer, message);
                Log.WriteLine(message);

                Plugin plugin = (Plugin)TypeUtilities.CreateInstanceOfType(descriptor.PluginType, Type.EmptyTypes, new object[] {});

                descriptor.AttachPluginInstance(plugin);
            }
            catch (Exception ex)
            {
                Log.WriteLine(ex);
            }
        }
        /// <summary>
        /// Stops the plugins defined in the collection that have been created.
        /// </summary>
        /// <param name="progressViewer">The callback object implementing IProgressViewer that will be used to monitor progress.</param>
        /// <param name="descriptors">The collection of PluginDescriptors that describe the Plugins to be loaded.</param>
        public static void StopPlugins(IProgressViewer progressViewer, PluginDescriptorCollection descriptors)
        {
            Log.WriteLine("Stopping Plugins. # of Plugins: '{0}'.", descriptors.Count.ToString());

            // fire the BeforePluginsStopped event of the PluginContext
            PluginContext.Current.OnBeforePluginsStopped(new PluginContextEventArgs(PluginContext.Current));

            // stop all of the plugins
            foreach (PluginDescriptor descriptor in descriptors)
            {
                if (descriptor.PluginInstance != null)
                {
                    StopPlugin(progressViewer, descriptor);
                }
                else
                {
                    Log.WriteLine(string.Format("Skipped Plugin: '{0}' was not created.", descriptor.PluginName));
                }
            }
        }
        /// <summary>
        /// Called when the provider should load the configuration it is managing.
        /// </summary>
        public virtual void Load(IProgressViewer progressViewer)
        {
            // read or create the local user configuration
            ProgressViewer.SetExtendedDescription(progressViewer, string.Format("Loading '{0}' configuration...", this.ConfigurationName));

            ConfigurationProvidersManager.ReadOrCreateConfiguration(
                CarbonConfig.Verbose,
                this.ConfigurationName,
                this.FullPath,
                out _configuration,
                this.GetEncryptionEngine(),
                this.FormatConfiguration);

            if (this.Configuration != null)
            {
                this.Configuration.TimeToSave += new EventHandler(OnConfigurationTimeToSave);

                // by default we'll add this to the list so that the configuration shows up in the options dialog
                ConfigurationProvidersManager.EnumeratingConfigurations += new EventHandler <XmlConfigurationManagerEventArgs>(OnConfigurationProvidersManagerEnumeratingConfigurations);
            }
        }
		/// <summary>
		/// Uses the PluginProviders specified to load Plugin Types that will be used to create Plugins.
		/// </summary>
		/// <param name="progressViewer">The callback object implementing IProgressViewer that will be used to monitor progress.</param>
		/// <param name="pluginProviders">The collection of PluginProviders that will be used to load the Plugin Types from their various sources.</param>
		/// <returns></returns>
		public static TypeCollection LoadPluginTypes(IProgressViewer progressViewer, PluginProviderCollection pluginProviders)
		{
			TypeCollection pluginTypes = new TypeCollection();
			foreach (PluginProvider provider in pluginProviders)
			{
				try
				{
					Log.WriteLine("Loading Plugin Types. PluginProvider: '{0}'.", provider.Name);

					TypeCollection types = provider.LoadPluginTypes(progressViewer);
					if (types != null)
					{
						pluginTypes.AddRange(types);
					}
				}
				catch(Exception ex)
				{
					Log.WriteLine(ex);
				}
			}
			return pluginTypes;
		}
        /// <summary>
        /// Uses the PluginProviders specified to load Plugin Types that will be used to create Plugins.
        /// </summary>
        /// <param name="progressViewer">The callback object implementing IProgressViewer that will be used to monitor progress.</param>
        /// <param name="pluginProviders">The collection of PluginProviders that will be used to load the Plugin Types from their various sources.</param>
        /// <returns></returns>
        public static TypeCollection LoadPluginTypes(IProgressViewer progressViewer, PluginProviderCollection pluginProviders)
        {
            TypeCollection pluginTypes = new TypeCollection();

            foreach (PluginProvider provider in pluginProviders)
            {
                try
                {
                    Log.WriteLine("Loading Plugin Types. PluginProvider: '{0}'.", provider.Name);

                    TypeCollection types = provider.LoadPluginTypes(progressViewer);
                    if (types != null)
                    {
                        pluginTypes.AddRange(types);
                    }
                }
                catch (Exception ex)
                {
                    Log.WriteLine(ex);
                }
            }
            return(pluginTypes);
        }
        /// <summary>
        /// Creates PluginDescriptors from each Plugin Type specified.
        /// </summary>
        /// <param name="progressViewer">The callback object implementing IProgressViewer that will be used to monitor progress.</param>
        /// <param name="types">The collection of Plugin Types to create descriptors for.</param>
        /// <returns></returns>
        public static PluginDescriptorCollection CreatePluginDescriptors(IProgressViewer progressViewer, TypeCollection types)
        {
            PluginDescriptorCollection descriptors = new PluginDescriptorCollection();

            foreach (Type type in types)
            {
                try
                {
                    string message = string.Format("Creating PluginDescriptor, Type: '{0}'.", type.FullName);
                    ProgressViewer.SetExtendedDescription(progressViewer, message);
                    Log.WriteLine(message);

                    PluginDescriptor descriptor = new PluginDescriptor(type);

                    descriptors.Add(descriptor);
                }
                catch (Exception ex)
                {
                    Log.WriteLine(ex);
                }
            }
            return(descriptors);
        }
 /// <summary>
 /// Sets the progress viewer's extended description
 /// </summary>
 /// <param name="viewer">The progress viewer to manipulate</param>
 /// <param name="text">The text to display</param>
 public static void SetExtendedDescription(IProgressViewer viewer, string text)
 {
     try
     {
         if (viewer != null)
         {
             Control control = viewer as Control;
             if (control != null)
             {
                 if (control.InvokeRequired)
                 {
                     control.Invoke(new SetTextEventHandler(SetExtendedDescription), new object[] { viewer, text });
                     return;
                 }
             }
             viewer.SetExtendedDescription(text);
         }
     }
     catch (Exception ex)
     {
         Log.WriteLine(ex);
     }
 }
 /// <summary>
 /// Sets the progress viewer's marquee state
 /// </summary>
 /// <param name="viewer">The progress viewer to manipulate</param>
 /// <param name="moving">A flag that determines if the marquee is moving or stopped</param>
 /// <param name="reset">A flag that determines if the marquee should be reset</param>
 public static void SetMarqueeMoving(IProgressViewer viewer, bool moving, bool reset)
 {
     try
     {
         if (viewer != null)
         {
             Control control = viewer as Control;
             if (control != null)
             {
                 if (control.InvokeRequired)
                 {
                     control.Invoke(new SetMarqueeMovingEventHandler(SetMarqueeMoving), new object[] { viewer, moving, reset });
                     return;
                 }
             }
             viewer.SetMarqueeMoving(moving, reset);
         }
     }
     catch (Exception ex)
     {
         Log.WriteLine(ex);
     }
 }
 /// <summary>
 /// Sets the progress viewer's image
 /// </summary>
 /// <param name="viewer">The progress viewer to manipulate</param>
 /// <param name="image">The image to display</param>
 public static void SetImage(IProgressViewer viewer, Image image)
 {
     try
     {
         if (viewer != null)
         {
             Control control = viewer as Control;
             if (control != null)
             {
                 if (control.InvokeRequired)
                 {
                     control.Invoke(new SetImageEventHandler(SetImage), new object[] { viewer, image });
                     return;
                 }
             }
             viewer.SetImage(image);
         }
     }
     catch (Exception ex)
     {
         Log.WriteLine(ex);
     }
 }
示例#33
0
        private bool DeleteOlderVersions(
            VersionedDirectory[] versionedDirectories,
            VersionedDirectory versionStarted,
            IProgressViewer progressViewer)
        {
            try
            {
                // grab the newest version
                VersionedDirectory newestVersion = versionedDirectories[0];

                // loop thru and delete the oldest versions not in use
                foreach (VersionedDirectory version in versionedDirectories)
                {
                    // keep the newest version and the one that started
                    if (version != newestVersion && version != versionStarted)
                    {
                        try
                        {
                            ProgressViewer.SetExtendedDescription(progressViewer, "Bootstrap: Removing older version " + version.Version.ToString() + "...");

                            // recursively delete this version directory
                            Directory.Delete(version.Directory.FullName, true);
                        }
                        catch (System.Exception systemException)
                        {
                            System.Diagnostics.Trace.WriteLine(systemException);
                        }
                    }
                }
            }
            catch (System.Exception systemException)
            {
                System.Diagnostics.Trace.WriteLine(systemException);
            }
            return(false);
        }
            /// <summary>
            /// Searches for plugins in the application's startup path
            /// </summary>
            /// <param name="viewer"></param>
            /// <returns>null if no plugins were found</returns>
            private TypeCollection InternalSearchForPluginTypes(IProgressViewer progressViewer)
            {
                TypeCollection types = null;

                // starting in the startup path
                DirectoryInfo directoryInfo = new DirectoryInfo(Application.StartupPath);

                // look for all the dlls
                FileInfo[] files = directoryInfo.GetFiles("*.dll");

                // see if we can find any plugins defined in each assembly
                foreach (FileInfo file in files)
                {
                    // try and load the assembly
                    Assembly assembly = this.LoadAssembly(file.FullName);
                    if (assembly != null)
                    {
                        ProgressViewer.SetExtendedDescription(progressViewer, string.Format("Searching for plugins. Searching '{0}'...", assembly.GetName().Name));

                        // see if the assembly has any plugins defined in it
                        TypeCollection typesInAssembly = this.LoadPluginTypesFromAssembly(assembly);
                        if (typesInAssembly != null)
                        {
                            if (types == null)
                            {
                                types = new TypeCollection();
                            }

                            // add the types defined as plugins to the master list
                            types.AddRange(typesInAssembly);
                        }
                    }
                }

                return(types);
            }
		/// <summary>
		/// Creates a copy of the manifest file in the alternate path
		/// </summary>
		/// <param name="downloadDescriptor"></param>
		public virtual void CreateCopyOfManifestInAlternatePath(IProgressViewer progressViewer, AutoUpdateDownloadDescriptor downloadDescriptor)
		{
			try
			{
				// if the alternate path is not set, then we don't have to do this
				if (downloadDescriptor.Options.AlternatePath == null ||	downloadDescriptor.Options.AlternatePath == string.Empty)
					return;

				// format a path to the product's alternate path
				string altPath = Path.Combine(downloadDescriptor.Options.AlternatePath, downloadDescriptor.Manifest.Product.Name);

				// if the path doesn't exist, just bail, we don't create alternate paths
				bool folderExists = Directory.Exists(altPath);
				Debug.WriteLine(string.Format("Confirming the product's 'Alternate Download Path' folder.\n\tThe folder '{0}' {1}.", altPath, (folderExists ? "already exists" : "does not exist")), MY_TRACE_CATEGORY);
				if (!folderExists)
				{
					Debug.WriteLine(string.Format("Creating the product's 'Alternate Download Path' folder at '{0}'.", altPath), MY_TRACE_CATEGORY);
					Directory.CreateDirectory(altPath);
				}
				
				// format a path to the file in the alternate path
				string dstPath = Path.Combine(altPath, string.Format("{0}-{1}.manifest", downloadDescriptor.Manifest.Product.Name, downloadDescriptor.Manifest.Product.Version.ToString()));

				bool fileExists = File.Exists(dstPath);
				Debug.WriteLine(string.Format("Preparing to copy the manifest to the product's 'Alternate Download Path' folder.\n\tThe file '{0}' {1}.", dstPath, (fileExists ? "already exists" : "does not exist")), MY_TRACE_CATEGORY);
							
				// otherwise write the manifest to the alternate path
				ProgressViewer.SetExtendedDescription(progressViewer, "Creating a backup copy of the manifest file.");
				Debug.WriteLine(string.Format("Copying the manifest to '{0}'.", dstPath), MY_TRACE_CATEGORY);
				XmlAutoUpdateManifestWriter.Write(downloadDescriptor.Manifest, dstPath, System.Text.Encoding.UTF8);				
			}
			catch(ThreadAbortException)
			{

			}
			catch(Exception ex)
			{
				Debug.WriteLine(ex);
			}
		}
		/// <summary>
		/// Unzips the .zip file to a directory of it's own using the name of the .zip file as a base
		/// </summary>
		/// <param name="progressViewer"></param>
		/// <param name="zipFilename"></param>
		/// <returns></returns>
		protected virtual bool Unzip(IProgressViewer progressViewer, AutoUpdateDownloadDescriptor downloadDescriptor, string zipFilename)
		{
			ZipInputStream zipStream = null;
			FileStream fs = null;
			string newVersionPath = null;

			try
			{												
				// calculate the rootname 
				string rootName = Path.GetFileName(zipFilename).Replace(Path.GetExtension(zipFilename), null);

				// the text to remove includes the name of the product and a dash
				string prependedTextToRemove = string.Format("{0}-", downloadDescriptor.Manifest.Product.Name);
				
				// remove that and we're left with a version
				rootName = rootName.Replace(prependedTextToRemove, null);
				
				// extract here
				string rootPath = Path.GetDirectoryName(zipFilename);
				
				// the destination where the files will be unzipped for the new version
				newVersionPath = Path.Combine(rootPath, rootName);
				
				// make sure the directory where the new version will be extracted exists
				bool folderExists = Directory.Exists(newVersionPath);
				Debug.WriteLine(string.Format("Confirming the new version's path.\n\tThe folder '{0}' {1}.", newVersionPath, (folderExists ? "already exists" : "does not exist")), MY_TRACE_CATEGORY);
				if (!folderExists)
				{
					Debug.WriteLine(string.Format("Creating the new verion's folder '{0}'.", newVersionPath), MY_TRACE_CATEGORY);
					Directory.CreateDirectory(newVersionPath);
				}

				// try and find the postbuildevent.bat file
				string postBuildFile = Path.Combine(rootPath, "PostBuildEvent.bat");

				// open the zip file using a zip input stream
				Debug.WriteLine(string.Format("Opening the archive '{0}' for reading.", zipFilename), MY_TRACE_CATEGORY);
				zipStream = new ZipInputStream(File.OpenRead(zipFilename));								
				
				// ready each zip entry
				ZipEntry zipEntry;
				while((zipEntry = zipStream.GetNextEntry()) != null)
				{					
					try
					{
						string zipEntryFilename = Path.Combine(rootPath, zipEntry.Name);
						zipEntryFilename = zipEntryFilename.Replace("/", "\\");
	                    
						// trace the entry to where it is going
						Debug.WriteLine(string.Format("Extracting '{0}' to '{1}'.", zipEntry.Name, zipEntryFilename), MY_TRACE_CATEGORY);

						if (zipEntry.IsDirectory)
						{
							Debug.WriteLine(string.Format("Creating the folder '{0}'.", zipEntryFilename), MY_TRACE_CATEGORY);
							Directory.CreateDirectory(zipEntryFilename);
						}
						else
						{
							ProgressViewer.SetExtendedDescription(progressViewer, "Extracting " + zipEntry.Name + "...");
							
							// make sure the directory exists
							FileInfo fi = new FileInfo(zipEntryFilename);
							DirectoryInfo di = fi.Directory;
							if (!Directory.Exists(di.FullName))
								Directory.CreateDirectory(di.FullName);
							fi = null;
							di = null;

							// create each file
							fs = File.Create(zipEntryFilename);
							int size = 2048;
							byte[] data = new byte[size];
							while(true)
							{
								size = zipStream.Read(data, 0, data.Length);
								if (size > 0)
									fs.Write(data, 0, size);
								else
									break;
							}
							// close the extracted file
							fs.Close();
							fs = null;
						}
					}					
					catch(Exception ex)
					{
						Debug.WriteLine(ex);
					}
				}

				// close the zip stream
				zipStream.Close();
				
				RunFileIfFound(progressViewer, postBuildFile);

				return true;
			}
			catch(ThreadAbortException)
			{
				try
				{					
					// make sure the streams are closed
					if (zipStream != null)
						zipStream.Close();

					if (fs != null)
						fs.Close();

					// delete the root folder of the new install upon cancellation
					Directory.Delete(newVersionPath, true);
				}
				catch(Exception)
				{

				}
			}
			catch(Exception ex)
			{
				Debug.WriteLine(ex);
			}
			finally
			{
				// make sure the streams are closed
				if (zipStream != null)
					zipStream.Close();

				if (fs != null)
					fs.Close();
			}

			return false;
		}
		/// <summary>
		/// Runs the specified file if it exists
		/// </summary>
		/// <param name="progressViewer"></param>
		/// <param name="file"></param>
		protected virtual void RunFileIfFound(IProgressViewer progressViewer, string file)
		{
			try
			{
				bool fileExists = File.Exists(file);
				Trace.WriteLine(string.Format("Preparing to start a process.\n\tThe file '{0}' {1}.", file, (fileExists ? "exists" : "does not exist")), MY_TRACE_CATEGORY);				

				if (fileExists)
				{
					ProgressViewer.SetExtendedDescription(progressViewer, string.Format("Creating process '{0}'...",Path.GetFileName(file)));	

					ProcessStartInfo pi = new ProcessStartInfo();

					pi.FileName = file;
					pi.WorkingDirectory = new FileInfo(file).DirectoryName;

					Process p = Process.Start(pi);
					if (p != null)
					{
						p.WaitForExit(); 
					}
				}	
			}
			catch(ThreadAbortException)
			{

			}
			catch(Exception ex)
			{
				Trace.WriteLine(ex);
			}
			finally
			{
				ProgressViewer.SetExtendedDescription(progressViewer, null);
			}
		}
		/// <summary>
		/// Updates the display of the specified progress dialog
		/// </summary>
		/// <param name="progressViewer"></param>
		/// <param name="bytesReceived"></param>
		/// <param name="bytesTotal"></param>
		public virtual void SetDownloadProgress(IProgressViewer progressViewer, long bytesReceived, long bytesTotal)
		{								
			double p = ((double)bytesReceived / (double)bytesTotal) * 100;
			int percent = (int)p;
			
			string title = string.Format("AutoUpdate Progress..." + "({0}% Completed)", percent.ToString());
			string received = this.FormatFileLengthForDisplay(bytesReceived);
			string total = this.FormatFileLengthForDisplay(bytesTotal);
			string description = string.Format("Progress: ({0} of {1} downloaded)", received, total);

			ProgressViewer.SetTitle(progressViewer, title);
			ProgressViewer.SetExtendedDescription(progressViewer, description);							
		}
//		/// <summary>
//		/// Finds and creates all SnapIn classes discovered using the specified search.
//		/// </summary>
//		/// <param name="search"></param>
//		/// <param name="outputWindow"></param>
//		/// <returns></returns>
//		public static SnapInInfoCollection FindAndCreateSnapIns(Search search, IProgressViewer progressViewer)
//		{
//			SnapInInfoCollection snapIns = new SnapInInfoCollection();
//			try
//			{								
//				AppDomain domain = AppDomain.CreateDomain(Guid.NewGuid().ToString());
//				SnapInProvider provider = (SnapInProvider)domain.CreateInstanceFromAndUnwrap(System.Reflection.Assembly.GetExecutingAssembly().Location, typeof(SnapInProvider).FullName);
//				ArrayList array = provider.SearchForTypes(search, typeof(ISnapIn), progressViewer);
//				AppDomain.Unload(domain);
//
//				if (array != null)
//				{
//					foreach(RuntimeClassProviderEventArgs e in array)
//					{
//						object runTimeObject = SnapInProvider.CreateSnapInFrom(e.Assembly, e.Type, progressViewer);
//						if (runTimeObject != null)
//						{
//							snapIns.Add(e.Assembly, e.Type, (ISnapIn)runTimeObject);						
//							
////							if (outputWindow != null)
////								outputWindow.Write("Created SnapIn...Created SnapIn '" + e.Type.FullName + "'"); // from '" + e.Assembly.Location + "'");
////	
////							System.Diagnostics.Trace.WriteLine("Created SnapIn '" + e.Type.FullName + "' from '" + e.Assembly.Location + "'", typeof(SnapInProvider).Name);
//						}
//					}
//				}
//			}
//			catch(System.Exception systemException)
//			{
//				System.Diagnostics.Trace.WriteLine(systemException);
//			}
//			return snapIns;
//		}

		public static ArrayList FindSnapIns(Search search, IProgressViewer progressViewer)
		{
			try
			{
				AppDomain domain = AppDomain.CreateDomain(Guid.NewGuid().ToString());
				SnapInProvider provider = (SnapInProvider)domain.CreateInstanceFromAndUnwrap(System.Reflection.Assembly.GetExecutingAssembly().Location, typeof(SnapInProvider).FullName);
				ArrayList array = provider.SearchForTypes(search, typeof(ISnapIn), progressViewer);
				AppDomain.Unload(domain);
				return array;
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.WriteLine(systemException);
			}
			return new ArrayList();
		}
        /// <summary>
        /// Stops the specified plugin.
        /// </summary>
        /// <param name="progressViewer">The callback object implementing IProgressViewer that will be used to monitor progress.</param>
        /// <param name="descriptor">The descriptor that contains the plugin to stop.</param>
        private static void StopPlugin(IProgressViewer progressViewer, PluginDescriptor descriptor)
        {
			ProgressViewer.SetExtendedDescription(progressViewer, string.Format("Stopping Plugin: '{0}'.", descriptor.PluginName));

            // stop the plugin
            descriptor.PluginInstance.OnStop(PluginContext.Current, new PluginDescriptorEventArgs(descriptor));
        }
		/// <summary>
		/// Instructs the AutoUpdateDownloader to cleanup after an install
		/// </summary>
		/// <param name="progressViewer">The progress viewer by which progress should be displayed</param>
		/// <param name="downloadDescriptor">The download descriptor that describes the download that occurred and was installed</param>
		public virtual bool FinalizeInstallation(			
			IProgressViewer progressViewer,
			AutoUpdateDownloadDescriptor downloadDescriptor)
		{
			return true;			
		}
		/// <summary>
		/// Creates a copy of the update file in the alternate path
		/// </summary>
		/// <param name="progressViewer"></param>
		/// <param name="updateFilename"></param>
		/// <returns></returns>
		public virtual void CreateCopyOfUpdateInAlternatePath(IProgressViewer progressViewer, AutoUpdateDownloadDescriptor downloadDescriptor)
		{				 													
			try
			{
				// if the alternate path is not set, then we don't have to do this
				if (downloadDescriptor.Options.AlternatePath == null ||	downloadDescriptor.Options.AlternatePath == string.Empty)
					return;

				// take the alternate path
				string altPath = Path.Combine(downloadDescriptor.Options.AlternatePath, downloadDescriptor.Manifest.Product.Name);

				// see if the folder exists
				bool folderExists = Directory.Exists(altPath);				
				Debug.WriteLine(string.Format("Confirming the product's 'Alternate Download Path' folder.\n\tThe folder '{0}' {1}.", altPath, (folderExists ? "already exists" : "does not exist")), MY_TRACE_CATEGORY);
				if (!folderExists)
				{
					Debug.WriteLine(string.Format("Creating the product's 'Alternate Download Path' folder at '{0}'.", altPath), MY_TRACE_CATEGORY);
					Directory.CreateDirectory(altPath);
				}
	
				// format the backup filename from the alternate path, and the url where the update
				string dstPath = Path.Combine(altPath, Path.GetFileName(downloadDescriptor.Manifest.UrlOfUpdate));

				// see if the file already exists
				bool fileExists = File.Exists(dstPath);
				Debug.WriteLine(string.Format("Preparing to copy the update to the product's 'Alternate Download Path' folder.\n\tThe file '{0}' {1}.", dstPath, (fileExists ? "already exists" : "does not exist")), MY_TRACE_CATEGORY);
				
				// copy the .update we downloaded to the backup location in the alternate path directory
				ProgressViewer.SetExtendedDescription(progressViewer, "Creating a backup copy of the update file.");
				Debug.WriteLine(string.Format("Copying the update to '{0}'.", dstPath), MY_TRACE_CATEGORY);				
				File.Copy(downloadDescriptor.DownloadedPath, dstPath, false);								
			}
			catch(ThreadAbortException)
			{

			}
			catch(Exception ex)
			{
				Debug.WriteLine(ex);
			}
		}		
		public static void SetImage(IProgressViewer viewer, Image image)
		{
			try
			{
				if (viewer != null)
					viewer.SetImage(image);
			}
			catch(Exception ex)
			{
				Trace.WriteLine(ex);
			}
		}
		/// <summary>
		/// Creates PluginDescriptors from each Plugin Type specified.
		/// </summary>
		/// <param name="progressViewer">The callback object implementing IProgressViewer that will be used to monitor progress.</param>
		/// <param name="types">The collection of Plugin Types to create descriptors for.</param>
		/// <returns></returns>
		public static PluginDescriptorCollection CreatePluginDescriptors(IProgressViewer progressViewer, TypeCollection types)
		{
			PluginDescriptorCollection descriptors = new PluginDescriptorCollection();
			foreach (Type type in types)
			{
				try
				{
					string message = string.Format("Creating PluginDescriptor, Type: '{0}'.", type.FullName);
                    ProgressViewer.SetExtendedDescription(progressViewer, message);
					Log.WriteLine(message);

                    PluginDescriptor descriptor = new PluginDescriptor(type);

                    descriptors.Add(descriptor);
				}
				catch(Exception ex)
				{
					Log.WriteLine(ex);
				}
			}
			return descriptors;
		}
		/// <summary>
		/// Validates the dependencies for each of the PluginDescriptors
		/// </summary>
		/// <param name="progressViewer">The callback object implementing IProgressViewer that will be used to monitor progress.</param>
		/// <param name="descriptors">The collection of PluginDescriptors that describe the Plugins to be loaded.</param>
		public static void ValidatePluginDependencies(IProgressViewer progressViewer, PluginDescriptorCollection descriptors)
		{			
			/*
			 * Validation Phases
			 * Phase 1: Direct		(First level dependencies)
			 * Phase 2: Indirect	(Second level dependencies. i.e., dependencies of dependencies. Requires that Phase 1 already executed)
			 * Phase 3: Extended	(Provider Validation)
			 * */

			// Phase 1: Checks descriptors for missing dependencies and circular references. (direct)
			foreach (PluginDescriptor descriptor in descriptors)
			{
				try
				{
					// check for missing dependencies
//					MarkDescriptorIfMissingDependency(descriptor, descriptors);
					if (!descriptor.IsMissingDependency)
					{
						// check for circular references between plugins (direct, does not check dependency chains)
						MarkDescriptorIfCircularlyDependent(descriptor, descriptors);						
					}
				}
				catch(Exception ex)
				{
					Log.WriteLine(ex);
				}
			}

			// Phase 2: Checks depencencies for missing dependencies and circular references. (indirect)
			foreach (PluginDescriptor descriptor in descriptors)
			{
				try
				{
					// 
					if (!descriptor.IsMissingDependency && !descriptor.IsCircularlyDependent)
					{
						MarkDescriptorIfDependenciesAreMissingDependencyOrAreCircularlyDependent(descriptor, descriptors);
					}					
				}
				catch(Exception ex)
				{
					Log.WriteLine(ex);
				}
			}

			// Phase 3: Allow for Provider based validation?	
		
			/*
			 * Here we have an extension point. 
			 * If we created another provider who's sole purpose was to validate a PluginDescriptor,
			 * we could move this logic away from the core, and allow for validation to be extended.
			 * Possible reasons for doing this would be to prevent Plugins from being loaded based 
			 * on some other criteria. We could provide descriptions of why a particular descriptor failed validation.
			 * */
		}
        /// <summary>
        /// Creates instances of the Plugin type defined by each PluginDescriptor.
        /// </summary>
        /// <param name="progressViewer">The callback object implementing IProgressViewer that will be used to monitor progress.</param>
        /// <param name="descriptors">The collection of PluginDescriptors that describe the Plugins to be loaded.</param>
        public static void CreatePluginInstances(IProgressViewer progressViewer, PluginDescriptorCollection descriptors)
        {
			Log.WriteLine("Creating Plugins. # of Plugins: '{0}'.", descriptors.Count.ToString());

			foreach (PluginDescriptor descriptor in descriptors)
			{
				if (descriptor.IsStartable)
				{
					if (AreDependenciesCreated(descriptor, descriptors))
					{
						CreatePluginInstance(progressViewer, descriptor);
					}
				}
			}
        }
        /// <summary>
        /// Stops the plugins defined in the collection that have been created.
        /// </summary>
        /// <param name="progressViewer">The callback object implementing IProgressViewer that will be used to monitor progress.</param>
        /// <param name="descriptors">The collection of PluginDescriptors that describe the Plugins to be loaded.</param>
        public static void StopPlugins(IProgressViewer progressViewer, PluginDescriptorCollection descriptors)
        {
			Log.WriteLine("Stopping Plugins. # of Plugins: '{0}'.", descriptors.Count.ToString());

            // fire the BeforePluginsStopped event of the PluginContext
			PluginContext.Current.OnBeforePluginsStopped(new PluginContextEventArgs(PluginContext.Current));
			
            // stop all of the plugins
			foreach (PluginDescriptor descriptor in descriptors)
			{
				if (descriptor.PluginInstance != null)
				{
					StopPlugin(progressViewer, descriptor);
				}
				else
				{
					Log.WriteLine(string.Format("Skipped Plugin: '{0}' was not created.", descriptor.PluginName));
				}
			}
        }
        /// <summary>
        /// Creates an instance of the Type described by the PluginDescriptor and asserts that it derives from Plugin.
        /// </summary>
        /// <param name="progressViewer">The callback object implementing IProgressViewer that will be used to monitor progress.</param>
        /// <param name="descriptor">The PluginDescriptor that contains the Type to create.</param>
        private static void CreatePluginInstance(IProgressViewer progressViewer, PluginDescriptor descriptor)
        {            
            try
            {
                TypeUtilities.AssertTypeIsSubclassOfBaseType(descriptor.PluginType, typeof(Plugin));

				string message = string.Format("Creating Plugin: '{0}'.", descriptor.PluginName);
				ProgressViewer.SetExtendedDescription(progressViewer, message);
				Log.WriteLine(message);

                Plugin plugin = (Plugin)TypeUtilities.CreateInstanceOfType(descriptor.PluginType, Type.EmptyTypes, new object[] {});
                
                descriptor.AttachPluginInstance(plugin);
            }
            catch(Exception ex)
            {
                Log.WriteLine(ex);
            }
        }
		public static void SetMargueeMoving(IProgressViewer viewer, bool moving, bool reset)
		{
			try
			{
				if (viewer != null)
					viewer.SetMarqueeMoving(moving, reset);
			}
			catch(Exception ex)
			{
				Trace.WriteLine(ex);
			}
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="manager"></param>
		/// <param name="progressViewer"></param>
		public AutoUpdateManagerEventArgs(AutoUpdateManager manager, IProgressViewer progressViewer) : base()
		{
			_manager = manager;
			_progressViewer = progressViewer;
		}
        /// <summary>
        /// Instructs the AutoUpdateDownloader to download the update specified by the update descriptor
        /// </summary>
        /// <param name="progressViewer">The progress viewer by which progress should be displayed</param>
        /// <param name="downloadDescriptor">The download descriptor that describes the download that should occur</param>
        /// <returns></returns>
        public virtual bool Download(
            IProgressViewer progressViewer,
            AutoUpdateDownloadDescriptor downloadDescriptor)
        {
            FileStream localStream     = null;
            Stream     remoteStream    = null;
            string     myTraceCategory = string.Format("'{0}'", this.GetType().Name);

            try
            {
                // set the progress to zero for the start
                this.SetDownloadProgress(progressViewer, 0, downloadDescriptor.Manifest.SizeOfUpdate);

                // format the downloaded path where the .update file will be when the download is finished
                downloadDescriptor.DownloadedPath = Path.Combine(downloadDescriptor.Options.DownloadPath, Path.GetFileName(downloadDescriptor.Manifest.UrlOfUpdate));

                Debug.WriteLine(string.Format("Preparing to download update.\n\tThe update will be downloaded from '{0}'.\n\tThe update will be downloaded to '{1}'.", downloadDescriptor.Manifest.UrlOfUpdate, downloadDescriptor.DownloadedPath), myTraceCategory);

                // if the url where this update is supposed to be located is not set, just quit as there isn't anything else we can do
                if (downloadDescriptor.Manifest.UrlOfUpdate == null || downloadDescriptor.Manifest.UrlOfUpdate == string.Empty)
                {
                    return(false);
                }

                // create a new web client to download the file
                WebClient wc = new WebClient();

                // open a remote stream to the download
                Debug.WriteLine(string.Format("Preparing to download update.\n\tOpening stream to the remote url '{0}'.", downloadDescriptor.Manifest.UrlOfUpdate), myTraceCategory);
                remoteStream = wc.OpenRead(downloadDescriptor.Manifest.UrlOfUpdate);

                // open a local file stream where the update will be downloaded
                Debug.WriteLine(string.Format("Preparing to download update.\n\tOpening stream to the local url '{0}'.", downloadDescriptor.DownloadedPath), myTraceCategory);
                localStream = new FileStream(downloadDescriptor.DownloadedPath, FileMode.Create, FileAccess.Write, FileShare.None);

                // if successfull we'll receive the data in segments
                if (remoteStream != null)
                {
                    long bytesDownloaded = 0;
                    while (true)
                    {
                        // figure out how many bytes we have to download
                        long bytesToReceive = downloadDescriptor.Manifest.SizeOfUpdate - bytesDownloaded;

                        // correct it if it's more than the segment size
                        if (bytesToReceive > _segmentSize)
                        {
                            bytesToReceive = (long)_segmentSize;
                        }

                        byte[] segment = new byte[bytesToReceive];

                        // read a segment off the socket
                        int bytesReceived = remoteStream.Read(segment, 0, (int)bytesToReceive);

                        // bail if nothing read
                        if (bytesReceived == 0)
                        {
                            break;
                        }

                        // if we received anything
                        if (bytesReceived > 0)
                        {
                            // write it to the update file
                            localStream.Write(segment, 0, bytesReceived);
                            // update the position
                            bytesDownloaded += bytesReceived;
                        }

                        // update the progress viewer
                        this.SetDownloadProgress(progressViewer, bytesDownloaded, downloadDescriptor.Manifest.SizeOfUpdate);
                    }
                }

                Debug.WriteLine(string.Format("The update was successfully downloaded to '{0}'.", downloadDescriptor.DownloadedPath), myTraceCategory);

                return(true);
            }
            catch (ThreadAbortException)
            {
            }
            catch (Exception ex)
            {
                try
                {
                    if (localStream != null)
                    {
                        localStream.Close();
                    }

                    if (remoteStream != null)
                    {
                        remoteStream.Close();
                    }
                }
                catch (Exception)
                {
                }

                try
                {
                    // something broke, make sure we delete the .update file
                    File.Delete(downloadDescriptor.DownloadedPath);
                }
                catch (Exception)
                {
                }

                throw ex;
            }
            finally
            {
                /*
                 * make sure the streams are closed
                 * */

                try
                {
                    if (localStream != null)
                    {
                        localStream.Close();
                    }
                    if (remoteStream != null)
                    {
                        remoteStream.Close();
                    }
                }
                catch {}

                try
                {
                }
                catch {}
            }

            // if it's made it this far something went wrong
            return(false);
        }
		/// <summary>
		/// 
		/// </summary>
		/// <param name="manager"></param>
		/// <param name="progressViewer"></param>
		/// <param name="cancel"></param>
		public AutoUpdateManagerCancelEventArgs(AutoUpdateManager manager, IProgressViewer progressViewer, bool cancel) : base(manager, progressViewer)
		{
			_cancel = cancel;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="manager"></param>
		/// <param name="progressViewer"></param>
		/// <param name="downloadDescriptor"></param>
		public AutoUpdateManagerWithDownloadDescriptorEventArgs(AutoUpdateManager manager, IProgressViewer progressViewer, AutoUpdateDownloadDescriptor downloadDescriptor) : base(manager, progressViewer)
		{
			_downloadDescriptor = downloadDescriptor;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="manager"></param>
		/// <param name="progressViewer"></param>
		/// <param name="downloadDescriptor"></param>
		/// <param name="cancel"></param>
		public AutoUpdateManagerWithDownloadDescriptorCancelEventArgs(AutoUpdateManager manager, IProgressViewer progressViewer, AutoUpdateDownloadDescriptor downloadDescriptor, bool cancel) : base(manager, progressViewer, downloadDescriptor)
		{
			_cancel = cancel;
		}
 /// <summary>
 /// Initializes a new instance of the AutoUpdateManagerEventArgs class.
 /// </summary>
 /// <param name="manager">The AutoUpdateManager that is handling the update.</param>
 /// <param name="progressViewer">The IProgressViewer that can be used to display progress about the update.</param>
 public AutoUpdateManagerEventArgs(AutoUpdateManager manager, IProgressViewer progressViewer)
     : base()
 {
     _manager        = manager;
     _progressViewer = progressViewer;
 }
		/// <summary>
		/// Installs the .update file specified by decrypting it and then unziping the contents to a new versioned directory (ie. 1.0.0.1)
		/// </summary>
		/// <param name="progressViewer"></param>
		/// <param name="updateFilename"></param>
		/// <returns></returns>
		protected virtual bool InstallUpdate(IProgressViewer progressViewer, AutoUpdateDownloadDescriptor downloadDescriptor)
		{
			string zipFilename = null;
			try
			{
				Debug.WriteLine(string.Format("Preparing to install update from '{0}'.", downloadDescriptor.DownloadedPath), MY_TRACE_CATEGORY);

				// decrypt the .update file first				
				if (!this.DecryptToZip(progressViewer, downloadDescriptor, out zipFilename))
					return false;

				// then unzip the .zip file
				if (this.Unzip(progressViewer, downloadDescriptor, zipFilename))
				{	// delete the zip file
					File.Delete(zipFilename);
					return true;
				}
			}
			catch(ThreadAbortException)
			{
				try
				{
					// delete the zip file
					File.Delete(zipFilename);
				}
				catch(Exception)
				{

				}
			}

			return false;
		}
		/// <summary>
		/// Sets the progress viewer's text
		/// </summary>
		/// <param name="viewer">The progress viewer to manipulate</param>
		/// <param name="text">The text to display</param>
		public static void SetTitle(IProgressViewer viewer, string text)
		{
			try
			{
				if (viewer != null)
				{
					Control control = viewer as Control;
					if (control != null)
					{
						if (control.InvokeRequired)
						{
							control.Invoke(new SetTextEventHandler(SetTitle), new object[] {viewer, text});
							return;
						}
					}
					viewer.SetTitle(text);				
				}
			}
			catch(Exception ex)
			{
				Log.WriteLine(ex);
			}
		}
		/// <summary>
		/// Decrypts the .update file to a .zip file using the name of the .update file as a base in the same directory as the .update file
		/// </summary>
		/// <param name="progressViewer"></param>
		/// <param name="updateFilename"></param>
		/// <param name="zipFilename"></param>
		/// <returns></returns>
		protected virtual bool DecryptToZip(IProgressViewer progressViewer, AutoUpdateDownloadDescriptor downloadDescriptor, out string zipFilename)
		{
			zipFilename = null;
			try
			{						
				ProgressViewer.SetExtendedDescription(progressViewer, "Parsing update...");

				// save the path to the update
				string updateFilename = downloadDescriptor.DownloadedPath;

				// format the .zip file
				zipFilename = Path.Combine(Path.GetDirectoryName(updateFilename), Path.GetFileName(updateFilename).Replace(Path.GetExtension(updateFilename), null) + ".zip");
				
				// it is rijndael encrypted
				RijndaelEncryptionEngine ee = new RijndaelEncryptionEngine();
				
				// decrypt the .update file to a .zip file
				Debug.WriteLine(string.Format("Converting the update into an archive.\n\tThe archive will exist at '{0}'.", zipFilename), MY_TRACE_CATEGORY);
				ee.Decrypt(updateFilename, zipFilename);				
				
				return true;
			}
			catch(ThreadAbortException)
			{

			}
			return false;
		}
        /// <summary>
        /// Called when the provider should load the configuration it is managing.
        /// </summary>
        public virtual void Load(IProgressViewer progressViewer)
        {
            // read or create the local user configuration
            ProgressViewer.SetExtendedDescription(progressViewer, string.Format("Loading '{0}' configuration...", this.ConfigurationName));
            
            ConfigurationProvidersManager.ReadOrCreateConfiguration(
                CarbonConfig.Verbose, 
                this.ConfigurationName, 
                this.FullPath, 
                out _configuration, 
                this.GetEncryptionEngine(),
                this.FormatConfiguration);

            if (this.Configuration != null)
            {
                this.Configuration.TimeToSave += new EventHandler(OnConfigurationTimeToSave);

                // by default we'll add this to the list so that the configuration shows up in the options dialog
                ConfigurationProvidersManager.EnumeratingConfigurations += new EventHandler<XmlConfigurationManagerEventArgs>(OnConfigurationProvidersManagerEnumeratingConfigurations);
            }
        }
		/// <summary>
		/// Instructs the AutoUpdateDownloader to download the update specified by the update descriptor
		/// </summary>
		/// <param name="progressViewer">The progress viewer by which progress should be displayed</param>
		/// <param name="downloadDescriptor">The download descriptor that describes the download that should occur</param>
		/// <returns></returns>
		public virtual bool Download(
			IProgressViewer progressViewer,
			AutoUpdateDownloadDescriptor downloadDescriptor)
		{
			FileStream localStream = null;
			Stream remoteStream = null;
			string myTraceCategory = string.Format("'{0}'", this.GetType().Name);

			try
			{
				// set the progress to zero for the start
				this.SetDownloadProgress(progressViewer, 0, downloadDescriptor.Manifest.SizeOfUpdate);

				// format the downloaded path where the .update file will be when the download is finished				
				downloadDescriptor.DownloadedPath = Path.Combine(downloadDescriptor.Options.DownloadPath, Path.GetFileName(downloadDescriptor.Manifest.UrlOfUpdate));

				Debug.WriteLine(string.Format("Preparing to download update.\n\tThe update will be downloaded from '{0}'.\n\tThe update will be downloaded to '{1}'.", downloadDescriptor.Manifest.UrlOfUpdate, downloadDescriptor.DownloadedPath), myTraceCategory);
				
				// if the url where this update is supposed to be located is not set, just quit as there isn't anything else we can do
				if (downloadDescriptor.Manifest.UrlOfUpdate == null || downloadDescriptor.Manifest.UrlOfUpdate == string.Empty)
					return false;

				// create a new web client to download the file
				WebClient wc = new WebClient();

				// open a remote stream to the download
				Debug.WriteLine(string.Format("Preparing to download update.\n\tOpening stream to the remote url '{0}'.", downloadDescriptor.Manifest.UrlOfUpdate), myTraceCategory);
				remoteStream = wc.OpenRead(downloadDescriptor.Manifest.UrlOfUpdate);

				// open a local file stream where the update will be downloaded
				Debug.WriteLine(string.Format("Preparing to download update.\n\tOpening stream to the local url '{0}'.", downloadDescriptor.DownloadedPath), myTraceCategory);
				localStream = new FileStream(downloadDescriptor.DownloadedPath, FileMode.Create, FileAccess.Write, FileShare.None);

				// if successfull we'll receive the data in segments
				if (remoteStream != null)
				{
					long bytesDownloaded = 0;
					while (true)
					{
						// figure out how many bytes we have to download
						long bytesToReceive = downloadDescriptor.Manifest.SizeOfUpdate - bytesDownloaded;

						// correct it if it's more than the segment size
						if (bytesToReceive > _segmentSize)
							bytesToReceive = (long)_segmentSize;

						byte[] segment = new byte[bytesToReceive];

						// read a segment off the socket
						int bytesReceived = remoteStream.Read(segment, 0, (int)bytesToReceive);

						// bail if nothing read
						if (bytesReceived == 0)
							break;

						// if we received anything
						if (bytesReceived > 0)
						{
							// write it to the update file
							localStream.Write(segment, 0, bytesReceived);
							// update the position
							bytesDownloaded += bytesReceived;
						}

						// update the progress viewer
						this.SetDownloadProgress(progressViewer, bytesDownloaded, downloadDescriptor.Manifest.SizeOfUpdate);
					}
				}

				Debug.WriteLine(string.Format("The update was successfully downloaded to '{0}'.", downloadDescriptor.DownloadedPath), myTraceCategory);

				return true;
			}
			catch(ThreadAbortException)
			{

			}
			catch(Exception ex)
			{							
				try 
				{ 
					if (localStream != null) 
						localStream.Close(); 

					if (remoteStream != null) 
						remoteStream.Close();
				} 
				catch(Exception)
				{
				
				}

				try
				{
					// something broke, make sure we delete the .update file
					File.Delete(downloadDescriptor.DownloadedPath);
				}
				catch(Exception)
				{

				}

				throw ex;
			}
			finally
			{
				/* 
				 * make sure the streams are closed
				 * */

				try 
				{ 
					if (localStream != null) localStream.Close(); 
					if (remoteStream != null) remoteStream.Close();
				} 
				catch {}

				try
				{
					
				}
				catch {}
			}

			// if it's made it this far something went wrong
			return false;

		}