Merge pull request #122 from erri120/ceras

Ceras serialization
This commit is contained in:
Timothy Baldridge 2019-10-27 13:10:00 -06:00 committed by GitHub
commit 4c688bf593
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 172 additions and 40 deletions

View File

@ -4,4 +4,13 @@
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -6,6 +6,7 @@ using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading;
using Ceras;
using Compression.BSA;
using ICSharpCode.SharpZipLib.Zip;
using Newtonsoft.Json;
@ -505,7 +506,7 @@ namespace VFS
}
}
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
[MemberConfig(TargetMember.None)]
public class VirtualFile
{
private string _fullPath;
@ -517,7 +518,7 @@ namespace VFS
internal string _stagedPath;
[JsonProperty]
[Include]
public string[] Paths
{
get => _paths;
@ -529,13 +530,13 @@ namespace VFS
}
}
[JsonProperty] public string Hash { get; set; }
[Include] public string Hash { get; set; }
[JsonProperty] public long Size { get; set; }
[Include] public long Size { get; set; }
[JsonProperty] public ulong LastModified { get; set; }
[Include] public ulong LastModified { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
[Include]
public bool? FinishedIndexing { get; set; }

View File

@ -53,6 +53,9 @@
<Reference Include="AlphaFS, Version=2.2.0.0, Culture=neutral, PublicKeyToken=4d31a58f7d7ad5c9, processorArchitecture=MSIL">
<HintPath>..\packages\AlphaFS.2.2.6\lib\net452\AlphaFS.dll</HintPath>
</Reference>
<Reference Include="Ceras, Version=4.1.7.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Ceras.4.1.7\lib\net47\Ceras.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=1.2.0.246, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\packages\SharpZipLib.1.2.0\lib\net45\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
@ -60,11 +63,17 @@
<HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Collections.Immutable, Version=1.2.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll</HintPath>
</Reference>
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Transactions" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
@ -88,6 +97,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AlphaFS" version="2.2.6" targetFramework="net472" />
<package id="Ceras" version="4.1.7" targetFramework="net472" />
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net472" />
<package id="SharpZipLib" version="1.2.0" targetFramework="net472" />
<package id="System.Buffers" version="4.5.0" targetFramework="net472" />
<package id="System.Collections.Immutable" version="1.5.0" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net472" />
</packages>

View File

@ -10,6 +10,7 @@ using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Ceras;
using ICSharpCode.SharpZipLib.BZip2;
using IniParser;
using Newtonsoft.Json;
@ -192,13 +193,40 @@ namespace Wabbajack.Common
return new DynamicIniData(new FileIniDataParser().ReadData(new StreamReader(new MemoryStream(Encoding.UTF8.GetBytes(file)))));
}
public static void ToCERAS<T>(this T obj, string filename, ref SerializerConfig config)
{
var ceras = new CerasSerializer(config);
byte[] buffer = null;
ceras.Serialize(obj, ref buffer);
using(var m1 = new MemoryStream(buffer))
using (var m2 = new MemoryStream())
{
BZip2.Compress(m1, m2, false, 9);
m2.Seek(0, SeekOrigin.Begin);
File.WriteAllBytes(filename, m2.ToArray());
}
}
public static T FromCERAS<T>(this Stream data, ref SerializerConfig config)
{
var ceras = new CerasSerializer(config);
byte[] bytes = data.ReadAll();
using (var m1 = new MemoryStream(bytes))
using (var m2 = new MemoryStream())
{
BZip2.Decompress(m1, m2, false);
m2.Seek(0, SeekOrigin.Begin);
return ceras.Deserialize<T>(m2.ToArray());
}
}
public static void ToJSON<T>(this T obj, string filename)
{
File.WriteAllText(filename,
JsonConvert.SerializeObject(obj, Formatting.Indented,
new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.Auto}));
}
/*
public static void ToBSON<T>(this T obj, string filename)
{
using (var fo = File.OpenWrite(filename))
@ -209,7 +237,7 @@ namespace Wabbajack.Common
{TypeNameHandling = TypeNameHandling.Auto});
serializer.Serialize(br, obj);
}
}
}*/
public static ulong ToMilliseconds(this DateTime date)
{
@ -227,7 +255,7 @@ namespace Wabbajack.Common
return JsonConvert.DeserializeObject<T>(File.ReadAllText(filename),
new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.Auto});
}
/*
public static T FromBSON<T>(this string filename, bool root_is_array = false)
{
using (var fo = File.OpenRead(filename))
@ -237,7 +265,7 @@ namespace Wabbajack.Common
{TypeNameHandling = TypeNameHandling.Auto});
return serializer.Deserialize<T>(br);
}
}
}*/
public static T FromJSONString<T>(this string data)
{

View File

@ -53,6 +53,9 @@
<Reference Include="AlphaFS, Version=2.2.0.0, Culture=neutral, PublicKeyToken=4d31a58f7d7ad5c9, processorArchitecture=MSIL">
<HintPath>..\packages\AlphaFS.2.2.6\lib\net452\AlphaFS.dll</HintPath>
</Reference>
<Reference Include="Ceras, Version=4.1.7.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Ceras.4.1.7\lib\net47\Ceras.dll</HintPath>
</Reference>
<Reference Include="erri120.OMODFramework, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\erri120.OMODFramework.1.0.0\lib\net472\erri120.OMODFramework.dll</HintPath>
</Reference>
@ -78,10 +81,16 @@
<HintPath>..\packages\SevenZip.19.0.0\lib\net20\SevenZip.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Numerics" />
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Transactions" />
@ -109,6 +118,7 @@
<ItemGroup>
<EmbeddedResource Include="7z.dll.gz" />
<EmbeddedResource Include="7z.exe.gz" />
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AlphaFS" version="2.2.6" targetFramework="net472" />
<package id="Ceras" version="4.1.7" targetFramework="net472" />
<package id="erri120.OMODFramework" version="1.0.0" targetFramework="net472" />
<package id="ini-parser" version="2.5.2" targetFramework="net472" />
<package id="murmurhash" version="1.0.3" targetFramework="net472" />
@ -9,6 +10,8 @@
<package id="protobuf-net" version="2.4.0" targetFramework="net472" />
<package id="SevenZip" version="19.0.0" targetFramework="net472" />
<package id="SharpZipLib" version="1.2.0" targetFramework="net472" />
<package id="System.Buffers" version="4.5.0" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net472" />
<package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net472" />
<package id="YamlDotNet" version="7.0.0" targetFramework="net472" />
</packages>

View File

@ -0,0 +1,27 @@
using Ceras;
using Compression.BSA;
using VFS;
using Wabbajack.Common;
using Wabbajack.Lib.Downloaders;
namespace Wabbajack.Lib
{
public class CerasConfig
{
public static SerializerConfig Config = new SerializerConfig()
{
KnownTypes =
{
typeof(ModList), typeof(Game), typeof(Directive), typeof(IgnoredDirectly),
typeof(NoMatch), typeof(InlineFile), typeof(PropertyType), typeof(CleanedESM),
typeof(RemappedInlineFile), typeof(FromArchive), typeof(CreateBSA), typeof(PatchedFromArchive),
typeof(SourcePatch), typeof(MergedPatch), typeof(Archive), typeof(IndexedArchive), typeof(IndexedEntry),
typeof(IndexedArchiveEntry), typeof(BSAIndexedEntry), typeof(VirtualFile),
typeof(ArchiveStateObject), typeof(FileStateObject), typeof(IDownloader),
typeof(IUrlDownloader), typeof(AbstractDownloadState), typeof(ManualDownloader.State),
typeof(DropboxDownloader), typeof(GoogleDriveDownloader.State), typeof(HTTPDownloader.State),
typeof(MegaDownloader.State), typeof(ModDBDownloader.State), typeof(NexusDownloader.State)
}
};
}
}

View File

@ -304,7 +304,8 @@ namespace Wabbajack.Lib
{
Utils.Log($"Exporting Modlist to : {ModListOutputFile}");
ModList.ToJSON(Path.Combine(ModListOutputFolder, "modlist.json"));
//ModList.ToJSON(Path.Combine(ModListOutputFolder, "modlist.json"));
ModList.ToCERAS(Path.Combine(ModListOutputFolder, "modlist"), ref CerasConfig.Config);
if (File.Exists(ModListOutputFile))
File.Delete(ModListOutputFile);

View File

@ -1,7 +1,6 @@
using Newtonsoft.Json;
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Ceras;
using Compression.BSA;
using VFS;
using Wabbajack.Common;
@ -34,7 +33,6 @@ namespace Wabbajack.Lib
}
}
[Serializable]
public class ModList
{
/// <summary>
@ -93,7 +91,6 @@ namespace Wabbajack.Lib
public string ReportHTML;
}
[Serializable]
public class Directive
{
/// <summary>
@ -104,18 +101,15 @@ namespace Wabbajack.Lib
public string Hash;
}
[Serializable]
public class IgnoredDirectly : Directive
{
public string Reason;
}
[Serializable]
public class NoMatch : IgnoredDirectly
{
}
[Serializable]
public class InlineFile : Directive
{
/// <summary>
@ -129,13 +123,11 @@ namespace Wabbajack.Lib
/// <summary>
/// File meant to be extracted before the installation
/// </summary>
[Serializable]
public class PropertyFile : InlineFile
{
public PropertyType Type;
}
[Serializable]
public class CleanedESM : InlineFile
{
public string SourceESMHash;
@ -144,12 +136,11 @@ namespace Wabbajack.Lib
/// <summary>
/// A file that has the game and MO2 folders remapped on installation
/// </summary>
[Serializable]
public class RemappedInlineFile : InlineFile
{
}
[Serializable]
[MemberConfig(TargetMember.All)]
public class FromArchive : Directive
{
private string _fullPath;
@ -159,9 +150,10 @@ namespace Wabbajack.Lib
/// </summary>
public string[] ArchiveHashPath;
[JsonIgnore] [NonSerialized] public VirtualFile FromFile;
[Exclude]
public VirtualFile FromFile;
[JsonIgnore]
[Exclude]
public string FullPath
{
get
@ -172,7 +164,6 @@ namespace Wabbajack.Lib
}
}
[Serializable]
public class CreateBSA : Directive
{
public string TempID;
@ -181,7 +172,6 @@ namespace Wabbajack.Lib
public List<FileStateObject> FileStates { get; set; }
}
[Serializable]
public class PatchedFromArchive : FromArchive
{
/// <summary>
@ -190,21 +180,18 @@ namespace Wabbajack.Lib
public string PatchID;
}
[Serializable]
public class SourcePatch
{
public string RelativePath;
public string Hash;
}
[Serializable]
public class MergedPatch : Directive
{
public List<SourcePatch> Sources;
public string PatchID;
}
[Serializable]
public class Archive
{
/// <summary>
@ -225,7 +212,6 @@ namespace Wabbajack.Lib
public AbstractDownloadState State { get; set; }
}
[Serializable]
public class IndexedArchive
{
public dynamic IniData;
@ -237,7 +223,6 @@ namespace Wabbajack.Lib
/// <summary>
/// A archive entry
/// </summary>
[Serializable]
public class IndexedEntry
{
/// <summary>
@ -256,7 +241,6 @@ namespace Wabbajack.Lib
public long Size;
}
[Serializable]
public class IndexedArchiveEntry : IndexedEntry
{
public string[] HashPath;
@ -265,7 +249,6 @@ namespace Wabbajack.Lib
/// <summary>
/// Data found inside a BSA file in an archive
/// </summary>
[Serializable]
public class BSAIndexedEntry : IndexedEntry
{
/// <summary>

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using Newtonsoft.Json;
using Ceras;
using Wabbajack.Common;
using Wabbajack.Lib.Validation;
using File = Alphaleonis.Win32.Filesystem.File;
@ -48,14 +48,14 @@ namespace Wabbajack.Lib.Downloaders
{
}
[MemberConfig(TargetMember.All)]
public class State : AbstractDownloadState
{
public string Url { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public List<string> Headers { get; set; }
[JsonIgnore]
[Exclude]
public HttpClient Client { get; set; }
public override bool IsWhitelisted(ServerWhitelist whitelist)

View File

@ -84,9 +84,15 @@ namespace Wabbajack.Lib
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var ar = new ZipArchive(fs, ZipArchiveMode.Read))
{
var entry = ar.GetEntry("modlist.json");
var entry = ar.GetEntry("modlist");
if (entry == null)
{
entry = ar.GetEntry("modlist.json");
using (var e = entry.Open())
return e.FromJSON<ModList>();
}
using (var e = entry.Open())
return e.FromJSON<ModList>();
return e.FromCERAS<ModList>(ref CerasConfig.Config);
}
}

View File

@ -34,6 +34,9 @@
<Reference Include="AlphaFS, Version=2.2.0.0, Culture=neutral, PublicKeyToken=4d31a58f7d7ad5c9, processorArchitecture=MSIL">
<HintPath>..\packages\AlphaFS.2.2.6\lib\net452\AlphaFS.dll</HintPath>
</Reference>
<Reference Include="Ceras, Version=4.1.7.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Ceras.4.1.7\lib\net47\Ceras.dll</HintPath>
</Reference>
<Reference Include="CommonMark, Version=0.1.0.0, Culture=neutral, PublicKeyToken=001ef8810438905d, processorArchitecture=MSIL">
<HintPath>..\packages\CommonMark.NET.0.15.1\lib\net45\CommonMark.dll</HintPath>
</Reference>
@ -70,6 +73,9 @@
<HintPath>..\packages\Splat.Drawing.9.1.1\lib\net461\Splat.Drawing.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Core" />
<Reference Include="System.Design" />
<Reference Include="System.Drawing" />
@ -112,6 +118,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="CerasConfig.cs" />
<Compile Include="Compiler.cs" />
<Compile Include="Data.cs" />
<Compile Include="Downloaders\AbstractDownloadState.cs" />

View File

@ -6,6 +6,10 @@
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AlphaFS" version="2.2.6" targetFramework="net472" />
<package id="Ceras" version="4.1.7" targetFramework="net472" />
<package id="CommonMark.NET" version="0.15.1" targetFramework="net472" />
<package id="DynamicData" version="6.13.18" targetFramework="net472" />
<package id="MegaApiClient" version="1.7.1" targetFramework="net472" />
@ -12,6 +13,7 @@
<package id="SharpCompress" version="0.23.0" targetFramework="net472" />
<package id="Splat" version="9.1.1" targetFramework="net472" />
<package id="Splat.Drawing" version="9.1.1" targetFramework="net472" />
<package id="System.Buffers" version="4.5.0" targetFramework="net472" />
<package id="System.Drawing.Primitives" version="4.3.0" targetFramework="net472" />
<package id="System.Reactive" version="4.2.0" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net472" />

View File

@ -10,6 +10,10 @@
<assemblyIdentity name="System.Reactive" publicKeyToken="94bc3704cddfc263" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -9,6 +9,10 @@
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -6,6 +6,10 @@
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.4.0" newVersion="4.0.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -14,6 +14,10 @@
<assemblyIdentity name="System.Reactive" publicKeyToken="94bc3704cddfc263" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>