├── BitsUpdatePacker ├── Images │ ├── Add.png │ ├── Main.png │ ├── Pack.png │ └── Remove.png ├── BitsUpdatePacker.snk.pfx ├── Properties │ ├── Settings.settings │ ├── Settings.Designer.cs │ ├── AssemblyInfo.cs │ ├── app.manifest │ ├── Resources.Designer.cs │ └── Resources.resx ├── App.xaml ├── Configuration │ ├── TemplatesConfigSection.cs │ ├── TemplatesCollection.cs │ └── TemplatesElement.cs ├── UIFileSearchTemplate.cs ├── Data │ ├── StringRequiredValidationRule.cs │ ├── VersionConverter.cs │ ├── DirectoryExistsValidationRule.cs │ ├── SearchOptionToBoolConverter.cs │ ├── ValidationBorderConverter.cs │ ├── RegexValidationRule.cs │ ├── CertificateValidationRule.cs │ └── DirectoryCreateValidationRule.cs ├── UpdatePackerCommands.cs ├── App.xaml.cs ├── SelectFileControl.xaml.cs ├── SelectFolderControl.xaml.cs ├── App.config ├── SelectFileControl.xaml ├── SelectFolderControl.xaml ├── UIUpdatePackage.cs ├── MainWindow.xaml.cs ├── BitsUpdatePacker.csproj └── MainWindow.xaml ├── BitsUpdater ├── Files │ ├── Binaries │ │ ├── BitsUpdater.1.0.zip │ │ └── ApplicationLauncher.zip │ └── Libraries │ │ └── SharpBITS.Base.dll ├── UpdateDownloadedEventArgs.cs ├── Behavior │ ├── IUpdateBehavior.cs │ ├── UpdateDatabaseBehavior.cs │ └── UpdateServiceBehavior.cs ├── Extensions │ ├── AssemblyExtensions.cs │ └── StreamExtensions.cs ├── XmlUpdateManifest.cs ├── XmlUpdateStatus.cs ├── UpdateCheckedEventArgs.cs ├── UpdateErrorEventArgs.cs ├── UpdateProgressEventArgs.cs ├── FileSearchTemplate.cs ├── Properties │ └── AssemblyInfo.cs ├── UpdateStatus.cs ├── BitsUpdater.csproj ├── BitsUpdater.cs └── UpdatePackage.cs ├── ApplicationLauncher ├── Version │ └── 1.0.0.0 │ │ ├── BitsUpdater.dll │ │ ├── SharpBITS.Base.dll │ │ └── BitsUpdater.Example.exe ├── Program.cs ├── Properties │ └── AssemblyInfo.cs └── ApplicationLauncher.csproj ├── BitsUpdater.Example ├── Files │ └── BitsUpdater.Example.snk ├── Properties │ └── AssemblyInfo.cs ├── Program.cs └── BitsUpdater.Example.csproj ├── .gitignore └── BitsUpdater.sln /BitsUpdatePacker/Images/Add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakubgarfield/BitsUpdater/HEAD/BitsUpdatePacker/Images/Add.png -------------------------------------------------------------------------------- /BitsUpdatePacker/Images/Main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakubgarfield/BitsUpdater/HEAD/BitsUpdatePacker/Images/Main.png -------------------------------------------------------------------------------- /BitsUpdatePacker/Images/Pack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakubgarfield/BitsUpdater/HEAD/BitsUpdatePacker/Images/Pack.png -------------------------------------------------------------------------------- /BitsUpdatePacker/Images/Remove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakubgarfield/BitsUpdater/HEAD/BitsUpdatePacker/Images/Remove.png -------------------------------------------------------------------------------- /BitsUpdatePacker/BitsUpdatePacker.snk.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakubgarfield/BitsUpdater/HEAD/BitsUpdatePacker/BitsUpdatePacker.snk.pfx -------------------------------------------------------------------------------- /BitsUpdater/Files/Binaries/BitsUpdater.1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakubgarfield/BitsUpdater/HEAD/BitsUpdater/Files/Binaries/BitsUpdater.1.0.zip -------------------------------------------------------------------------------- /BitsUpdater/Files/Libraries/SharpBITS.Base.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakubgarfield/BitsUpdater/HEAD/BitsUpdater/Files/Libraries/SharpBITS.Base.dll -------------------------------------------------------------------------------- /ApplicationLauncher/Version/1.0.0.0/BitsUpdater.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakubgarfield/BitsUpdater/HEAD/ApplicationLauncher/Version/1.0.0.0/BitsUpdater.dll -------------------------------------------------------------------------------- /BitsUpdater.Example/Files/BitsUpdater.Example.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakubgarfield/BitsUpdater/HEAD/BitsUpdater.Example/Files/BitsUpdater.Example.snk -------------------------------------------------------------------------------- /BitsUpdater/Files/Binaries/ApplicationLauncher.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakubgarfield/BitsUpdater/HEAD/BitsUpdater/Files/Binaries/ApplicationLauncher.zip -------------------------------------------------------------------------------- /ApplicationLauncher/Version/1.0.0.0/SharpBITS.Base.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakubgarfield/BitsUpdater/HEAD/ApplicationLauncher/Version/1.0.0.0/SharpBITS.Base.dll -------------------------------------------------------------------------------- /ApplicationLauncher/Version/1.0.0.0/BitsUpdater.Example.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakubgarfield/BitsUpdater/HEAD/ApplicationLauncher/Version/1.0.0.0/BitsUpdater.Example.exe -------------------------------------------------------------------------------- /BitsUpdatePacker/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /BitsUpdater/UpdateDownloadedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace BitsUpdater 7 | { 8 | /// 9 | /// Bits Downloaded event args. 10 | /// 11 | public sealed class UpdateDownloadedEventArgs : EventArgs 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /BitsUpdatePacker/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /BitsUpdater/Behavior/IUpdateBehavior.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace BitsUpdater.Behavior 7 | { 8 | /// 9 | /// Interface used for different behaviors, which can be passed and executed by BitsUpdater method Update 10 | /// 11 | public interface IUpdateBehavior 12 | { 13 | void Execute(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /BitsUpdater/Extensions/AssemblyExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Reflection; 6 | using System.IO; 7 | 8 | namespace BitsUpdater.Extensions 9 | { 10 | public static class AssemblyExtensions 11 | { 12 | public static string GetDirectory(this Assembly assembly) 13 | { 14 | return Path.GetDirectoryName(assembly.Location); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /BitsUpdater/XmlUpdateManifest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Xml.Serialization; 6 | 7 | namespace BitsUpdater 8 | { 9 | [XmlRootAttribute("UpdateManifest", Namespace = "", IsNullable = false)] 10 | public sealed class XmlUpdateManifest 11 | { 12 | [XmlElementAttribute("Version")] 13 | public string Version; 14 | [XmlElementAttribute("Url")] 15 | public String Url; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /BitsUpdater/XmlUpdateStatus.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Xml.Serialization; 6 | 7 | namespace BitsUpdater 8 | { 9 | [XmlRootAttribute("UpdateStatus", Namespace = "", IsNullable = false)] 10 | public sealed class XmlUpdateStatus 11 | { 12 | [XmlElementAttribute("NextVersion")] 13 | public String NextVersion; 14 | [XmlElementAttribute("CurrentBITS")] 15 | public String BitsJobId; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ipch/ 2 | 3 | *.aux 4 | *.dvi 5 | *.log 6 | *.ps 7 | 8 | *.sdf 9 | *.opensdf 10 | 11 | #OS junk files 12 | Thumbs.db 13 | *.DS_Store 14 | 15 | #Visual Studio files 16 | *.obj 17 | *.pdb 18 | *.user 19 | *.aps 20 | *.pch 21 | *.vspscc 22 | *.vssscc 23 | *_i.c 24 | *_p.c 25 | *.ncb 26 | *.suo 27 | *.tlb 28 | *.tlh 29 | *.bak 30 | *.cache 31 | *.ilk 32 | *.log 33 | *.lib 34 | *.sbr 35 | obj/ 36 | [Bb]in 37 | [Dd]ebug*/ 38 | [Rr]elease*/ 39 | 40 | #Toolinga 41 | [Tt]est[Rr]esult 42 | 43 | #Project files 44 | [Bb]uild/ 45 | 46 | -------------------------------------------------------------------------------- /BitsUpdatePacker/Configuration/TemplatesConfigSection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Configuration; 6 | 7 | namespace BitsUpdatePacker.Configuration 8 | { 9 | internal sealed class TemplatesConfigSection : ConfigurationSection 10 | { 11 | [ConfigurationProperty("templates")] 12 | public TemplatesCollection Templates 13 | { 14 | get { return ((TemplatesCollection)(base["templates"])); } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /BitsUpdater/Behavior/UpdateDatabaseBehavior.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace BitsUpdater.Behavior 7 | { 8 | /// 9 | /// NOT IMPLEMENTED YET! 10 | /// 11 | public class UpdateDatabaseBehavior : IUpdateBehavior 12 | { 13 | /// 14 | /// Not implemented yet. 15 | /// 16 | public void Execute() 17 | { 18 | throw new NotImplementedException(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /BitsUpdater/Behavior/UpdateServiceBehavior.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace BitsUpdater.Behavior 7 | { 8 | /// 9 | /// NOT IMPLEMENTED YET! 10 | /// 11 | public class UpdateServiceBehavior : IUpdateBehavior 12 | { 13 | /// 14 | /// Not implemented yet. 15 | /// 16 | public void Execute() 17 | { 18 | throw new NotImplementedException(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /BitsUpdatePacker/UIFileSearchTemplate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | 7 | namespace BitsUpdatePacker 8 | { 9 | internal sealed class UIFileSearchTemplate 10 | { 11 | public string Directory 12 | { 13 | get; 14 | set; 15 | } 16 | 17 | public string Pattern 18 | { 19 | get; 20 | set; 21 | } 22 | 23 | public SearchOption SearchOption 24 | { 25 | get; 26 | set; 27 | } 28 | 29 | public UIFileSearchTemplate() 30 | { 31 | Pattern = "*"; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /BitsUpdatePacker/Data/StringRequiredValidationRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows.Controls; 6 | 7 | namespace BitsUpdatePacker.Data 8 | { 9 | public sealed class StringRequiredValidationRule : ValidationRule 10 | { 11 | public String ErrorMessage 12 | { 13 | get; 14 | set; 15 | } 16 | 17 | public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) 18 | { 19 | var isValid = (value ?? String.Empty).ToString().Length > 0; 20 | return new ValidationResult(isValid, (isValid ? null : ErrorMessage)); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /BitsUpdater/UpdateCheckedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace BitsUpdater 7 | { 8 | /// 9 | /// Event args used by CheckUpdate method in BitsUpdater. 10 | /// 11 | public sealed class UpdateCheckedEventArgs : EventArgs 12 | { 13 | /// 14 | /// True if new updates are available, false in there are no new updates. 15 | /// 16 | public bool UpdatesAvailable 17 | { 18 | get; 19 | private set; 20 | } 21 | 22 | public UpdateCheckedEventArgs(bool updatesAvailable) 23 | { 24 | UpdatesAvailable = updatesAvailable; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /BitsUpdatePacker/Data/VersionConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows.Data; 6 | 7 | namespace BitsUpdatePacker.Data 8 | { 9 | [ValueConversion(typeof(object), typeof(Version))] 10 | public sealed class VersionConverter : IValueConverter 11 | { 12 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 13 | { 14 | return (value ?? String.Empty).ToString(); 15 | } 16 | 17 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 18 | { 19 | return new Version((string)value); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /BitsUpdatePacker/Data/DirectoryExistsValidationRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows.Controls; 6 | using System.IO; 7 | 8 | namespace BitsUpdatePacker.Data 9 | { 10 | public sealed class DirectoryExistsValidationRule : ValidationRule 11 | { 12 | public String ErrorMessage 13 | { 14 | get; 15 | set; 16 | } 17 | 18 | public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) 19 | { 20 | bool isValid = false; 21 | if (value != null) 22 | { 23 | isValid = Directory.Exists(value.ToString()); 24 | } 25 | return new ValidationResult(isValid, (isValid ? null : ErrorMessage)); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /BitsUpdatePacker/Data/SearchOptionToBoolConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows.Data; 6 | using System.IO; 7 | 8 | namespace BitsUpdatePacker.Data 9 | { 10 | [ValueConversion(typeof(object), typeof(Version))] 11 | public sealed class SearchOptionToBoolConverter : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 14 | { 15 | return (SearchOption)value == SearchOption.AllDirectories; 16 | } 17 | 18 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 19 | { 20 | return (bool)value ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /BitsUpdatePacker/Data/ValidationBorderConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows.Controls; 6 | using System.Windows.Data; 7 | using System.Windows; 8 | 9 | namespace BitsUpdatePacker.Data 10 | { 11 | [ValueConversion(typeof(object), typeof(ValidationError))] 12 | public sealed class ValidationBorderConverter : IValueConverter 13 | { 14 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 15 | { 16 | return (value == null) ? new Thickness(0) : new Thickness(1); 17 | } 18 | 19 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 20 | { 21 | throw new NotImplementedException(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /BitsUpdater/UpdateErrorEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using SharpBits.Base; 6 | 7 | namespace BitsUpdater 8 | { 9 | /// 10 | /// Event args used to notify if error occured while using BITS download. 11 | /// 12 | public sealed class UpdateErrorEventArgs : EventArgs 13 | { 14 | /// 15 | /// Error Description. 16 | /// 17 | public string Description 18 | { 19 | get; 20 | set; 21 | } 22 | 23 | /// 24 | /// Error Code. 25 | /// 26 | public int Code 27 | { 28 | get; 29 | set; 30 | } 31 | 32 | public UpdateErrorEventArgs(BitsError error) 33 | { 34 | Description = error.Description; 35 | Code = error.ErrorCode; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /BitsUpdatePacker/Configuration/TemplatesCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Configuration; 6 | 7 | namespace BitsUpdatePacker.Configuration 8 | { 9 | [ConfigurationCollection(typeof(TemplatesElement))] 10 | internal sealed class TemplatesCollection : ConfigurationElementCollection 11 | { 12 | protected override ConfigurationElement CreateNewElement() 13 | { 14 | return new TemplatesElement(); 15 | } 16 | 17 | protected override object GetElementKey(ConfigurationElement element) 18 | { 19 | return (((TemplatesElement)(element)).Directory + ((TemplatesElement)(element)).Pattern).GetHashCode(); 20 | } 21 | 22 | public TemplatesElement this[int idx] 23 | { 24 | get 25 | { 26 | return (TemplatesElement)BaseGet(idx); 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /BitsUpdatePacker/UpdatePackerCommands.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows.Input; 6 | 7 | namespace BitsUpdatePacker 8 | { 9 | public sealed class UpdatePackerCommands 10 | { 11 | public static readonly RoutedUICommand CreatePackage = new RoutedUICommand("CreatePackage", "CreatePackage", typeof(UpdatePackerCommands)); 12 | public static readonly RoutedUICommand SelectFolder = new RoutedUICommand("SelectFolder", "SelectFolder", typeof(UpdatePackerCommands)); 13 | public static readonly RoutedUICommand SelectFile = new RoutedUICommand("SelectFile", "SelectFile", typeof(UpdatePackerCommands)); 14 | public static readonly RoutedUICommand AddNewTemplate = new RoutedUICommand("AddNewTemplate", "AddNewTemplate", typeof(UpdatePackerCommands)); 15 | public static readonly RoutedUICommand RemoveTemplate = new RoutedUICommand("RemoveTemplate", "RemoveTemplate", typeof(UpdatePackerCommands)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /BitsUpdater/UpdateProgressEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using SharpBits.Base; 6 | 7 | namespace BitsUpdater 8 | { 9 | /// 10 | /// Update progress event args used in UpdateProgressChanged event in BitsUpdater while BITS is downloading. 11 | /// 12 | public sealed class UpdateProgressEventArgs : EventArgs 13 | { 14 | /// 15 | /// Current bytes transferred by BITS. 16 | /// 17 | public ulong BytesTranferred 18 | { 19 | get; 20 | private set; 21 | } 22 | 23 | /// 24 | /// Total size of update. 25 | /// 26 | public ulong BytesTotal 27 | { 28 | get; 29 | private set; 30 | } 31 | 32 | public UpdateProgressEventArgs(ulong bytesTransferred, ulong bytesTotal) 33 | { 34 | BytesTranferred = bytesTransferred; 35 | BytesTotal = bytesTotal; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /BitsUpdatePacker/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.1 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace BitsUpdatePacker.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /BitsUpdatePacker/Data/RegexValidationRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows.Controls; 6 | using System.Globalization; 7 | using System.Text.RegularExpressions; 8 | 9 | namespace BitsUpdatePacker.Data 10 | { 11 | public sealed class RegexValidationRule : ValidationRule 12 | { 13 | private string _pattern; 14 | 15 | public override ValidationResult Validate(object value, CultureInfo cultureInfo) 16 | { 17 | ValidationResult result = new ValidationResult(true, null); 18 | 19 | if (!string.IsNullOrEmpty(_pattern)) 20 | { 21 | if (!Regex.IsMatch((value ?? String.Empty).ToString(), _pattern)) 22 | { 23 | result = new ValidationResult(false, ErrorMessage); 24 | } 25 | } 26 | 27 | return result; 28 | } 29 | 30 | public string Pattern 31 | { 32 | get { return _pattern; } 33 | set { _pattern = value; } 34 | } 35 | 36 | public String ErrorMessage 37 | { 38 | get; 39 | set; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /BitsUpdater/FileSearchTemplate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | 7 | namespace BitsUpdater 8 | { 9 | /// 10 | /// FileSearchTemplate is a mask used by BitsUpdatePacker to search files that are included in UpdatePackage. 11 | /// 12 | public struct FileSearchTemplate 13 | { 14 | /// 15 | /// Search pattern used in Directory.GetFiles() method. 16 | /// 17 | public string Pattern 18 | { 19 | get; 20 | set; 21 | } 22 | 23 | /// 24 | /// Root directory used for search. 25 | /// 26 | public DirectoryInfo Directory 27 | { 28 | get; 29 | set; 30 | } 31 | 32 | /// 33 | /// Option to define search behavior. 34 | /// 35 | public SearchOption SearchOption 36 | { 37 | get; 38 | set; 39 | } 40 | 41 | public FileSearchTemplate(DirectoryInfo directory, string pattern, SearchOption option) 42 | : this() 43 | { 44 | Pattern = pattern; 45 | Directory = directory; 46 | SearchOption = option; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /BitsUpdatePacker/Data/CertificateValidationRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows.Controls; 6 | using System.IO; 7 | using System.Reflection; 8 | 9 | namespace BitsUpdatePacker.Data 10 | { 11 | public sealed class CertificateValidationRule : ValidationRule 12 | { 13 | public String ErrorMessage 14 | { 15 | get; 16 | set; 17 | } 18 | 19 | public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) 20 | { 21 | bool isValid = false; 22 | if (value != null) 23 | { 24 | isValid = true; 25 | try 26 | { 27 | using (var certificate = new FileStream(value.ToString(), FileMode.Open, FileAccess.Read)) 28 | { 29 | var publicKey = new StrongNameKeyPair(certificate).PublicKey; 30 | } 31 | } 32 | catch (IOException) 33 | { 34 | isValid = false; 35 | } 36 | catch (ArgumentException) 37 | { 38 | isValid = false; 39 | } 40 | } 41 | return new ValidationResult(isValid, (isValid ? null : ErrorMessage)); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /BitsUpdatePacker/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Windows; 7 | 8 | namespace BitsUpdatePacker 9 | { 10 | /// 11 | /// Interaction logic for App.xaml 12 | /// 13 | public partial class App : Application 14 | { 15 | private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) 16 | { 17 | if (this.MainWindow != null) 18 | { 19 | var result = MessageBox.Show(this.MainWindow 20 | , e.Exception.GetType().FullName + "\r\n\r\n" + e.Exception.Message + "\r\n\r\nDo you want to continue?", "Oooops, something went wrong..." 21 | , MessageBoxButton.OK 22 | , MessageBoxImage.Error); 23 | } 24 | else 25 | { 26 | var result = MessageBox.Show(e.Exception.GetType().FullName + "\r\n\r\n" + e.Exception.Message + "\r\n\r\nDo you want to continue?", "Oooops, something went wrong..." 27 | , MessageBoxButton.OK 28 | , MessageBoxImage.Error); 29 | } 30 | e.Handled = true; 31 | App.Current.Shutdown(1); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /BitsUpdatePacker/SelectFileControl.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using System.Windows.Data; 8 | using System.Windows.Documents; 9 | using System.Windows.Input; 10 | using System.Windows.Media; 11 | using System.Windows.Media.Imaging; 12 | using System.Windows.Navigation; 13 | using System.Windows.Shapes; 14 | 15 | namespace BitsUpdatePacker 16 | { 17 | public partial class SelectFileControl : UserControl 18 | { 19 | public static readonly DependencyProperty FilePathProperty = DependencyProperty.Register("FilePath", typeof(string), typeof(SelectFileControl)); 20 | public string FilePath 21 | { 22 | get { return (string)GetValue(FilePathProperty); } 23 | set { SetValue(FilePathProperty, value); } 24 | } 25 | 26 | public SelectFileControl() 27 | { 28 | InitializeComponent(); 29 | } 30 | 31 | private void SelectFileExecuted(object sender, ExecutedRoutedEventArgs e) 32 | { 33 | using (var dialog = new System.Windows.Forms.OpenFileDialog()) 34 | { 35 | if (!String.IsNullOrEmpty(FilePath)) 36 | { 37 | dialog.FileName = FilePath; 38 | } 39 | dialog.ShowDialog(); 40 | FilePath = dialog.FileName; 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /BitsUpdatePacker/SelectFolderControl.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using System.Windows.Data; 8 | using System.Windows.Documents; 9 | using System.Windows.Input; 10 | using System.Windows.Media; 11 | using System.Windows.Media.Imaging; 12 | using System.Windows.Navigation; 13 | using System.Windows.Shapes; 14 | 15 | namespace BitsUpdatePacker 16 | { 17 | public partial class SelectFolderControl : UserControl 18 | { 19 | public static readonly DependencyProperty FolderPathProperty = DependencyProperty.Register("FolderPath", typeof(string), typeof(SelectFolderControl)); 20 | public string FolderPath 21 | { 22 | get { return (string)GetValue(FolderPathProperty); } 23 | set { SetValue(FolderPathProperty, value); } 24 | } 25 | 26 | public SelectFolderControl() 27 | { 28 | InitializeComponent(); 29 | } 30 | 31 | private void SelectFolderExecuted(object sender, ExecutedRoutedEventArgs e) 32 | { 33 | using (var dialog = new System.Windows.Forms.FolderBrowserDialog()) 34 | { 35 | if (!String.IsNullOrEmpty(FolderPath)) 36 | { 37 | dialog.SelectedPath = FolderPath; 38 | } 39 | dialog.ShowDialog(); 40 | FolderPath = dialog.SelectedPath; 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /BitsUpdatePacker/Configuration/TemplatesElement.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Configuration; 6 | using System.IO; 7 | 8 | namespace BitsUpdatePacker.Configuration 9 | { 10 | internal sealed class TemplatesElement : ConfigurationElement 11 | { 12 | [ConfigurationProperty("directory", DefaultValue = "", IsKey = false, IsRequired = true)] 13 | public string Directory 14 | { 15 | get 16 | { 17 | return ((string)(base["directory"])); 18 | } 19 | set 20 | { 21 | base["directory"] = value; 22 | } 23 | } 24 | 25 | [ConfigurationProperty("pattern", DefaultValue = "", IsKey = false, IsRequired = false)] 26 | public string Pattern 27 | { 28 | get 29 | { 30 | return ((string)(base["pattern"])); 31 | } 32 | set 33 | { 34 | base["pattern"] = value; 35 | } 36 | } 37 | 38 | [ConfigurationProperty("searchOption", DefaultValue = "TopDirectoryOnly", IsKey = false, IsRequired = false)] 39 | public SearchOption SearchOption 40 | { 41 | get 42 | { 43 | return (SearchOption)base["searchOption"]; 44 | } 45 | set 46 | { 47 | base["searchOption"] = value; 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ApplicationLauncher/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | using System.Diagnostics; 7 | 8 | namespace ApplicationLauncher 9 | { 10 | class Program 11 | { 12 | static void Main(string[] args) 13 | { 14 | string versionDirectory = "Version"; 15 | string applicationName = "BitsUpdater.Example.exe"; 16 | var latestVersion = GetLatestVersionDirectory(versionDirectory); 17 | 18 | string processPath = Path.Combine(versionDirectory, Path.Combine(latestVersion.ToString(), applicationName)); 19 | Process.Start(new ProcessStartInfo(processPath)); 20 | } 21 | 22 | private static Version GetLatestVersionDirectory(string versionDirectory) 23 | { 24 | Version max = new Version(); 25 | foreach (var item in Directory.GetDirectories(versionDirectory)) 26 | { 27 | try 28 | { 29 | var current = new Version(Path.GetFileName(item)); 30 | if (current > max) 31 | { 32 | max = current; 33 | } 34 | } 35 | catch (ArgumentException) { /* Version try parse */ } 36 | catch (OverflowException) { /* Version try parse */ } 37 | catch (FormatException) { /* Version try parse */ } 38 | } 39 | 40 | return max; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /BitsUpdater/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("BitsUpdater")] 9 | [assembly: AssemblyDescription("BitsUpdater is C# updating library using BITS for download.")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Jakub Chodounsky")] 12 | [assembly: AssemblyProduct("BitsUpdater")] 13 | [assembly: AssemblyCopyright("Copyright © Jakub Chodounsky 2010")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("36bc5e0f-b88e-4c57-9a56-adc1ce19fe94")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /BitsUpdatePacker/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /BitsUpdater.Example/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("BitsUpdater.Example")] 9 | [assembly: AssemblyDescription("Example application using BitsUpdater library.")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Jakub Chodounsky")] 12 | [assembly: AssemblyProduct("BitsUpdater.Example")] 13 | [assembly: AssemblyCopyright("Copyright © Jakub Chodounsky 2010")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8bbb4c76-4d40-4c18-8d0f-9667707b9604")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.1.0")] 36 | [assembly: AssemblyFileVersion("1.0.1.0")] 37 | -------------------------------------------------------------------------------- /ApplicationLauncher/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ApplicationLauncher")] 9 | [assembly: AssemblyDescription("Example application launcher determines last version to run.")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Jakub Chodounsky")] 12 | [assembly: AssemblyProduct("ApplicationLauncher")] 13 | [assembly: AssemblyCopyright("Copyright © Jakub Chodounsky 2010")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("361bfc8c-f256-4828-9f76-17d01781e88b")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /BitsUpdatePacker/Data/DirectoryCreateValidationRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows.Controls; 6 | using System.IO; 7 | 8 | namespace BitsUpdatePacker.Data 9 | { 10 | public sealed class DirectoryCreateValidationRule : ValidationRule 11 | { 12 | public String ErrorMessage 13 | { 14 | get; 15 | set; 16 | } 17 | 18 | public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) 19 | { 20 | bool isValid = false; 21 | 22 | if (value != null) 23 | { 24 | isValid = true; 25 | var directoryPath = value.ToString(); 26 | if (!Directory.Exists(directoryPath)) 27 | { 28 | try 29 | { 30 | Directory.CreateDirectory(directoryPath); 31 | } 32 | catch (IOException) 33 | { 34 | isValid = false; 35 | } 36 | catch (ArgumentException) 37 | { 38 | isValid = false; 39 | } 40 | catch (NotSupportedException) 41 | { 42 | isValid = false; 43 | } 44 | catch (UnauthorizedAccessException) 45 | { 46 | isValid = false; 47 | } 48 | } 49 | } 50 | 51 | return new ValidationResult(isValid, (isValid ? null : ErrorMessage)); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /BitsUpdatePacker/SelectFileControl.xaml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 29 | 30 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 89 | Version: 90 | 91 | 94 | 95 | 96 | 98 | 99 | 100 | 101 | 104 | 105 | 106 | Url Directory (not the file Url!): 107 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | Certificate: 119 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | Output Directory: 131 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 146 | 159 | 160 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | Update folders and files: 179 | 192 | 193 | 194 | 196 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | Excluded folders and files: 210 | 223 | 224 | 225 | 227 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /BitsUpdater/UpdatePackage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | using System.Reflection; 7 | using System.Reflection.Emit; 8 | using System.IO.Compression; 9 | using BitsUpdater.Extensions; 10 | using System.Text.RegularExpressions; 11 | using System.Globalization; 12 | 13 | namespace BitsUpdater 14 | { 15 | /// 16 | /// Class for creating and unpacking normalised BitsUpdater update packages that are used in whole update process. 17 | /// 18 | public sealed class UpdatePackage 19 | { 20 | private sealed class AssemblyProxy : MarshalByRefObject 21 | { 22 | public void ExtractUpdate(Version version, DirectoryInfo outputDirectory, string publicToken) 23 | { 24 | Assembly update = Assembly.ReflectionOnlyLoad(String.Format("{0}, Version={1}, Culture=neutral, PublicKeyToken={2}", string.Format(UpdatePackage.AssemblyName, version), version, publicToken)); 25 | 26 | foreach (string name in update.GetManifestResourceNames()) 27 | { 28 | using (var fs = new FileStream(Path.Combine(outputDirectory.FullName, name), FileMode.Create)) 29 | { 30 | update.GetManifestResourceStream(name).CopyTo(fs); 31 | } 32 | } 33 | } 34 | } 35 | 36 | private readonly string _certificatePath; 37 | private readonly Version _version; 38 | private readonly bool _isDifferential; 39 | private readonly List _included = new List(); 40 | private readonly List _excluded = new List(); 41 | internal const string LatestVersionDirectory = "LatestVersion\\"; 42 | public const string AssemblyName = "Update.{0}"; 43 | public const string AssemblySuffix = ".dll"; 44 | public const string PackageSuffix = ".gz"; 45 | 46 | public UpdatePackage(string certificatePath, Version version, bool isDifferential) 47 | { 48 | _certificatePath = certificatePath; 49 | _version = version; 50 | _isDifferential = isDifferential; 51 | } 52 | 53 | /// 54 | /// List of templates specifying files that are included in update. 55 | /// 56 | public IList IncludedFiles 57 | { 58 | get 59 | { 60 | return _included; 61 | } 62 | } 63 | 64 | /// 65 | /// List of templates for files that are NOT included in update. 66 | /// 67 | public IList ExcludedFiles 68 | { 69 | get 70 | { 71 | return _excluded; 72 | } 73 | } 74 | 75 | /// 76 | /// Creates normalized Update Package for BitsUpdater library. 77 | /// 78 | /// Directory where to save files. It is recommended to use one directory because of program looking for Last Version files during differential update. 79 | /// Assembly Thumbprint as string for retrieving assembly content during unpacking phase. 80 | public string Create(DirectoryInfo outputDirectory) 81 | { 82 | using (var certificate = new FileStream(_certificatePath, FileMode.Open, FileAccess.Read)) 83 | { 84 | FileInfo fileName = new FileInfo(string.Format(AssemblyName + AssemblySuffix, _version)); 85 | var name = new AssemblyName(string.Format(AssemblyName, _version)) 86 | { 87 | Version = _version, 88 | KeyPair = new StrongNameKeyPair(certificate), 89 | }; 90 | var builder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Save, outputDirectory.FullName); 91 | var moduleBuilder = builder.DefineDynamicModule(name.Name, fileName.Name); 92 | 93 | IEnumerable files; 94 | if (_isDifferential && Directory.Exists(Path.Combine(outputDirectory.FullName, LatestVersionDirectory))) 95 | { 96 | files = CreateDifferentialPackage(moduleBuilder, outputDirectory); 97 | } 98 | else 99 | { 100 | files = CreatePackage(moduleBuilder, outputDirectory); 101 | } 102 | 103 | builder.Save(fileName.Name); 104 | 105 | foreach (var item in files) 106 | { 107 | item.Dispose(); 108 | } 109 | 110 | Compress(outputDirectory, fileName.Name); 111 | return RetrievePublicTokenString(name); 112 | } 113 | } 114 | 115 | internal static void Extract(DirectoryInfo outputDirectory, Version version, string publicToken) 116 | { 117 | FileInfo packageLocation = new FileInfo(Path.Combine(outputDirectory.Parent.FullName, string.Format(AssemblyName, version) + AssemblySuffix + PackageSuffix)); 118 | FileInfo assemblyLocation = new FileInfo(Path.Combine(Assembly.GetEntryAssembly().GetDirectory(), string.Format(AssemblyName, version) + AssemblySuffix)); 119 | CopyPreviousFiles(outputDirectory); 120 | Decompress(packageLocation, assemblyLocation); 121 | ExtractFiles(version, outputDirectory, publicToken, assemblyLocation); 122 | } 123 | 124 | private static void CopyPreviousFiles(DirectoryInfo outputDirectory) 125 | { 126 | if (outputDirectory.Exists) 127 | { 128 | outputDirectory.Delete(true); 129 | } 130 | 131 | DirectoryInfo versionDirectory = outputDirectory.Parent; 132 | Version max = new Version(); 133 | foreach (var item in versionDirectory.GetDirectories()) 134 | { 135 | try 136 | { 137 | var current = new Version(item.Name); 138 | if (current > max) 139 | { 140 | max = current; 141 | } 142 | } 143 | catch (ArgumentException) { /* Version try parse */ } 144 | catch (OverflowException) { /* Version try parse */ } 145 | catch (FormatException) { /* Version try parse */ } 146 | } 147 | 148 | outputDirectory.Create(); 149 | 150 | if (max > new Version()) 151 | { 152 | foreach (var item in Directory.GetFiles(Path.Combine(versionDirectory.FullName, max.ToString()))) 153 | { 154 | if (!item.EndsWith(UpdateStatus.UpdateStatusFileName, true, CultureInfo.InvariantCulture)) 155 | { 156 | using (FileStream input = new FileStream(item, FileMode.Open, FileAccess.Read)) 157 | { 158 | using (FileStream output = new FileStream(Path.Combine(outputDirectory.FullName, Path.GetFileName(item)), FileMode.OpenOrCreate)) 159 | { 160 | input.CopyTo(output); 161 | } 162 | } 163 | } 164 | } 165 | } 166 | } 167 | 168 | private static void ExtractFiles(Version version, DirectoryInfo outputDirectory, string publicToken, FileInfo assemblyLocation) 169 | { 170 | var domain = AppDomain.CreateDomain("TemporaryDomain"); 171 | var proxy = domain.CreateInstanceAndUnwrap(Assembly.GetAssembly(typeof(AssemblyProxy)).FullName, typeof(AssemblyProxy).ToString()) as AssemblyProxy; 172 | if (proxy != null) 173 | { 174 | proxy.ExtractUpdate(version, outputDirectory, publicToken); 175 | } 176 | AppDomain.Unload(domain); 177 | assemblyLocation.Delete(); 178 | } 179 | 180 | private string RetrievePublicTokenString(AssemblyName name) 181 | { 182 | var builder = new StringBuilder(); 183 | var token = name.GetPublicKeyToken(); 184 | for (int i = 0; i < token.GetLength(0); i++) 185 | { 186 | builder.Append(token[i].ToString("x")); 187 | } 188 | return builder.ToString(); 189 | } 190 | 191 | private IEnumerable CreatePackage(ModuleBuilder moduleBuilder, DirectoryInfo outputDirectory) 192 | { 193 | var files = new List(); 194 | 195 | foreach (var item in IncludedFiles) 196 | { 197 | files.AddRange(AddFiles(moduleBuilder, item, false, null)); 198 | } 199 | 200 | DirectoryInfo lastVersionDirectoryPath = new DirectoryInfo(Path.Combine(outputDirectory.FullName, LatestVersionDirectory)); 201 | if (lastVersionDirectoryPath.Exists) 202 | { 203 | lastVersionDirectoryPath.Delete(true); 204 | } 205 | 206 | lastVersionDirectoryPath.Create(); 207 | 208 | FillLatestVersionDirectory(files, lastVersionDirectoryPath); 209 | 210 | return files; 211 | } 212 | 213 | private IEnumerable CreateDifferentialPackage(ModuleBuilder moduleBuilder, DirectoryInfo outputDirectory) 214 | { 215 | var files = new List(); 216 | DirectoryInfo lastVersionDirectoryPath = new DirectoryInfo(Path.Combine(outputDirectory.FullName, LatestVersionDirectory)); 217 | 218 | foreach (var item in IncludedFiles) 219 | { 220 | files.AddRange(AddFiles(moduleBuilder, item, true, lastVersionDirectoryPath)); 221 | } 222 | 223 | FillLatestVersionDirectory(files, lastVersionDirectoryPath); 224 | 225 | return files; 226 | } 227 | 228 | private void FillLatestVersionDirectory(List files, DirectoryInfo lastVersionDirectoryPath) 229 | { 230 | foreach (FileStream file in files) 231 | { 232 | using (FileStream copy = new FileStream(Path.Combine(lastVersionDirectoryPath.FullName, Path.GetFileName(file.Name)), FileMode.Create)) 233 | { 234 | file.CopyTo(copy); 235 | } 236 | } 237 | } 238 | 239 | private IEnumerable AddFiles(ModuleBuilder moduleBuilder, FileSearchTemplate template, bool compareLatest, DirectoryInfo lastVersionDirectoryPath) 240 | { 241 | var files = new List(); 242 | var excludedFileNames = GetExcludedFileNames(ExcludedFiles); 243 | if (template.Directory.Exists) 244 | { 245 | foreach (var fileInfo in template.Directory.GetFiles(template.Pattern, template.SearchOption)) 246 | { 247 | if (!ExcludedContains(fileInfo, excludedFileNames)) 248 | { 249 | var file = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read); 250 | if (compareLatest) 251 | { 252 | FileInfo latestFilePath = new FileInfo(Path.Combine(lastVersionDirectoryPath.FullName, fileInfo.Name)); 253 | if (latestFilePath.Exists) 254 | { 255 | using (var latestFile = new FileStream(latestFilePath.FullName, FileMode.Open, FileAccess.Read)) 256 | { 257 | if (!file.AreEqual(latestFile)) 258 | { 259 | AddFile(moduleBuilder, fileInfo, file, files); 260 | } 261 | else 262 | { 263 | file.Close(); 264 | } 265 | } 266 | } 267 | else 268 | { 269 | AddFile(moduleBuilder, fileInfo, file, files); 270 | } 271 | } 272 | else 273 | { 274 | AddFile(moduleBuilder, fileInfo, file, files); 275 | } 276 | } 277 | } 278 | } 279 | 280 | return files; 281 | } 282 | 283 | private bool ExcludedContains(FileInfo fileInfo, IEnumerable excluded) 284 | { 285 | foreach (var item in excluded) 286 | { 287 | if (fileInfo.FullName == item.FullName) 288 | { 289 | return true; 290 | } 291 | } 292 | return false; 293 | } 294 | 295 | private void AddFile(ModuleBuilder moduleBuilder, FileInfo filePath, FileStream file, List files) 296 | { 297 | moduleBuilder.DefineManifestResource(filePath.Name, file, ResourceAttributes.Public); 298 | files.Add(file); 299 | } 300 | 301 | private IEnumerable GetExcludedFileNames(IEnumerable filesNotForUpdate) 302 | { 303 | var result = new List(); 304 | 305 | foreach (var item in filesNotForUpdate) 306 | { 307 | if (item.Directory.Exists) 308 | { 309 | result.AddRange(item.Directory.GetFiles(item.Pattern, item.SearchOption)); 310 | } 311 | } 312 | 313 | return result; 314 | } 315 | 316 | private void Compress(DirectoryInfo directory, string fileName) 317 | { 318 | string inFilePath = Path.Combine(directory.FullName, fileName); 319 | string outFilePath = Path.Combine(directory.FullName, fileName + PackageSuffix); 320 | using (var inFile = new FileStream(inFilePath, FileMode.Open, FileAccess.Read)) 321 | { 322 | using (var outFile = new FileStream(outFilePath, FileMode.Create)) 323 | { 324 | using (var compress = new GZipStream(outFile, CompressionMode.Compress)) 325 | { 326 | inFile.CopyTo(compress); 327 | } 328 | } 329 | } 330 | File.Delete(inFilePath); 331 | } 332 | 333 | private static void Decompress(FileInfo packageName, FileInfo assemblyLocation) 334 | { 335 | using (var inFile = new FileStream(packageName.FullName, FileMode.Open)) 336 | { 337 | using (var outFile = new FileStream(assemblyLocation.FullName, FileMode.Create)) 338 | { 339 | using (var decompress = new GZipStream(inFile, CompressionMode.Decompress)) 340 | { 341 | decompress.CopyTo(outFile); 342 | } 343 | } 344 | } 345 | packageName.Delete(); 346 | } 347 | } 348 | } 349 | --------------------------------------------------------------------------------