diff --git a/CHANGELOG.md b/CHANGELOG.md index 4154644..a4d84d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 2.0.1 +- Version 2 RTM, for integration to ASPNET Core 2.1 IHttpClientFactory + +## 2.0.0-v2alpha +- Publish as strong-named package only (discontinue non-strong-named versions) +- Add .NetStandard 2.0 target + ## 1.0.3 - RTM version diff --git a/GitVersionConfig.yaml b/GitVersionConfig.yaml index cd6a99d..58c9946 100644 --- a/GitVersionConfig.yaml +++ b/GitVersionConfig.yaml @@ -1 +1 @@ -next-version: 1.0.3 \ No newline at end of file +next-version: 2.0.1 \ No newline at end of file diff --git a/README.md b/README.md index af0a447..cce5669 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Polly.Extensions.Http is an extensions package containing opinionated convenience methods for configuring [Polly](https://github.com/App-vNext/Polly) policies to handle transient faults typical of calls through HttpClient. -Polly.Extensions.Http targets .NET Standard 1.1. +Polly.Extensions.Http targets .NET Standard 1.1 and .NET Standard 2.0. [Polly](https://github.com/App-vNext/Polly) is a .NET resilience and transient-fault-handling library that allows developers to express policies such as Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback in a fluent and thread-safe manner. @@ -17,11 +17,7 @@ Polly is a member of the [.NET Foundation](https://www.dotnetfoundation.org/abou Install-Package Polly.Extensions.Http -You can install the Strongly Named version via: - - Install-Package Polly.Extensions.Http-Signed - -The strongly-named version works with the strongly-named Polly-Signed nuget package. +This package contains a strongly-named DLL. # Convenience methods for transient faults of HttpClient calls @@ -72,9 +68,9 @@ var policy = Policy .RetryAsync(3); ``` -# Using Polly.Extensions.Http with HttpClientFactory +# Using Polly.Extensions.Http with IHttpClientFactory -Polly.Extensions.Http is ideal for creating custom Polly policies for use with HttpClientFactory ([preview1 blog post](https://blogs.msdn.microsoft.com/webdev/2018/02/28/asp-net-core-2-1-preview1-introducing-httpclient-factory/); [preview2 blog post](https://blogs.msdn.microsoft.com/webdev/2018/04/12/asp-net-core-2-1-0-preview2-now-available/)), available from ASP.NET Core 2.1. +Polly.Extensions.Http is ideal for creating custom Polly policies for use with IHttpClientFactory, available from ASP.NET Core 2.1. ```csharp var retryPolicy = HttpPolicyExtensions @@ -89,11 +85,14 @@ serviceCollection.AddHttpClient("example.com", c => c.BaseAddress = new Uri("htt .AddPolicyHandler(timeoutPolicy); ``` -#### TODO: link to public HttpClientFactory documentation and/or expand example, when that documentation is published. +## Official documentation -# For more information on Polly ++ [Microsoft documentation on IHttpClientFactory](https://docs.microsoft.com/en-gb/aspnet/core/fundamentals/http-requests?view=aspnetcore-2.1) ++ [Microsoft documentation on using Polly policies with IHttpClientFactory](https://docs.microsoft.com/en-gb/aspnet/core/fundamentals/http-requests?view=aspnetcore-2.1#use-polly-based-handlers) ++ [Polly documentation on Polly and HttpClientFactory](https://github.com/App-vNext/Polly/wiki/Polly-and-HttpClientFactory) ++ [Main Polly readme](https://github.com/App-vNext/Polly): quickstart details of all Polly policies and features ++ [Polly wiki](https://github.com/App-vNext/Polly/wiki): deep doco on Polly features -For more information on Polly and configuring Polly policies see the [main Polly repository](https://github.com/App-vNext/Polly) and [wiki](https://github.com/App-vNext/Polly/wiki). # Release notes diff --git a/build.cake b/build.cake index aca42d7..c94a056 100644 --- a/build.cake +++ b/build.cake @@ -38,23 +38,27 @@ var testResultsDir = artifactsDir + Directory("test-results"); // NuGet var nuspecExtension = ".nuspec"; -var signed = "-Signed"; var nuspecFolder = "nuget-package"; var nuspecSrcFile = srcDir + File(projectName + nuspecExtension); var nuspecDestFile = buildDir + File(projectName + nuspecExtension); -var nuspecSignedDestFile = buildDir + File(projectName + signed + nuspecExtension); var nupkgDestDir = artifactsDir + Directory(nuspecFolder); var snkFile = srcDir + File(keyName); var projectToNugetFolderMap = new Dictionary() { { "NetStandard11", new [] {"netstandard1.1"} }, - { "NetStandard11-Signed", new [] {"netstandard1.1"} }, + { "NetStandard20", new [] {"netstandard2.0"} }, }; // Gitversion var gitVersionPath = ToolsExePath("GitVersion.exe"); Dictionary gitVersionOutput; +// Versioning +string nugetVersion; +string appveyorBuildNumber; +string assemblyVersion; +string assemblySemver; + // StrongNameSigner var strongNameSignerPath = ToolsExePath("StrongNameSigner.Console.exe"); @@ -128,37 +132,62 @@ Task("__UpdateAssemblyVersionInformation") gitVersionOutput = new JsonParser().Parse>(output); Information("Updated GlobalAssemblyInfo"); - Information("AssemblyVersion -> {0}", gitVersionOutput["AssemblySemVer"]); - Information("AssemblyFileVersion -> {0}", gitVersionOutput["MajorMinorPatch"]); - Information("AssemblyInformationalVersion -> {0}", gitVersionOutput["InformationalVersion"]); + + Information(""); + Information("Obtained raw version info for package versioning:"); + Information("NuGetVersion -> {0}", gitVersionOutput["NuGetVersion"]); + Information("FullSemVer -> {0}", gitVersionOutput["FullSemVer"]); + Information("AssemblySemVer -> {0}", gitVersionOutput["AssemblySemVer"]); + + appveyorBuildNumber = gitVersionOutput["FullSemVer"].ToString(); + nugetVersion = gitVersionOutput["NuGetVersion"].ToString(); + assemblyVersion = gitVersionOutput["Major"].ToString() + ".0.0.0"; + assemblySemver = gitVersionOutput["AssemblySemVer"].ToString(); + + Information(""); + Information("Mapping versioning information to:"); + Information("Appveyor build number -> {0}", appveyorBuildNumber); + Information("Nuget package version -> {0}", nugetVersion); + Information("AssemblyVersion -> {0}", assemblyVersion); + Information("AssemblyFileVersion -> {0}", assemblySemver); + Information("AssemblyInformationalVersion -> {0}", assemblySemver); }); Task("__UpdateDotNetStandardAssemblyVersionNumber") .Does(() => { - // NOTE: TEMPORARY fix only, while GitVersionTask does not support .Net Standard assemblies. See https://github.com/App-vNext/Polly/issues/176. - // This build Task can be removed when GitVersionTask supports .Net Standard assemblies. - var assemblySemVer = gitVersionOutput["AssemblySemVer"].ToString(); - Information("Updating NetStandard AssemblyVersions to {0}", assemblySemVer); + Information("Updating Assembly Version Information"); + + var attributeToValueMap = new Dictionary() { + { "AssemblyVersion", assemblyVersion }, + { "AssemblyFileVersion", assemblySemver }, + { "AssemblyInformationalVersion", assemblySemver }, + }; + var assemblyInfosToUpdate = GetFiles("./src/**/Properties/AssemblyInfo.cs") .Select(f => f.FullPath) .Where(f => !f.Contains("Specs")); - foreach(var assemblyInfo in assemblyInfosToUpdate) { - var replacedFiles = ReplaceRegexInFiles(assemblyInfo, "AssemblyVersion[(]\".*\"[)]", "AssemblyVersion(\"" + assemblySemVer +"\")"); - if (!replacedFiles.Any()) - { - throw new Exception($"AssemblyVersion could not be updated in {assemblyInfo}."); + foreach(var attributeMap in attributeToValueMap) { + var attribute = attributeMap.Key; + var value = attributeMap.Value; + + foreach(var assemblyInfo in assemblyInfosToUpdate) { + var replacedFiles = ReplaceRegexInFiles(assemblyInfo, attribute + "[(]\".*\"[)]", attribute + "(\"" + value +"\")"); + if (!replacedFiles.Any()) + { + throw new Exception($"{attribute} attribute could not be updated in {assemblyInfo}."); + } } } + }); Task("__UpdateAppVeyorBuildNumber") .WithCriteria(() => AppVeyor.IsRunningOnAppVeyor) .Does(() => { - var fullSemVer = gitVersionOutput["FullSemVer"].ToString(); - AppVeyor.UpdateBuildVersion(fullSemVer); + AppVeyor.UpdateBuildVersion(appveyorBuildNumber); }); Task("__BuildSolutions") @@ -189,12 +218,10 @@ Task("__RunTests") } }); -Task("__CopyNonSignedOutputToNugetFolder") +Task("__CopyOutputToNugetFolder") .Does(() => { - foreach(var project in projectToNugetFolderMap.Keys - .Where(p => !p.Contains(signed)) - ) { + foreach(var project in projectToNugetFolderMap.Keys) { var sourceDir = srcDir + Directory(projectName + "." + project) + Directory("bin") + Directory(configuration); foreach(var targetFolder in projectToNugetFolderMap[project]) { @@ -208,35 +235,25 @@ Task("__CopyNonSignedOutputToNugetFolder") CopyFile(nuspecSrcFile, nuspecDestFile); }); -Task("__CopySignedOutputToNugetFolder") +Task("__StronglySignAssemblies") .Does(() => { - foreach(var project in projectToNugetFolderMap.Keys - .Where(p => p.Contains(signed)) - ) { - var sourceDir = srcDir + Directory(projectName + "." + project) + Directory("bin") + Directory(configuration); - - foreach(var targetFolder in projectToNugetFolderMap[project]) { - var destDir = buildDir + Directory("lib"); - - Information("Copying {0} -> {1}.", sourceDir, destDir); - CopyDirectory(sourceDir, destDir); - } - } + //see: https://github.com/brutaldev/StrongNameSigner + var strongNameSignerSettings = new ProcessSettings() + .WithArguments(args => args + .Append("-in") + .AppendQuoted(buildDir) + .Append("-k") + .AppendQuoted(snkFile) + .Append("-l") + .AppendQuoted("Changes")); - CopyFile(nuspecSrcFile, nuspecSignedDestFile); - - var replacedFiles = ReplaceTextInFiles(nuspecSignedDestFile, "dependency id=\"Polly\"", "dependency id=\"Polly-Signed\""); - if (!replacedFiles.Any()) - { - throw new Exception("Could not set Polly dependency to Polly-Signed, for -Signed nuget package."); - } + StartProcess(strongNameSignerPath, strongNameSignerSettings); }); -Task("__CreateNonSignedNugetPackage") +Task("__CreateSignedNugetPackage") .Does(() => { - var nugetVersion = gitVersionOutput["NuGetVersion"].ToString(); var packageName = projectName; Information("Building {0}.{1}.nupkg", packageName, nugetVersion); @@ -251,40 +268,6 @@ Task("__CreateNonSignedNugetPackage") NuGetPack(nuspecDestFile, nuGetPackSettings); }); -Task("__CreateSignedNugetPackage") - .Does(() => -{ - var nugetVersion = gitVersionOutput["NuGetVersion"].ToString(); - var packageName = projectName + "-Signed"; - - Information("Building {0}.{1}.nupkg", packageName, nugetVersion); - - var nuGetPackSettings = new NuGetPackSettings { - Id = packageName, - Title = packageName, - Version = nugetVersion, - OutputDirectory = nupkgDestDir - }; - - NuGetPack(nuspecSignedDestFile, nuGetPackSettings); -}); - -Task("__StronglySignAssemblies") - .Does(() => -{ - //see: https://github.com/brutaldev/StrongNameSigner - var strongNameSignerSettings = new ProcessSettings() - .WithArguments(args => args - .Append("-in") - .AppendQuoted(buildDir) - .Append("-k") - .AppendQuoted(snkFile) - .Append("-l") - .AppendQuoted("Changes")); - - StartProcess(strongNameSignerPath, strongNameSignerSettings); -}); - ////////////////////////////////////////////////////////////////////// // BUILD TASKS ////////////////////////////////////////////////////////////////////// @@ -297,9 +280,7 @@ Task("Build") .IsDependentOn("__UpdateAppVeyorBuildNumber") .IsDependentOn("__BuildSolutions") .IsDependentOn("__RunTests") - .IsDependentOn("__CopyNonSignedOutputToNugetFolder") - .IsDependentOn("__CreateNonSignedNugetPackage") - .IsDependentOn("__CopySignedOutputToNugetFolder") + .IsDependentOn("__CopyOutputToNugetFolder") .IsDependentOn("__StronglySignAssemblies") .IsDependentOn("__CreateSignedNugetPackage"); diff --git a/src/Polly.Extensions.Http.NetStandard11.Specs/Polly.Extensions.Http.NetStandard11.Specs.csproj b/src/Polly.Extensions.Http.NetStandard11.Specs/Polly.Extensions.Http.NetStandard11.Specs.csproj index f91ccd3..7fb7747 100644 --- a/src/Polly.Extensions.Http.NetStandard11.Specs/Polly.Extensions.Http.NetStandard11.Specs.csproj +++ b/src/Polly.Extensions.Http.NetStandard11.Specs/Polly.Extensions.Http.NetStandard11.Specs.csproj @@ -17,7 +17,7 @@ - + diff --git a/src/Polly.Extensions.Http.NetStandard11/Polly.Extensions.Http.NetStandard11.csproj b/src/Polly.Extensions.Http.NetStandard11/Polly.Extensions.Http.NetStandard11.csproj index 3c17f50..8f60a27 100644 --- a/src/Polly.Extensions.Http.NetStandard11/Polly.Extensions.Http.NetStandard11.csproj +++ b/src/Polly.Extensions.Http.NetStandard11/Polly.Extensions.Http.NetStandard11.csproj @@ -6,7 +6,7 @@ en-US false true - PolicyExtensions + Polly.Extensions.Http netstandard1.1 1.6.1 @@ -28,7 +28,7 @@ - + \ No newline at end of file diff --git a/src/Polly.Extensions.Http.NetStandard11/Properties/AssemblyInfo.cs b/src/Polly.Extensions.Http.NetStandard11/Properties/AssemblyInfo.cs index 963c192..1754279 100644 --- a/src/Polly.Extensions.Http.NetStandard11/Properties/AssemblyInfo.cs +++ b/src/Polly.Extensions.Http.NetStandard11/Properties/AssemblyInfo.cs @@ -3,7 +3,9 @@ using System.Runtime.CompilerServices; [assembly: AssemblyTitle("Polly.Extensions.Http")] -[assembly: AssemblyVersion("1.0.3.0")] +[assembly: AssemblyInformationalVersion("2.0.1.0")] +[assembly: AssemblyFileVersion("2.0.1.0")] +[assembly: AssemblyVersion("2.0.0.0")] [assembly: CLSCompliant(true)] [assembly: InternalsVisibleTo("Polly.Extensions.Http.NetStandard11.Specs")] \ No newline at end of file diff --git a/src/Polly.Extensions.Http.NetStandard11-Signed.Specs/Polly.Extensions.Http.NetStandard11-Signed.Specs.csproj b/src/Polly.Extensions.Http.NetStandard20.Specs/Polly.Extensions.Http.NetStandard20.Specs.csproj similarity index 76% rename from src/Polly.Extensions.Http.NetStandard11-Signed.Specs/Polly.Extensions.Http.NetStandard11-Signed.Specs.csproj rename to src/Polly.Extensions.Http.NetStandard20.Specs/Polly.Extensions.Http.NetStandard20.Specs.csproj index 25cf76b..77fe697 100644 --- a/src/Polly.Extensions.Http.NetStandard11-Signed.Specs/Polly.Extensions.Http.NetStandard11-Signed.Specs.csproj +++ b/src/Polly.Extensions.Http.NetStandard20.Specs/Polly.Extensions.Http.NetStandard20.Specs.csproj @@ -1,23 +1,23 @@ - + false Library - netcoreapp1.1 + netcoreapp2.0 library full - TRACE;DEBUG;NETCOREAPP1_1 + TRACE;DEBUG;NETCOREAPP2_0 pdbonly true - TRACE;RELEASE;NETCOREAPP1_1 + TRACE;RELEASE;NETCOREAPP2_0 - + @@ -27,7 +27,7 @@ - + diff --git a/src/Polly.Extensions.Http.NetStandard11-Signed.Specs/Properties/AssemblyInfo.cs b/src/Polly.Extensions.Http.NetStandard20.Specs/Properties/AssemblyInfo.cs similarity index 100% rename from src/Polly.Extensions.Http.NetStandard11-Signed.Specs/Properties/AssemblyInfo.cs rename to src/Polly.Extensions.Http.NetStandard20.Specs/Properties/AssemblyInfo.cs diff --git a/src/Polly.Extensions.Http.NetStandard11-Signed/Polly.Extensions.Http.NetStandard11-Signed.csproj b/src/Polly.Extensions.Http.NetStandard20/Polly.Extensions.Http.NetStandard20.csproj similarity index 79% rename from src/Polly.Extensions.Http.NetStandard11-Signed/Polly.Extensions.Http.NetStandard11-Signed.csproj rename to src/Polly.Extensions.Http.NetStandard20/Polly.Extensions.Http.NetStandard20.csproj index 37210ab..79e77c1 100644 --- a/src/Polly.Extensions.Http.NetStandard11-Signed/Polly.Extensions.Http.NetStandard11-Signed.csproj +++ b/src/Polly.Extensions.Http.NetStandard20/Polly.Extensions.Http.NetStandard20.csproj @@ -1,4 +1,4 @@ - + Polly.Extensions.Http @@ -6,9 +6,8 @@ en-US false true - PolicyExtensions - netstandard1.1 - 1.6.1 + Polly.Extensions.Http + netstandard2.0 full @@ -28,7 +27,7 @@ - + \ No newline at end of file diff --git a/src/Polly.Extensions.Http.NetStandard11-Signed/Properties/AssemblyInfo.cs b/src/Polly.Extensions.Http.NetStandard20/Properties/AssemblyInfo.cs similarity index 60% rename from src/Polly.Extensions.Http.NetStandard11-Signed/Properties/AssemblyInfo.cs rename to src/Polly.Extensions.Http.NetStandard20/Properties/AssemblyInfo.cs index 063044a..70f5749 100644 --- a/src/Polly.Extensions.Http.NetStandard11-Signed/Properties/AssemblyInfo.cs +++ b/src/Polly.Extensions.Http.NetStandard20/Properties/AssemblyInfo.cs @@ -3,7 +3,9 @@ using System.Runtime.CompilerServices; [assembly: AssemblyTitle("Polly.Extensions.Http")] -[assembly: AssemblyVersion("1.0.3.0")] +[assembly: AssemblyInformationalVersion("2.0.1.0")] +[assembly: AssemblyFileVersion("2.0.1.0")] +[assembly: AssemblyVersion("2.0.0.0")] [assembly: CLSCompliant(true)] -[assembly: InternalsVisibleTo("Polly.Extensions.Http.NetStandard11-Signed.Specs")] \ No newline at end of file +[assembly: InternalsVisibleTo("Polly.Extensions.Http.NetStandard20.Specs")] \ No newline at end of file diff --git a/src/Polly.Extensions.Http.nuspec b/src/Polly.Extensions.Http.nuspec index 6dd5cc4..d79d757 100644 --- a/src/Polly.Extensions.Http.nuspec +++ b/src/Polly.Extensions.Http.nuspec @@ -13,6 +13,15 @@ HttpClient Exception Handling Resilience Transient Fault Policy Copyright © 2018, App vNext + 2.0.1 + --------------------- + - Version 2 RTM, for integration to ASPNET Core 2.1 IHttpClientFactory + + 2.0.0-v2alpha + --------------------- + - Publish as strong-named package only (discontinue non-strong-named versions) + - Add .NetStandard 2.0 target + 1.0.3 --------------------- - RTM version @@ -36,9 +45,12 @@ - + + + + diff --git a/src/Polly.Extensions.Http.sln b/src/Polly.Extensions.Http.sln index 8226d85..412814c 100644 --- a/src/Polly.Extensions.Http.sln +++ b/src/Polly.Extensions.Http.sln @@ -17,9 +17,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Polly.Extensions.Http.NetSt EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Polly.Extensions.Http.NetStandard11.Specs", "Polly.Extensions.Http.NetStandard11.Specs\Polly.Extensions.Http.NetStandard11.Specs.csproj", "{615C92EC-5921-40F4-A690-C66B1587C08E}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Polly.Extensions.Http.NetStandard11-Signed", "Polly.Extensions.Http.NetStandard11-Signed\Polly.Extensions.Http.NetStandard11-Signed.csproj", "{1CFC0F44-E534-4F9F-B916-F408244356B4}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Polly.Extensions.Http.NetStandard20", "Polly.Extensions.Http.NetStandard20\Polly.Extensions.Http.NetStandard20.csproj", "{D8108479-6F4B-45CB-9E49-D45D1DC18F10}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Polly.Extensions.Http.NetStandard11-Signed.Specs", "Polly.Extensions.Http.NetStandard11-Signed.Specs\Polly.Extensions.Http.NetStandard11-Signed.Specs.csproj", "{A69B39A4-158C-41C0-9144-E49503FE7A8D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Polly.Extensions.Http.NetStandard20.Specs", "Polly.Extensions.Http.NetStandard20.Specs\Polly.Extensions.Http.NetStandard20.Specs.csproj", "{435D99EB-3689-4EA0-96FE-2FA17930322D}" EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution @@ -40,14 +40,14 @@ Global {615C92EC-5921-40F4-A690-C66B1587C08E}.Debug|Any CPU.Build.0 = Debug|Any CPU {615C92EC-5921-40F4-A690-C66B1587C08E}.Release|Any CPU.ActiveCfg = Release|Any CPU {615C92EC-5921-40F4-A690-C66B1587C08E}.Release|Any CPU.Build.0 = Release|Any CPU - {1CFC0F44-E534-4F9F-B916-F408244356B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1CFC0F44-E534-4F9F-B916-F408244356B4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1CFC0F44-E534-4F9F-B916-F408244356B4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1CFC0F44-E534-4F9F-B916-F408244356B4}.Release|Any CPU.Build.0 = Release|Any CPU - {A69B39A4-158C-41C0-9144-E49503FE7A8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A69B39A4-158C-41C0-9144-E49503FE7A8D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A69B39A4-158C-41C0-9144-E49503FE7A8D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A69B39A4-158C-41C0-9144-E49503FE7A8D}.Release|Any CPU.Build.0 = Release|Any CPU + {D8108479-6F4B-45CB-9E49-D45D1DC18F10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D8108479-6F4B-45CB-9E49-D45D1DC18F10}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D8108479-6F4B-45CB-9E49-D45D1DC18F10}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D8108479-6F4B-45CB-9E49-D45D1DC18F10}.Release|Any CPU.Build.0 = Release|Any CPU + {435D99EB-3689-4EA0-96FE-2FA17930322D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {435D99EB-3689-4EA0-96FE-2FA17930322D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {435D99EB-3689-4EA0-96FE-2FA17930322D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {435D99EB-3689-4EA0-96FE-2FA17930322D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE