├── 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 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/BitsUpdatePacker/SelectFolderControl.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
22 |
23 |
24 |
25 |
28 |
29 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/BitsUpdater/Extensions/StreamExtensions.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.Extensions
8 | {
9 | public static class StreamExtensions
10 | {
11 | public static void CopyTo(this Stream input, Stream destination, int bufferSize)
12 | {
13 | var buffer = new byte[bufferSize];
14 | int read = 0;
15 | do
16 | {
17 | read = input.Read(buffer, 0, bufferSize);
18 | destination.Write(buffer, 0, read);
19 | } while (read > 0);
20 | }
21 |
22 | public static void CopyTo(this Stream input, Stream destination)
23 | {
24 | var bufferSize = 1048576;
25 | CopyTo(input, destination, bufferSize);
26 | }
27 |
28 | public static bool AreEqual(this Stream input, Stream other)
29 | {
30 | int buffer = sizeof(Int64);
31 |
32 | if (input.Length != other.Length)
33 | return false;
34 |
35 | int iterations = (int)Math.Ceiling((double)input.Length / buffer);
36 |
37 | byte[] one = new byte[buffer];
38 | byte[] two = new byte[buffer];
39 |
40 | for (int i = 0; i < iterations; i++)
41 | {
42 | input.Read(one, 0, buffer);
43 | other.Read(two, 0, buffer);
44 |
45 | if (BitConverter.ToInt64(one, 0) != BitConverter.ToInt64(two, 0))
46 | {
47 | input.Position = 0;
48 | other.Position = 0;
49 | return false;
50 | }
51 | }
52 | input.Position = 0;
53 | other.Position = 0;
54 | return true;
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/BitsUpdater.Example/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.Reflection;
7 | using BitsUpdater.Extensions;
8 |
9 | namespace BitsUpdater.Example
10 | {
11 | class Program
12 | {
13 | public const String PublicToken = "e9aa88526a6ef0e2";
14 |
15 | static void Main(string[] args)
16 | {
17 | var assemblyDirectory = Assembly.GetExecutingAssembly().GetDirectory();
18 | Console.WriteLine("Starting BitsUpdater.Example version: " + Assembly.GetExecutingAssembly().GetName().Version.ToString() +" from location " + assemblyDirectory);
19 | Console.WriteLine("Press key to continue...");
20 | Console.ReadKey();
21 |
22 | BitsUpdater updater = new BitsUpdater("http://chodounsky.net/projects/BitsUpdater.Example/UpdateManifest.xml", Path.GetDirectoryName(assemblyDirectory));
23 | RegisterUpdaterEvents(updater);
24 | updater.ResumePreviousDownload();
25 |
26 | updater.CheckUpdateAsync();
27 |
28 | Console.ReadKey();
29 | }
30 |
31 | private static void RegisterUpdaterEvents(BitsUpdater updater)
32 | {
33 | updater.UpdateDownloaded += (s, e) =>
34 | {
35 | Console.WriteLine("Update package is downloaded. Starting to apply update.");
36 | updater.Update(PublicToken);
37 | };
38 |
39 | updater.UpdateDownloadError += (s, e) =>
40 | {
41 | Console.WriteLine("Download error(" + e.Code + ") occured: " + e.Description);
42 | };
43 |
44 | updater.UpdateDownloadProgressChanged += (s, e) =>
45 | {
46 | Console.WriteLine("Downloaded " + e.BytesTranferred/1024 + "/" + e.BytesTotal/1024);
47 | };
48 |
49 | updater.UpdateChecked += (s, e) =>
50 | {
51 | if (e.UpdatesAvailable)
52 | {
53 | Console.WriteLine("New updates are ready to download!");
54 | updater.Download();
55 | }
56 | else
57 | {
58 | Console.WriteLine("There are no new updates.");
59 | }
60 | };
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/BitsUpdatePacker/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("BitsUpdatePacker")]
11 | [assembly: AssemblyDescription("BitsUpdatePacker is program used to create update packages for BitsUpdater")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("Jakub Chodounsky")]
14 | [assembly: AssemblyProduct("BitsUpdatePacker")]
15 | [assembly: AssemblyCopyright("Copyright © Jakub Chodounsky 2010")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Setting ComVisible to false makes the types in this assembly not visible
20 | // to COM components. If you need to access a type in this assembly from
21 | // COM, set the ComVisible attribute to true on that type.
22 | [assembly: ComVisible(false)]
23 |
24 | //In order to begin building localizable applications, set
25 | //CultureYouAreCodingWith in your .csproj file
26 | //inside a . For example, if you are using US english
27 | //in your source files, set the to en-US. Then uncomment
28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
29 | //the line below to match the UICulture setting in the project file.
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
36 | //(used if a resource is not found in the page,
37 | // or application resource dictionaries)
38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
39 | //(used if a resource is not found in the page,
40 | // app, or any theme specific resource dictionaries)
41 | )]
42 |
43 |
44 | // Version information for an assembly consists of the following four values:
45 | //
46 | // Major Version
47 | // Minor Version
48 | // Build Number
49 | // Revision
50 | //
51 | // You can specify all the values or you can default the Build and Revision Numbers
52 | // by using the '*' as shown below:
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion("1.0.0.0")]
55 | [assembly: AssemblyFileVersion("1.0.0.0")]
56 |
--------------------------------------------------------------------------------
/BitsUpdatePacker/Properties/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
47 |
--------------------------------------------------------------------------------
/BitsUpdater.Example/BitsUpdater.Example.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | x86
6 | 8.0.30703
7 | 2.0
8 | {63730B60-110F-447F-99EF-93784DA4E11A}
9 | Exe
10 | Properties
11 | BitsUpdater.Example
12 | BitsUpdater.Example
13 | v4.0
14 | Client
15 | 512
16 |
17 |
18 | x86
19 | true
20 | full
21 | false
22 | bin\Debug\
23 | DEBUG;TRACE
24 | prompt
25 | 4
26 |
27 |
28 | x86
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | {722D747F-8C34-48B0-9301-F40A8B4CA2B8}
52 | BitsUpdater
53 |
54 |
55 |
56 |
57 |
58 |
59 |
66 |
--------------------------------------------------------------------------------
/BitsUpdater/UpdateStatus.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Xml.Serialization;
6 | using System.IO;
7 | using System.Reflection;
8 | using BitsUpdater.Extensions;
9 |
10 | namespace BitsUpdater
11 | {
12 | internal sealed class UpdateStatus
13 | {
14 | internal const String UpdateStatusFileName = "UpdateStatus.xml";
15 | private static readonly XmlSerializer _xmlUpdateStatusSerializer = new XmlSerializer(typeof(XmlUpdateStatus));
16 | private XmlUpdateStatus _updateStatus = new XmlUpdateStatus();
17 | private Guid _jobId;
18 | private Version _nextVersion;
19 |
20 | public Version NextVersion
21 | {
22 | get
23 | {
24 | return _nextVersion;
25 | }
26 | set
27 | {
28 | _nextVersion = value;
29 | _updateStatus.NextVersion = _nextVersion.ToString();
30 | }
31 | }
32 |
33 | public Guid BitsJobId
34 | {
35 | get
36 | {
37 | return _jobId;
38 | }
39 | set
40 | {
41 | _jobId = value;
42 | _updateStatus.BitsJobId = _jobId.ToString();
43 | }
44 | }
45 |
46 | private UpdateStatus()
47 | {
48 | }
49 |
50 | public static UpdateStatus Load()
51 | {
52 | var updateStatus = new UpdateStatus();
53 |
54 | try
55 | {
56 | using (var xmlFile = new FileStream(Path.Combine(Assembly.GetEntryAssembly().GetDirectory(), UpdateStatusFileName), FileMode.Open, FileAccess.Read))
57 | {
58 | updateStatus._updateStatus = (XmlUpdateStatus)_xmlUpdateStatusSerializer.Deserialize(xmlFile);
59 | }
60 | }
61 | catch (FileNotFoundException)
62 | {
63 | updateStatus.CreateDefault();
64 | }
65 |
66 | try
67 | {
68 | updateStatus._jobId = new Guid(updateStatus._updateStatus.BitsJobId);
69 | updateStatus._nextVersion = new Version(updateStatus._updateStatus.NextVersion);
70 | }
71 | catch (FormatException)
72 | {
73 | updateStatus.CreateDefault();
74 | }
75 |
76 | return updateStatus;
77 | }
78 |
79 | public void Save()
80 | {
81 | using (var file = new FileStream(Path.Combine(Assembly.GetEntryAssembly().GetDirectory(), UpdateStatusFileName), FileMode.OpenOrCreate))
82 | {
83 | _xmlUpdateStatusSerializer.Serialize(file, _updateStatus);
84 | }
85 | }
86 |
87 | private void CreateDefault()
88 | {
89 | BitsJobId = Guid.Empty;
90 | NextVersion = new Version();
91 | Save();
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/ApplicationLauncher/ApplicationLauncher.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | x86
6 | 8.0.30703
7 | 2.0
8 | {F04A7A97-B907-40BC-8DE2-00EA270AAC8C}
9 | Exe
10 | Properties
11 | ApplicationLauncher
12 | ApplicationLauncher
13 | v3.5
14 | 512
15 |
16 |
17 | x86
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | x86
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | PreserveNewest
50 |
51 |
52 | PreserveNewest
53 |
54 |
55 | PreserveNewest
56 |
57 |
58 |
59 |
66 |
--------------------------------------------------------------------------------
/BitsUpdatePacker/Properties/Resources.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 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BitsUpdatePacker.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/BitsUpdater/BitsUpdater.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {722D747F-8C34-48B0-9301-F40A8B4CA2B8}
9 | Library
10 | Properties
11 | BitsUpdater
12 | BitsUpdater
13 | v3.5
14 | 512
15 |
16 |
17 |
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
79 |
--------------------------------------------------------------------------------
/BitsUpdatePacker/UIUpdatePackage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Collections.ObjectModel;
6 | using System.Windows;
7 | using System.IO;
8 | using BitsUpdatePacker.Configuration;
9 | using System.Configuration;
10 | using BitsUpdater;
11 |
12 | namespace BitsUpdatePacker
13 | {
14 | internal sealed class UIUpdatePackage : DependencyObject
15 | {
16 | public static readonly DependencyProperty TokenStringProperty = DependencyProperty.Register("TokenString", typeof(string), typeof(UIUpdatePackage));
17 | public string TokenString
18 | {
19 | get { return (string)GetValue(TokenStringProperty); }
20 | set { SetValue(TokenStringProperty, value); }
21 | }
22 |
23 | public string PackageUrlDirectory
24 | {
25 | get;
26 | set;
27 | }
28 |
29 | public Version NextVersion
30 | {
31 | get;
32 | set;
33 | }
34 |
35 | public string CertificatePath
36 | {
37 | get;
38 | set;
39 | }
40 |
41 | public bool IsDifferential
42 | {
43 | get;
44 | set;
45 | }
46 |
47 | public string OutputDirectory
48 | {
49 | get;
50 | set;
51 | }
52 |
53 | public ObservableCollection IncludedFiles
54 | {
55 | get;
56 | private set;
57 | }
58 |
59 | public ObservableCollection ExcludedFiles
60 | {
61 | get;
62 | private set;
63 | }
64 |
65 | public UIUpdatePackage()
66 | {
67 | IncludedFiles = new ObservableCollection();
68 | ExcludedFiles = new ObservableCollection();
69 | InitializeConfigValues();
70 | }
71 |
72 | public static IEnumerable ConvertFileTemplates(IEnumerable files)
73 | {
74 | var result = new List();
75 |
76 | if (files != null)
77 | {
78 | foreach (var item in files)
79 | {
80 | if (Directory.Exists(item.Directory))
81 | {
82 | result.Add(new FileSearchTemplate(new DirectoryInfo(item.Directory), item.Pattern, item.SearchOption));
83 | }
84 | }
85 | }
86 | return result;
87 | }
88 |
89 | private void InitializeConfigValues()
90 | {
91 | OutputDirectory = ConfigurationManager.AppSettings["OutputDirectory"];
92 | CertificatePath = ConfigurationManager.AppSettings["CertificatePath"];
93 | PackageUrlDirectory = ConfigurationManager.AppSettings["PackageDirectoryUrl"];
94 | AddTemplates(IncludedFiles, (TemplatesConfigSection)ConfigurationManager.GetSection("includedFiles"));
95 | AddTemplates(ExcludedFiles, (TemplatesConfigSection)ConfigurationManager.GetSection("excludedFiles"));
96 | }
97 |
98 | private void AddTemplates(ObservableCollection observableCollection, TemplatesConfigSection configSection)
99 | {
100 | foreach (TemplatesElement item in configSection.Templates)
101 | {
102 | observableCollection.Add(new UIFileSearchTemplate
103 | {
104 | Directory = item.Directory,
105 | Pattern = item.Pattern,
106 | SearchOption = item.SearchOption,
107 | });
108 | }
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/BitsUpdater.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BitsUpdater", "BitsUpdater\BitsUpdater.csproj", "{722D747F-8C34-48B0-9301-F40A8B4CA2B8}"
5 | EndProject
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BitsUpdatePacker", "BitsUpdatePacker\BitsUpdatePacker.csproj", "{36B8E1B6-7B54-4864-9383-9F6B426A3C8F}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BitsUpdater.Example", "BitsUpdater.Example\BitsUpdater.Example.csproj", "{63730B60-110F-447F-99EF-93784DA4E11A}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApplicationLauncher", "ApplicationLauncher\ApplicationLauncher.csproj", "{F04A7A97-B907-40BC-8DE2-00EA270AAC8C}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Debug|Mixed Platforms = Debug|Mixed Platforms
16 | Debug|x86 = Debug|x86
17 | Release|Any CPU = Release|Any CPU
18 | Release|Mixed Platforms = Release|Mixed Platforms
19 | Release|x86 = Release|x86
20 | EndGlobalSection
21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
22 | {722D747F-8C34-48B0-9301-F40A8B4CA2B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {722D747F-8C34-48B0-9301-F40A8B4CA2B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {722D747F-8C34-48B0-9301-F40A8B4CA2B8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
25 | {722D747F-8C34-48B0-9301-F40A8B4CA2B8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
26 | {722D747F-8C34-48B0-9301-F40A8B4CA2B8}.Debug|x86.ActiveCfg = Debug|Any CPU
27 | {722D747F-8C34-48B0-9301-F40A8B4CA2B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
28 | {722D747F-8C34-48B0-9301-F40A8B4CA2B8}.Release|Any CPU.Build.0 = Release|Any CPU
29 | {722D747F-8C34-48B0-9301-F40A8B4CA2B8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
30 | {722D747F-8C34-48B0-9301-F40A8B4CA2B8}.Release|Mixed Platforms.Build.0 = Release|Any CPU
31 | {722D747F-8C34-48B0-9301-F40A8B4CA2B8}.Release|x86.ActiveCfg = Release|Any CPU
32 | {36B8E1B6-7B54-4864-9383-9F6B426A3C8F}.Debug|Any CPU.ActiveCfg = Debug|x86
33 | {36B8E1B6-7B54-4864-9383-9F6B426A3C8F}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
34 | {36B8E1B6-7B54-4864-9383-9F6B426A3C8F}.Debug|Mixed Platforms.Build.0 = Debug|x86
35 | {36B8E1B6-7B54-4864-9383-9F6B426A3C8F}.Debug|x86.ActiveCfg = Debug|x86
36 | {36B8E1B6-7B54-4864-9383-9F6B426A3C8F}.Debug|x86.Build.0 = Debug|x86
37 | {36B8E1B6-7B54-4864-9383-9F6B426A3C8F}.Release|Any CPU.ActiveCfg = Release|x86
38 | {36B8E1B6-7B54-4864-9383-9F6B426A3C8F}.Release|Mixed Platforms.ActiveCfg = Release|x86
39 | {36B8E1B6-7B54-4864-9383-9F6B426A3C8F}.Release|Mixed Platforms.Build.0 = Release|x86
40 | {36B8E1B6-7B54-4864-9383-9F6B426A3C8F}.Release|x86.ActiveCfg = Release|x86
41 | {36B8E1B6-7B54-4864-9383-9F6B426A3C8F}.Release|x86.Build.0 = Release|x86
42 | {63730B60-110F-447F-99EF-93784DA4E11A}.Debug|Any CPU.ActiveCfg = Debug|x86
43 | {63730B60-110F-447F-99EF-93784DA4E11A}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
44 | {63730B60-110F-447F-99EF-93784DA4E11A}.Debug|Mixed Platforms.Build.0 = Debug|x86
45 | {63730B60-110F-447F-99EF-93784DA4E11A}.Debug|x86.ActiveCfg = Debug|x86
46 | {63730B60-110F-447F-99EF-93784DA4E11A}.Debug|x86.Build.0 = Debug|x86
47 | {63730B60-110F-447F-99EF-93784DA4E11A}.Release|Any CPU.ActiveCfg = Release|x86
48 | {63730B60-110F-447F-99EF-93784DA4E11A}.Release|Mixed Platforms.ActiveCfg = Release|x86
49 | {63730B60-110F-447F-99EF-93784DA4E11A}.Release|Mixed Platforms.Build.0 = Release|x86
50 | {63730B60-110F-447F-99EF-93784DA4E11A}.Release|x86.ActiveCfg = Release|x86
51 | {63730B60-110F-447F-99EF-93784DA4E11A}.Release|x86.Build.0 = Release|x86
52 | {F04A7A97-B907-40BC-8DE2-00EA270AAC8C}.Debug|Any CPU.ActiveCfg = Debug|x86
53 | {F04A7A97-B907-40BC-8DE2-00EA270AAC8C}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
54 | {F04A7A97-B907-40BC-8DE2-00EA270AAC8C}.Debug|Mixed Platforms.Build.0 = Debug|x86
55 | {F04A7A97-B907-40BC-8DE2-00EA270AAC8C}.Debug|x86.ActiveCfg = Debug|x86
56 | {F04A7A97-B907-40BC-8DE2-00EA270AAC8C}.Debug|x86.Build.0 = Debug|x86
57 | {F04A7A97-B907-40BC-8DE2-00EA270AAC8C}.Release|Any CPU.ActiveCfg = Release|x86
58 | {F04A7A97-B907-40BC-8DE2-00EA270AAC8C}.Release|Mixed Platforms.ActiveCfg = Release|x86
59 | {F04A7A97-B907-40BC-8DE2-00EA270AAC8C}.Release|Mixed Platforms.Build.0 = Release|x86
60 | {F04A7A97-B907-40BC-8DE2-00EA270AAC8C}.Release|x86.ActiveCfg = Release|x86
61 | {F04A7A97-B907-40BC-8DE2-00EA270AAC8C}.Release|x86.Build.0 = Release|x86
62 | EndGlobalSection
63 | GlobalSection(SolutionProperties) = preSolution
64 | HideSolutionNode = FALSE
65 | EndGlobalSection
66 | EndGlobal
67 |
--------------------------------------------------------------------------------
/BitsUpdatePacker/MainWindow.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 | using BitsUpdater;
15 | using System.Collections.ObjectModel;
16 | using System.IO;
17 | using System.Configuration;
18 | using BitsUpdatePacker.Configuration;
19 | using System.Xml.Serialization;
20 |
21 | namespace BitsUpdatePacker
22 | {
23 | public partial class MainWindow : Window
24 | {
25 | private UIUpdatePackage _package = new UIUpdatePackage();
26 | private static readonly XmlSerializer _manifestSerializer = new XmlSerializer(typeof(XmlUpdateManifest));
27 |
28 | public MainWindow()
29 | {
30 | InitializeComponent();
31 | this.DataContext = _package;
32 | }
33 |
34 | private void RemoveTemplateExecuted(object sender, ExecutedRoutedEventArgs e)
35 | {
36 | var template = e.Parameter as UIFileSearchTemplate;
37 | if (template != null)
38 | {
39 | ((ObservableCollection)((ItemsControl)e.Source).ItemsSource).Remove(template);
40 | }
41 | }
42 |
43 | private void AddNewTemplateExecuted(object sender, ExecutedRoutedEventArgs e)
44 | {
45 | if (e.Parameter.ToString() == "Include")
46 | {
47 | _package.IncludedFiles.Add(new UIFileSearchTemplate());
48 | }
49 | else if (e.Parameter.ToString() == "Exclude")
50 | {
51 | _package.ExcludedFiles.Add(new UIFileSearchTemplate());
52 | }
53 | }
54 |
55 | private void CreatePackageExecuted(object sender, ExecutedRoutedEventArgs e)
56 | {
57 | if (IsValid((Grid)sender))
58 | {
59 | var package = new UpdatePackage(_package.CertificatePath, _package.NextVersion, _package.IsDifferential);
60 | foreach (var item in UIUpdatePackage.ConvertFileTemplates(_package.IncludedFiles))
61 | {
62 | package.IncludedFiles.Add(item);
63 | }
64 | foreach (var item in UIUpdatePackage.ConvertFileTemplates(_package.ExcludedFiles))
65 | {
66 | package.ExcludedFiles.Add(item);
67 | }
68 | _package.TokenString = package.Create(new DirectoryInfo(_package.OutputDirectory));
69 | CreateManifest();
70 | MessageBox.Show(this
71 | , "Update package was successfully completed."
72 | , "Package Completed!"
73 | , MessageBoxButton.OK
74 | , MessageBoxImage.Asterisk);
75 | }
76 | }
77 |
78 | private void CreateManifest()
79 | {
80 | XmlUpdateManifest manifest = new XmlUpdateManifest
81 | {
82 | Url = ((_package.PackageUrlDirectory.EndsWith("/")) ? _package.PackageUrlDirectory : _package.PackageUrlDirectory + "/") + string.Format(UpdatePackage.AssemblyName, _package.NextVersion) + UpdatePackage.AssemblySuffix + UpdatePackage.PackageSuffix,
83 | Version = _package.NextVersion.ToString(),
84 | };
85 |
86 | using (var manifestFile = new FileStream(System.IO.Path.Combine(_package.OutputDirectory, "UpdateManifest.xml"), FileMode.Create))
87 | {
88 | _manifestSerializer.Serialize(manifestFile, manifest);
89 | }
90 | }
91 |
92 | private bool IsValid(Grid grid)
93 | {
94 | BindingExpression version = txtVersion.GetBindingExpression(TextBox.TextProperty);
95 | version.UpdateSource();
96 |
97 | BindingExpression certificatePath = sfcCertificate.GetBindingExpression(SelectFileControl.FilePathProperty);
98 | certificatePath.UpdateSource();
99 |
100 | BindingExpression outputPath = sfcOutput.GetBindingExpression(SelectFolderControl.FolderPathProperty);
101 | outputPath.UpdateSource();
102 |
103 | BindingExpression url = txtUrl.GetBindingExpression(TextBox.TextProperty);
104 | url.UpdateSource();
105 | return !version.HasError && !certificatePath.HasError && !outputPath.HasError && !url.HasError;
106 | }
107 |
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/BitsUpdatePacker/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/BitsUpdatePacker/BitsUpdatePacker.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | x86
6 | 8.0.30703
7 | 2.0
8 | {36B8E1B6-7B54-4864-9383-9F6B426A3C8F}
9 | WinExe
10 | Properties
11 | BitsUpdatePacker
12 | BitsUpdatePacker
13 | v3.5
14 | Client
15 | 512
16 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
17 | 4
18 | false
19 | c:\
20 | true
21 | Disk
22 | false
23 | Foreground
24 | 7
25 | Days
26 | false
27 | false
28 | true
29 | 0
30 | 1.0.0.%2a
31 | false
32 | true
33 | true
34 |
35 |
36 | x86
37 | true
38 | full
39 | false
40 | bin\Debug\
41 | DEBUG;TRACE
42 | prompt
43 | 4
44 |
45 |
46 | x86
47 | pdbonly
48 | true
49 | bin\Release\
50 | TRACE
51 | prompt
52 | 4
53 |
54 |
55 |
56 |
57 |
58 |
59 | 5B6EA9E959A00757818C82A9E979D06C27929949
60 |
61 |
62 | BitsUpdatePacker_TemporaryKey.pfx
63 |
64 |
65 | false
66 |
67 |
68 | false
69 |
70 |
71 | LocalIntranet
72 |
73 |
74 | Properties\app.manifest
75 |
76 |
77 | false
78 |
79 |
80 | BitsUpdatePacker.snk.pfx
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 | 4.0
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 | MSBuild:Compile
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 | SelectFileControl.xaml
116 |
117 |
118 | SelectFolderControl.xaml
119 |
120 |
121 |
122 |
123 | MSBuild:Compile
124 | Designer
125 |
126 |
127 | App.xaml
128 | Code
129 |
130 |
131 |
132 | MainWindow.xaml
133 | Code
134 |
135 |
136 | Designer
137 | MSBuild:Compile
138 |
139 |
140 | Designer
141 | MSBuild:Compile
142 |
143 |
144 |
145 |
146 | Code
147 |
148 |
149 | True
150 | True
151 | Resources.resx
152 |
153 |
154 | True
155 | Settings.settings
156 | True
157 |
158 |
159 | ResXFileCodeGenerator
160 | Resources.Designer.cs
161 |
162 |
163 | Designer
164 |
165 |
166 |
167 |
168 | SettingsSingleFileGenerator
169 | Settings.Designer.cs
170 |
171 |
172 |
173 |
174 |
175 | {722D747F-8C34-48B0-9301-F40A8B4CA2B8}
176 | BitsUpdater
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 | False
192 | Microsoft .NET Framework 4 Client Profile %28x86 and x64%29
193 | true
194 |
195 |
196 | False
197 | .NET Framework 3.5 SP1 Client Profile
198 | false
199 |
200 |
201 | False
202 | .NET Framework 3.5 SP1
203 | false
204 |
205 |
206 | False
207 | Windows Installer 3.1
208 | true
209 |
210 |
211 |
212 |
219 |
--------------------------------------------------------------------------------
/BitsUpdater/BitsUpdater.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using BitsUpdater.Behavior;
6 | using SharpBits.Base;
7 | using System.Net;
8 | using System.Xml.Serialization;
9 | using System.Reflection;
10 | using BitsUpdater.Extensions;
11 | using System.IO;
12 |
13 | namespace BitsUpdater
14 | {
15 | ///
16 | /// Main class used for update download, checking for new updates and their applying.
17 | ///
18 | public sealed class BitsUpdater : IDisposable
19 | {
20 | private static readonly XmlSerializer _manifestSerializer = new XmlSerializer(typeof(XmlUpdateManifest));
21 |
22 | private const String JobDescription = "BitsUpdater application update download";
23 |
24 | private readonly UpdateStatus _status = UpdateStatus.Load();
25 | private readonly BitsManager _manager = new BitsManager();
26 | private readonly WebClient _webClient = new WebClient();
27 | private readonly String _manifestUrl;
28 | private readonly String _updateDirectory;
29 |
30 |
31 | private XmlUpdateManifest _manifest;
32 |
33 | ///
34 | /// Notifies when update check is done. It is raised by CheckUpdatesAsync method.
35 | ///
36 | public event EventHandler UpdateChecked;
37 | ///
38 | /// Event is fired when new updates are downloaded.
39 | ///
40 | public event EventHandler UpdateDownloaded;
41 | ///
42 | /// Event is fired when error occurs during download.
43 | ///
44 | public event EventHandler UpdateDownloadError;
45 | ///
46 | /// Event is raised if the progress of Bits download changed. Can be used to display current update progress.
47 | ///
48 | public event EventHandler UpdateDownloadProgressChanged;
49 |
50 | ///
51 | /// Initializes new instance of BitsUpdater.
52 | ///
53 | /// Location of UpdateManifest.xml on the internet.
54 | /// Location of update store directory. For example if directory Version is passed, actual download of version 1.0.0.1 will be located in Version\1.0.0.1 directory.
55 | public BitsUpdater(string manifestUrl, string updateDirectory)
56 | {
57 | _manifestUrl = manifestUrl;
58 | _updateDirectory = updateDirectory.EndsWith("\\") ? updateDirectory + "{0}" : updateDirectory + "\\{0}";
59 | ResumePreviousDownload();
60 | }
61 |
62 | ///
63 | /// Checks for new updates.
64 | ///
65 | /// Thrown when manifestUrl is null.
66 | /// Thrown when manifestUrl is not valid url or client can't connect to specified url.
67 | /// True if new updates are available. False if there are no new updates or downloaded UpdateManifest couldn't be deserialized.
68 | public bool CheckUpdate()
69 | {
70 | _manifest = _manifestSerializer.Deserialize(_webClient.OpenRead(_manifestUrl)) as XmlUpdateManifest;
71 | return UpdatesAvailable();
72 | }
73 |
74 | ///
75 | /// Checks for new updates asynchronously. After update check is finished, event UpdateChecked is raised.
76 | ///
77 | /// Thrown when manifestUrl is null.
78 | /// Thrown when manifestUrl is not valid url or client can't connect to specified url.
79 | public void CheckUpdateAsync()
80 | {
81 | _webClient.OpenReadCompleted += (sender, args) =>
82 | {
83 | _manifest = _manifestSerializer.Deserialize(args.Result) as XmlUpdateManifest;
84 | OnUpdateChecked(new UpdateCheckedEventArgs(UpdatesAvailable()));
85 | };
86 | _webClient.OpenReadAsync(new Uri(_manifestUrl));
87 | }
88 |
89 | ///
90 | /// Starts downloading updates using BITS. If new updates are downloaded event UpdateDownloaded is raised. If hadn't checked for updates, it uses synchronous method CheckUpdates.
91 | ///
92 | public void Download()
93 | {
94 | if ((_manifest == null) ? CheckUpdate() : UpdatesAvailable())
95 | {
96 | _status.NextVersion = new Version(_manifest.Version);
97 | _status.Save();
98 | StartDownload();
99 | }
100 | }
101 |
102 | ///
103 | /// Apply downloaded updates. This method will unpack update to specified directory.
104 | ///
105 | /// Public token is used to unpack files in UpdatePackage. Public token can be obtained while using BitsUpdatePacker app and creating package.
106 | /// True if everything went well.
107 | public bool Update(string publicToken)
108 | {
109 | return Update(null, publicToken);
110 | }
111 |
112 | ///
113 | /// Apply downloaded updates. Method will execute behavior method after files are unpacked.
114 | ///
115 | /// Defines behavior of update method after files are unpacked. For example you can backup your database etc.
116 | /// Public token is used to unpack files in UpdatePackage. Public token can be obtained while using BitsUpdatePacker app and creating package.
117 | /// True if everything went well.
118 | public bool Update(IUpdateBehavior behavior, string publicToken)
119 | {
120 | if (_status.NextVersion > Assembly.GetEntryAssembly().GetName().Version && File.Exists(GetUpdateSaveLocation()))
121 | {
122 | UpdatePackage.Extract(new DirectoryInfo(string.Format(_updateDirectory, _status.NextVersion)), _status.NextVersion, publicToken);
123 |
124 | if (behavior != null)
125 | {
126 | behavior.Execute();
127 | }
128 |
129 | return true;
130 | }
131 |
132 | return false;
133 | }
134 |
135 | ///
136 | /// Resumes active BITS download if there is any. This method should be called with initializing new BitsUpdater.
137 | ///
138 | public void ResumePreviousDownload()
139 | {
140 | if (_status.BitsJobId != Guid.Empty)
141 | {
142 | if (!IsUpdateDownloaded())
143 | {
144 | if (_manager.EnumJobs().ContainsKey(_status.BitsJobId))
145 | {
146 | var job = _manager.Jobs[_status.BitsJobId];
147 | RegisterEvents(job);
148 | job.Resume();
149 | }
150 | else
151 | {
152 | _status.NextVersion = new Version();
153 | _status.BitsJobId = Guid.Empty;
154 | _status.Save();
155 | }
156 | }
157 | }
158 | }
159 |
160 | public void Dispose()
161 | {
162 | _manager.Dispose();
163 | }
164 |
165 | private String GetUpdateSaveLocation()
166 | {
167 | return Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().GetDirectory()), String.Format("{0}{1}{2}", string.Format(UpdatePackage.AssemblyName, _status.NextVersion), UpdatePackage.AssemblySuffix, UpdatePackage.PackageSuffix));
168 | }
169 |
170 | private void StartDownload()
171 | {
172 | if (!IsUpdateDownloaded())
173 | {
174 | var job = _manager.CreateJob(JobDescription, JobType.Download);
175 | job.AddFile(_manifest.Url, GetUpdateSaveLocation());
176 | RegisterEvents(job);
177 | _status.BitsJobId = job.JobId;
178 | _status.Save();
179 | job.Resume();
180 | }
181 | }
182 |
183 | private bool IsUpdateDownloaded()
184 | {
185 | if (File.Exists(GetUpdateSaveLocation()))
186 | {
187 | OnUpdateDownloaded(new UpdateDownloadedEventArgs());
188 | return true;
189 | }
190 | return false;
191 | }
192 |
193 | private void RegisterEvents(BitsJob job)
194 | {
195 | job.OnJobError += (s, e) =>
196 | {
197 | _status.NextVersion = new Version();
198 | _status.BitsJobId = Guid.Empty;
199 | _status.Save();
200 | OnUpdateDownloadError(new UpdateErrorEventArgs(e.Error));
201 | job.Cancel();
202 | job.Dispose();
203 | };
204 |
205 | job.OnJobTransferred += (s, e) =>
206 | {
207 | job.Complete();
208 | job.Dispose();
209 | OnUpdateDownloaded(new UpdateDownloadedEventArgs());
210 | };
211 |
212 | job.OnJobModified += (s, e) =>
213 | {
214 | if (job != null && job.State == JobState.Transferring)
215 | {
216 | if (job.Progress != null)
217 | {
218 | OnUpdateDownloadProgressChanged(new UpdateProgressEventArgs(job.Progress.BytesTransferred, job.Progress.BytesTotal));
219 | }
220 | }
221 | };
222 | }
223 |
224 | private bool UpdatesAvailable()
225 | {
226 | if (_manifest != null)
227 | {
228 | var currentVersion = Assembly.GetEntryAssembly().GetName().Version;
229 | var manifestVersion = new Version(_manifest.Version);
230 | return (manifestVersion > currentVersion && _status.NextVersion < manifestVersion);
231 | }
232 |
233 | return false;
234 | }
235 |
236 | private void OnUpdateChecked(UpdateCheckedEventArgs e)
237 | {
238 | if (UpdateChecked != null)
239 | {
240 | UpdateChecked(this, e);
241 | }
242 | }
243 |
244 | private void OnUpdateDownloaded(UpdateDownloadedEventArgs e)
245 | {
246 | if (UpdateDownloaded != null)
247 | {
248 | UpdateDownloaded(this, e);
249 | }
250 | }
251 |
252 | private void OnUpdateDownloadError(UpdateErrorEventArgs e)
253 | {
254 | if (UpdateDownloadError != null)
255 | {
256 | UpdateDownloadError(this, e);
257 | }
258 | }
259 |
260 | private void OnUpdateDownloadProgressChanged(UpdateProgressEventArgs e)
261 | {
262 | if (UpdateDownloadProgressChanged != null)
263 | {
264 | UpdateDownloadProgressChanged(this, e);
265 | }
266 | }
267 | }
268 | }
269 |
--------------------------------------------------------------------------------
/BitsUpdatePacker/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
13 |
15 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
46 |
48 |
51 |
52 |
53 |
57 |
58 |
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 |
161 |
167 |
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 |
--------------------------------------------------------------------------------