From 9da2475e2f6f3689890e1ddb1c70d20ed43ee85b Mon Sep 17 00:00:00 2001 From: Andrew Stanton-Nurse Date: Tue, 13 Oct 2015 14:31:29 -0700 Subject: [PATCH] port DNX's ApplicationHostContext as ProjectContext --- Microsoft.DotNet.Cli.sln | 28 +- bootstrap.cmd | 6 + build.cmd | 12 +- makefile.shade | 6 +- scripts/dotnet-resolve-sources | 17 - scripts/dotnet-resolve-sources.cmd | 11 - .../AnsiExtensions.cs | 49 + src/Microsoft.DotNet.Cli.Utils/Command.cs | 5 + src/Microsoft.DotNet.Cli.Utils/Constants.cs | 1 + src/Microsoft.DotNet.Cli.Utils/DebugHelper.cs | 28 + src/Microsoft.DotNet.Cli.Utils/project.json | 20 +- src/Microsoft.DotNet.Cli/Program.cs | 2 + src/Microsoft.DotNet.Cli/project.json | 41 +- .../Program.cs | 210 ++-- .../Reporter.cs | 17 + .../project.json | 50 +- ...soft.DotNet.Tools.DependencyResolver.xproj | 19 - .../Program.cs | 101 -- .../Resolver.cs | 83 -- .../project.json | 26 - src/Microsoft.DotNet.Tools.Publish/Program.cs | 107 +- .../Reporter.cs | 17 + .../project.json | 50 +- src/Microsoft.DotNet.Tools.Run/Program.cs | 112 -- src/Microsoft.DotNet.Tools.Run/project.json | 27 - ...icrosoft.DotNet.Tools.SourceResolver.xproj | 19 - .../Program.cs | 32 - .../Resolver.cs | 53 - .../project.json | 25 - .../Compilation/LibraryExport.cs | 43 + .../Compilation/LibraryExporter.cs | 257 +++++ .../CompilerOptions.cs | 98 ++ .../DiagnosticMessage.cs | 148 +++ .../DiagnosticMessageExtensions.cs | 21 + .../DiagnosticMessageSeverity.cs | 15 + .../DiagnosticMonikers.cs | 41 + .../EnvironmentNames.cs | 7 + .../FileFormatException.cs | 124 +++ .../GlobalSettings.cs | 84 ++ .../Graph/LibraryDependencyType.cs | 47 + .../Graph/LibraryDependencyTypeFlag.cs | 21 + .../Graph/LibraryIdentity.cs | 86 ++ .../Graph/LibraryRange.cs | 109 ++ .../Graph/LibraryType.cs | 86 ++ .../Graph/LockFile.cs | 134 +++ .../Graph/LockFileItem.cs | 20 + .../Graph/LockFileLookup.cs | 57 + .../Graph/LockFilePackageLibrary.cs | 21 + .../Graph/LockFileProjectLibrary.cs | 16 + .../Graph/LockFileReader.cs | 492 +++++++++ .../Graph/LockFileTarget.cs | 17 + .../Graph/LockFileTargetLibrary.cs | 34 + .../LibraryDescription.cs | 49 + .../Microsoft.Extensions.ProjectModel.xproj} | 7 +- .../PackIncludeEntry.cs | 41 + .../PackageDescription.cs | 31 + .../PatternGroup.cs | 123 +++ .../PatternsCollectionHelper.cs | 107 ++ .../Project.cs | 200 ++++ .../ProjectContext.cs | 114 ++ .../ProjectContextBuilder.cs | 231 ++++ .../ProjectDescription.cs | 48 + .../ProjectFileDependencyGroup.cs | 21 + .../ProjectFilesCollection.cs | 201 ++++ .../ProjectReader.cs | 519 +++++++++ .../ProjectRootResolver.cs | 31 + .../Properties/AssemblyInfo.cs | 23 + .../Resolution/FrameworkDefinitions.cs | 992 ++++++++++++++++++ .../Resolution/FrameworkInformation.cs | 49 + .../Resolution/FrameworkReferenceResolver.cs | 369 +++++++ .../Resolution/LibraryManager.cs | 292 ++++++ .../Resolution/PackageDependencyProvider.cs | 164 +++ .../Resolution/ProjectDependencyProvider.cs | 74 ++ .../ReferenceAssemblyDependencyResolver.cs | 56 + .../UnresolvedDependencyProvider.cs | 24 + .../TargetFrameworkInformation.cs | 30 + .../Utilities/DictionaryExtensions.cs | 23 + .../Utilities/FileSystemUtility.cs | 39 + .../Utilities/FrameworksExtensions.cs | 20 + .../Utilities/JsonExtensions.cs | 27 + .../Utilities/NamedResourceReader.cs | 76 ++ .../Utilities/PathUtility.cs | 202 ++++ .../Utilities/VersionUtility.cs | 18 + .../Utilities/VersioningExtensions.cs | 45 + .../project.json | 25 + 85 files changed, 6676 insertions(+), 747 deletions(-) create mode 100644 bootstrap.cmd delete mode 100644 scripts/dotnet-resolve-sources delete mode 100644 scripts/dotnet-resolve-sources.cmd create mode 100644 src/Microsoft.DotNet.Cli.Utils/AnsiExtensions.cs create mode 100644 src/Microsoft.DotNet.Cli.Utils/DebugHelper.cs create mode 100644 src/Microsoft.DotNet.Tools.Compiler/Reporter.cs delete mode 100644 src/Microsoft.DotNet.Tools.DependencyResolver/Microsoft.DotNet.Tools.DependencyResolver.xproj delete mode 100644 src/Microsoft.DotNet.Tools.DependencyResolver/Program.cs delete mode 100644 src/Microsoft.DotNet.Tools.DependencyResolver/Resolver.cs delete mode 100644 src/Microsoft.DotNet.Tools.DependencyResolver/project.json create mode 100644 src/Microsoft.DotNet.Tools.Publish/Reporter.cs delete mode 100644 src/Microsoft.DotNet.Tools.Run/Program.cs delete mode 100644 src/Microsoft.DotNet.Tools.Run/project.json delete mode 100644 src/Microsoft.DotNet.Tools.SourceResolver/Microsoft.DotNet.Tools.SourceResolver.xproj delete mode 100644 src/Microsoft.DotNet.Tools.SourceResolver/Program.cs delete mode 100644 src/Microsoft.DotNet.Tools.SourceResolver/Resolver.cs delete mode 100644 src/Microsoft.DotNet.Tools.SourceResolver/project.json create mode 100644 src/Microsoft.Extensions.ProjectModel/Compilation/LibraryExport.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Compilation/LibraryExporter.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/CompilerOptions.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/DiagnosticMessage.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/DiagnosticMessageExtensions.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/DiagnosticMessageSeverity.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/DiagnosticMonikers.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/EnvironmentNames.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/FileFormatException.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/GlobalSettings.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Graph/LibraryDependencyType.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Graph/LibraryDependencyTypeFlag.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Graph/LibraryIdentity.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Graph/LibraryRange.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Graph/LibraryType.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Graph/LockFile.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Graph/LockFileItem.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Graph/LockFileLookup.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Graph/LockFilePackageLibrary.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Graph/LockFileProjectLibrary.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Graph/LockFileReader.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Graph/LockFileTarget.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Graph/LockFileTargetLibrary.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/LibraryDescription.cs rename src/{Microsoft.DotNet.Tools.Run/Microsoft.DotNet.Tools.Run.xproj => Microsoft.Extensions.ProjectModel/Microsoft.Extensions.ProjectModel.xproj} (87%) create mode 100644 src/Microsoft.Extensions.ProjectModel/PackIncludeEntry.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/PackageDescription.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/PatternGroup.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/PatternsCollectionHelper.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Project.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/ProjectContext.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/ProjectContextBuilder.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/ProjectDescription.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/ProjectFileDependencyGroup.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/ProjectFilesCollection.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/ProjectReader.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/ProjectRootResolver.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Properties/AssemblyInfo.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Resolution/FrameworkDefinitions.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Resolution/FrameworkInformation.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Resolution/FrameworkReferenceResolver.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Resolution/LibraryManager.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Resolution/PackageDependencyProvider.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Resolution/ProjectDependencyProvider.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Resolution/ReferenceAssemblyDependencyResolver.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Resolution/UnresolvedDependencyProvider.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/TargetFrameworkInformation.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Utilities/DictionaryExtensions.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Utilities/FileSystemUtility.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Utilities/FrameworksExtensions.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Utilities/JsonExtensions.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Utilities/NamedResourceReader.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Utilities/PathUtility.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Utilities/VersionUtility.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/Utilities/VersioningExtensions.cs create mode 100644 src/Microsoft.Extensions.ProjectModel/project.json diff --git a/Microsoft.DotNet.Cli.sln b/Microsoft.DotNet.Cli.sln index 0ab4fd608..525d8e8e4 100644 --- a/Microsoft.DotNet.Cli.sln +++ b/Microsoft.DotNet.Cli.sln @@ -17,14 +17,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Cli.Utils" EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Tools.Compiler", "src\Microsoft.DotNet.Tools.Compiler\Microsoft.DotNet.Tools.Compiler.xproj", "{0A309227-A9D8-4DDF-88DD-326B57B04378}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Tools.DependencyResolver", "src\Microsoft.DotNet.Tools.DependencyResolver\Microsoft.DotNet.Tools.DependencyResolver.xproj", "{4298DF4A-E04C-4ED9-95F8-FBB7CB32721F}" -EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Tools.Publish", "src\Microsoft.DotNet.Tools.Publish\Microsoft.DotNet.Tools.Publish.xproj", "{391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Tools.Run", "src\Microsoft.DotNet.Tools.Run\Microsoft.DotNet.Tools.Run.xproj", "{8B23B5EC-6740-447C-92D9-1F10692F232D}" -EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Tools.SourceResolver", "src\Microsoft.DotNet.Tools.SourceResolver\Microsoft.DotNet.Tools.SourceResolver.xproj", "{7108E4FB-E2F1-4682-8464-1DD6EFB17035}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{13F8C30C-1011-459C-82B2-0ACDD73EDA18}" ProjectSection(SolutionItems) = preProject scripts\dotnet = scripts\dotnet @@ -43,6 +37,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{13F8 scripts\dotnet.cmd = scripts\dotnet.cmd EndProjectSection EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Extensions.ProjectModel", "src\Microsoft.Extensions.ProjectModel\Microsoft.Extensions.ProjectModel.xproj", "{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -61,22 +57,14 @@ Global {0A309227-A9D8-4DDF-88DD-326B57B04378}.Debug|Any CPU.Build.0 = Debug|Any CPU {0A309227-A9D8-4DDF-88DD-326B57B04378}.Release|Any CPU.ActiveCfg = Release|Any CPU {0A309227-A9D8-4DDF-88DD-326B57B04378}.Release|Any CPU.Build.0 = Release|Any CPU - {4298DF4A-E04C-4ED9-95F8-FBB7CB32721F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4298DF4A-E04C-4ED9-95F8-FBB7CB32721F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4298DF4A-E04C-4ED9-95F8-FBB7CB32721F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4298DF4A-E04C-4ED9-95F8-FBB7CB32721F}.Release|Any CPU.Build.0 = Release|Any CPU {391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.Debug|Any CPU.Build.0 = Debug|Any CPU {391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.Release|Any CPU.ActiveCfg = Release|Any CPU {391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.Release|Any CPU.Build.0 = Release|Any CPU - {8B23B5EC-6740-447C-92D9-1F10692F232D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8B23B5EC-6740-447C-92D9-1F10692F232D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8B23B5EC-6740-447C-92D9-1F10692F232D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8B23B5EC-6740-447C-92D9-1F10692F232D}.Release|Any CPU.Build.0 = Release|Any CPU - {7108E4FB-E2F1-4682-8464-1DD6EFB17035}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7108E4FB-E2F1-4682-8464-1DD6EFB17035}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7108E4FB-E2F1-4682-8464-1DD6EFB17035}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7108E4FB-E2F1-4682-8464-1DD6EFB17035}.Release|Any CPU.Build.0 = Release|Any CPU + {303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -85,9 +73,7 @@ Global {60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} {61B7C351-C77D-43F7-B56F-BB1440178E10} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} {0A309227-A9D8-4DDF-88DD-326B57B04378} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} - {4298DF4A-E04C-4ED9-95F8-FBB7CB32721F} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} {391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} - {8B23B5EC-6740-447C-92D9-1F10692F232D} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} - {7108E4FB-E2F1-4682-8464-1DD6EFB17035} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} + {303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} EndGlobalSection EndGlobal diff --git a/bootstrap.cmd b/bootstrap.cmd new file mode 100644 index 000000000..dda509d78 --- /dev/null +++ b/bootstrap.cmd @@ -0,0 +1,6 @@ +REM Build 'dotnet' using a version of 'dotnet' hosted on the DNX +REM The output of this is independent of DNX + +call "%~dp0scripts\dotnet" publish --framework dnxcore50 --runtime win7-x64 --output "%~dp0artifacts\published" "%~dp0src\Microsoft.DotNet.Cli" +call "%~dp0scripts\dotnet" publish --framework dnxcore50 --runtime win7-x64 --output "%~dp0artifacts\published" "%~dp0src\Microsoft.DotNet.Tools.Compiler" +call "%~dp0scripts\dotnet" publish --framework dnxcore50 --runtime win7-x64 --output "%~dp0artifacts\published" "%~dp0src\Microsoft.DotNet.Tools.Publish" \ No newline at end of file diff --git a/build.cmd b/build.cmd index 70d974a61..bb8b27608 100644 --- a/build.cmd +++ b/build.cmd @@ -26,14 +26,6 @@ IF %BUILDCMD_KOREBUILD_VERSION%=="" ( ) .nuget\nuget.exe install Sake -ExcludeVersion -Out packages -IF "%SKIP_DNX_INSTALL%"=="1" goto run -IF %BUILDCMD_DNX_VERSION%=="" ( - CALL packages\KoreBuild\build\dnvm upgrade -runtime CLR -arch x86 -) ELSE ( - CALL packages\KoreBuild\build\dnvm install %BUILDCMD_DNX_VERSION% -runtime CLR -arch x86 -alias default -) -CALL packages\KoreBuild\build\dnvm install default -runtime CoreCLR -arch x86 - :run -CALL packages\KoreBuild\build\dnvm use default -runtime CLR -arch x86 -packages\Sake\tools\Sake.exe -I packages\KoreBuild\build -f makefile.shade %* \ No newline at end of file +CALL packages\KoreBuild\build\dnvm use default -runtime CoreCLR -arch x64 +packages\Sake\tools\Sake.exe -I packages\KoreBuild\build -f makefile.shade %* diff --git a/makefile.shade b/makefile.shade index 562494d14..acc5be863 100644 --- a/makefile.shade +++ b/makefile.shade @@ -1,7 +1,11 @@ - var VERSION='0.1' var FULL_VERSION='0.1' var AUTHORS='Microsoft Open Technologies, Inc.' use-standard-lifecycle k-standard-goals + +#bootstrap + -// Build the compiler and publisher using dnu (kpm == dnu) + kpm-build projectFile='src/Microsoft.DotNet.Tools.Compiler/project.json' + kpm-build projectFile='src/Microsoft.DotNet.Tools.Publish/project.json' diff --git a/scripts/dotnet-resolve-sources b/scripts/dotnet-resolve-sources deleted file mode 100644 index 108f847e6..000000000 --- a/scripts/dotnet-resolve-sources +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink - DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - SOURCE="$(readlink "$SOURCE")" - [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located -done -DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - -# work around restore timeouts on Mono -[ -z "$MONO_THREADS_PER_CPU" ] && export MONO_THREADS_PER_CPU=50 - -# Makes development easier -export PATH=$PATH:$DIR - -exec "dnx" -p "$DIR/../src/Microsoft.DotNet.Tools.SourceResolver" run "$@" diff --git a/scripts/dotnet-resolve-sources.cmd b/scripts/dotnet-resolve-sources.cmd deleted file mode 100644 index 58efcbfeb..000000000 --- a/scripts/dotnet-resolve-sources.cmd +++ /dev/null @@ -1,11 +0,0 @@ -@Echo OFF -SETLOCAL -SET ERRORLEVEL= - -REM makes testing easier for now -set PATH=%PATH%;%~dp0 - -dnx %DOTNET_OPTIONS% -p %~dp0..\src\Microsoft.DotNet.Tools.SourceResolver run %* - -exit /b %ERRORLEVEL% -ENDLOCAL diff --git a/src/Microsoft.DotNet.Cli.Utils/AnsiExtensions.cs b/src/Microsoft.DotNet.Cli.Utils/AnsiExtensions.cs new file mode 100644 index 000000000..f7174c3c5 --- /dev/null +++ b/src/Microsoft.DotNet.Cli.Utils/AnsiExtensions.cs @@ -0,0 +1,49 @@ +namespace Microsoft.DotNet.Cli.Utils +{ + public static class AnsiExtensions + { + public static string Black(this string text) + { + return "\x1B[30m" + text + "\x1B[39m"; + } + + public static string Red(this string text) + { + return "\x1B[31m" + text + "\x1B[39m"; + } + public static string Green(this string text) + { + return "\x1B[32m" + text + "\x1B[39m"; + } + + public static string Yellow(this string text) + { + return "\x1B[33m" + text + "\x1B[39m"; + } + + public static string Blue(this string text) + { + return "\x1B[34m" + text + "\x1B[39m"; + } + + public static string Magenta(this string text) + { + return "\x1B[35m" + text + "\x1B[39m"; + } + + public static string Cyan(this string text) + { + return "\x1B[36m" + text + "\x1B[39m"; + } + + public static string White(this string text) + { + return "\x1B[37m" + text + "\x1B[39m"; + } + + public static string Bold(this string text) + { + return "\x1B[1m" + text + "\x1B[22m"; + } + } +} diff --git a/src/Microsoft.DotNet.Cli.Utils/Command.cs b/src/Microsoft.DotNet.Cli.Utils/Command.cs index 923a9899e..baf40a800 100644 --- a/src/Microsoft.DotNet.Cli.Utils/Command.cs +++ b/src/Microsoft.DotNet.Cli.Utils/Command.cs @@ -4,12 +4,15 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Threading.Tasks; namespace Microsoft.DotNet.Cli.Utils { public class Command { + private static readonly string[] WindowsExecutableExtensions = new[] { "exe", "cmd", "bat" }; + private TaskCompletionSource _processTcs; private Process _process; @@ -59,6 +62,8 @@ namespace Microsoft.DotNet.Cli.Utils { args = " " + args; } + var cmd = executable + args; + cmd = cmd.Replace("\"", "\\\""); args = $"/C \"{executable}{args}\""; executable = comSpec; } diff --git a/src/Microsoft.DotNet.Cli.Utils/Constants.cs b/src/Microsoft.DotNet.Cli.Utils/Constants.cs index 1ee503cb3..1e5dc861e 100644 --- a/src/Microsoft.DotNet.Cli.Utils/Constants.cs +++ b/src/Microsoft.DotNet.Cli.Utils/Constants.cs @@ -10,5 +10,6 @@ namespace Microsoft.DotNet.Cli.Utils // TODO: On Unix, exe suffix is empty string... public static readonly string ExeSuffix = ".exe"; public static readonly string CoreConsoleName = "coreconsole" + ExeSuffix; + public static readonly string DefaultConfiguration = "Debug"; } } diff --git a/src/Microsoft.DotNet.Cli.Utils/DebugHelper.cs b/src/Microsoft.DotNet.Cli.Utils/DebugHelper.cs new file mode 100644 index 000000000..f2478c201 --- /dev/null +++ b/src/Microsoft.DotNet.Cli.Utils/DebugHelper.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.DotNet.Cli.Utils +{ + internal static class DebugHelper + { + [Conditional("DEBUG")] + public static void HandleDebugSwitch(ref string[] args) + { + if (args.Length > 0 && string.Equals("--debug", args[0], StringComparison.OrdinalIgnoreCase)) + { + args = args.Skip(1).ToArray(); + WaitForDebugger(); + } + } + + private static void WaitForDebugger() + { + Console.WriteLine("Waiting for debugger to attach, or press Ctrl-C to terminate"); + Console.WriteLine($"Process ID: {Process.GetCurrentProcess().Id}"); + while (!Debugger.IsAttached) { } + } + } +} diff --git a/src/Microsoft.DotNet.Cli.Utils/project.json b/src/Microsoft.DotNet.Cli.Utils/project.json index 720be3507..f99a91d85 100644 --- a/src/Microsoft.DotNet.Cli.Utils/project.json +++ b/src/Microsoft.DotNet.Cli.Utils/project.json @@ -1,13 +1,15 @@ { - "version": "1.0.0-*", + "version": "1.0.0-*", - "shared": "**/*.cs", + "shared": "**/*.cs", - "dependencies": { - "System.Console": "4.0.0-*", - "System.Diagnostics.Process": "4.1.0-*" - }, - "frameworks": { - "dnxcore50": { } - } + "dependencies": { + "System.Console": "4.0.0-*", + "System.IO.FileSystem": "4.0.1-*", + "System.Diagnostics.Process": "4.1.0-*", + "System.Runtime.InteropServices.RuntimeInformation": "4.0.0-beta-*" + }, + "frameworks": { + "dnxcore50": { } + } } diff --git a/src/Microsoft.DotNet.Cli/Program.cs b/src/Microsoft.DotNet.Cli/Program.cs index dd231b45d..ef84b0eaa 100644 --- a/src/Microsoft.DotNet.Cli/Program.cs +++ b/src/Microsoft.DotNet.Cli/Program.cs @@ -1,4 +1,6 @@ using System; +using System.Diagnostics; +using System.IO; using System.Linq; using Microsoft.DotNet.Cli.Utils; diff --git a/src/Microsoft.DotNet.Cli/project.json b/src/Microsoft.DotNet.Cli/project.json index 74f974e52..0f310831a 100644 --- a/src/Microsoft.DotNet.Cli/project.json +++ b/src/Microsoft.DotNet.Cli/project.json @@ -1,22 +1,25 @@ { - "version": "1.0.0-*", - "compilationOptions": { - "emitEntryPoint": true - }, - "commands": { - "run": "Microsoft.DotNet.Cli" - }, - "dependencies": { - "System.Console": "4.0.0-*", - "System.Collections": "4.0.11-*", - "System.Linq": "4.0.1-*", - "System.Diagnostics.Process": "4.1.0-*", - "Microsoft.DotNet.Cli.Utils": { - "type": "build", - "version": "1.0.0-*" + "version": "1.0.0-*", + "compilationOptions": { + "emitEntryPoint": true + }, + "commands": { + "dotnet": "Microsoft.DotNet.Cli" + }, + "dependencies": { + "Microsoft.NETCore.ConsoleHost": "1.0.0-*", + "Microsoft.NETCore.Runtime": "1.0.1-*", + + "System.Console": "4.0.0-*", + "System.Collections": "4.0.11-*", + "System.Linq": "4.0.1-*", + "System.Diagnostics.Process": "4.1.0-*", + "Microsoft.DotNet.Cli.Utils": { + "type": "build", + "version": "1.0.0-*" + } + }, + "frameworks": { + "dnxcore50": { } } - }, - "frameworks": { - "dnxcore50": { } - } } \ No newline at end of file diff --git a/src/Microsoft.DotNet.Tools.Compiler/Program.cs b/src/Microsoft.DotNet.Tools.Compiler/Program.cs index 0058a46ea..a86dd6a60 100644 --- a/src/Microsoft.DotNet.Tools.Compiler/Program.cs +++ b/src/Microsoft.DotNet.Tools.Compiler/Program.cs @@ -1,8 +1,12 @@ using System; +using System.Collections.Generic; using System.IO; using System.Linq; using Microsoft.Dnx.Runtime.Common.CommandLine; using Microsoft.DotNet.Cli.Utils; +using Microsoft.Extensions.ProjectModel; +using Microsoft.Extensions.ProjectModel.Compilation; +using NuGet.Frameworks; namespace Microsoft.DotNet.Tools.Compiler { @@ -10,6 +14,8 @@ namespace Microsoft.DotNet.Tools.Compiler { public static int Main(string[] args) { + DebugHelper.HandleDebugSwitch(ref args); + var app = new CommandLineApplication(); app.Name = "dotnet compile"; app.FullName = ".NET Compiler"; @@ -17,32 +23,36 @@ namespace Microsoft.DotNet.Tools.Compiler app.HelpOption("-h|--help"); var output = app.Option("-o|--output ", "Directory in which to place outputs", CommandOptionType.SingleValue); - var framework = app.Option("-f|--framework ", "Target framework to compile for", CommandOptionType.SingleValue); + var framework = app.Option("-f|--framework ", "Compile a specific framework", CommandOptionType.MultipleValue); + var configuration = app.Option("-c|--configuration ", "Configuration under which to build", CommandOptionType.SingleValue); var project = app.Argument("", "The project to compile, defaults to the current directory. Can be a path to a project.json or a project directory"); app.OnExecute(() => { - // Validate arguments - CheckArg(framework, "--framework"); - // Locate the project and get the name and full path var path = project.Value; if (string.IsNullOrEmpty(path)) { path = Directory.GetCurrentDirectory(); } - if (!string.Equals(Path.GetFileName(path), "project.json", StringComparison.OrdinalIgnoreCase)) - { - path = Path.Combine(path, "project.json"); - } - if (!File.Exists(path)) - { - Console.Error.WriteLine($"Could not find project: {path}"); - return 1; - } - var dir = new FileInfo(path).Directory; - return Compile(path, framework.Value(), dir, output.Value()); + // Load project contexts for each framework and compile them + bool success = true; + if (framework.HasValue()) + { + foreach (var context in framework.Values.Select(f => ProjectContext.Create(path, NuGetFramework.Parse(f)))) + { + success &= Compile(context, configuration.Value() ?? Constants.DefaultConfiguration, output.Value()); + } + } + else + { + foreach (var context in ProjectContext.CreateContextForEachFramework(path)) + { + success &= Compile(context, configuration.Value() ?? Constants.DefaultConfiguration, output.Value()); + } + } + return success ? 0 : 1; }); try @@ -56,78 +66,138 @@ namespace Microsoft.DotNet.Tools.Compiler } } - private static void CheckArg(CommandOption argument, string name) + private static bool Compile(ProjectContext context, string configuration, string outputPath) { - if (!argument.HasValue()) - { - // TODO: GROOOOOOSS - throw new OperationCanceledException($"Missing required argument: {name}"); - } - } + Reporter.Output.WriteLine($"Building {context.RootProject.Identity.Name.Yellow()} for {context.TargetFramework.DotNetFrameworkName.Yellow()}"); - private static int Compile(string path, string framework, DirectoryInfo projectDir, string outputPath) - { - // Make output directory - // TODO(anurse): per-framework and per-configuration output dir - // TODO(anurse): configurable base output dir? (maybe dotnet compile doesn't support that?) + // Create the library exporter + var exporter = context.CreateExporter(configuration); + + // Gather exports for the project + var dependencies = exporter.GetCompilationDependencies().ToList(); + + // Hackily trigger builds of the dependent projects + foreach (var dependency in dependencies.Where(d => d.CompilationAssemblies.Any())) + { + var projectDependency = dependency.Library as ProjectDescription; + if (projectDependency != null && !string.Equals(projectDependency.Identity.Name, context.RootProject.Identity.Name, StringComparison.Ordinal)) + { + var compileResult = Command.Create("dotnet-compile", $"--framework \"{projectDependency.Framework}\" --configuration \"{configuration}\" {projectDependency.Project.ProjectDirectory}") + .ForwardStdOut() + .ForwardStdErr() + .RunAsync() + .Result; + if (compileResult.ExitCode != 0) + { + Console.Error.WriteLine($"Failed to compile dependency: {projectDependency.Identity.Name}"); + return false; + } + } + } + + // Dump dependency data + ShowDependencyInfo(dependencies); + + // Hackily generate the output path if (string.IsNullOrEmpty(outputPath)) { - outputPath = Path.Combine(projectDir.FullName, "bin"); + outputPath = Path.Combine( + context.Project.ProjectDirectory, + "bin", + configuration, + context.TargetFramework.GetTwoDigitShortFolderName()); } - if (!Directory.Exists(outputPath)) { Directory.CreateDirectory(outputPath); } - // Resolve compilation references - var result = Command.Create("dotnet-resolve-references", $"--framework {framework} --assets compile {path}") - .CaptureStdOut() - .ForwardStdErr(Console.Error) - .RunAsync() - .Result; - if(result.ExitCode != 0) - { - Console.Error.WriteLine("Failed to resolve references"); - return result.ExitCode; - } - var references = result.StdOut.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); + // Get compilation options + var compilationOptions = context.Project.GetCompilerOptions(context.TargetFramework, configuration); + var outputName = Path.Combine(outputPath, context.Project.Name + ".dll"); - // Resolve source files - result = Command.Create("dotnet-resolve-sources", $"{path}") - .CaptureStdOut() - .ForwardStdErr(Console.Error) - .RunAsync() - .Result; - if(result.ExitCode != 0) + // Assemble csc args + var cscArgs = new List() { - Console.Error.WriteLine("Failed to resolve sources"); - return result.ExitCode; - } - var sources = result.StdOut.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); + "-nostdlib", + "-nologo", + $"-out:{outputName}" + }; - // Build csc args - var cscArgs = new[] - { - "-nostdlib", - $"-out:{Path.Combine(outputPath, projectDir.Name + ".dll")}" - } - .Concat(references.Select(r => $"-r:{r}")) - .Concat(sources); + // Add compilation options to the args + ApplyCompilationOptions(compilationOptions, cscArgs); + + foreach (var dependency in dependencies) + { + cscArgs.AddRange(dependency.CompilationAssemblies.Select(r => $"-r:{r}")); + cscArgs.AddRange(dependency.SourceReferences); + } + + // Add project source files + cscArgs.AddRange(context.Project.Files.SourceFiles); + + // Write RSP file var rsp = Path.Combine(outputPath, "csc.rsp"); - if(File.Exists(rsp)) - { - File.Delete(rsp); - } File.WriteAllLines(rsp, cscArgs); - // Run csc - return Command.Create("csc", $"@{rsp}") - .ForwardStdErr(Console.Error) - .ForwardStdOut(Console.Out) + // Execute CSC! + var result = Command.Create("csc", $"-noconfig @{rsp}") + .ForwardStdErr() + .ForwardStdOut() .RunAsync() - .Result - .ExitCode; + .Result; + return result.ExitCode == 0; + } + + private static void ApplyCompilationOptions(CompilerOptions compilationOptions, List cscArgs) + { + var targetType = (compilationOptions.EmitEntryPoint ?? false) ? "exe" : "library"; + cscArgs.Add($"-target:{targetType}"); + if (compilationOptions.AllowUnsafe == true) + { + cscArgs.Add("-unsafe+"); + } + cscArgs.AddRange(compilationOptions.Defines.Select(d => $"-d:{d}")); + if (compilationOptions.Optimize == true) + { + cscArgs.Add("-optimize"); + } + if (!string.IsNullOrEmpty(compilationOptions.Platform)) + { + cscArgs.Add($"-platform:{compilationOptions.Platform}"); + } + if (compilationOptions.WarningsAsErrors == true) + { + cscArgs.Add("-warnaserror"); + } + } + + private static void ShowDependencyInfo(IEnumerable dependencies) + { + foreach (var dependency in dependencies) + { + if (!dependency.Library.Resolved) + { + Reporter.Error.WriteLine($" Unable to resolve dependency {dependency.Library.Identity.ToString().Red().Bold()}"); + Reporter.Error.WriteLine(""); + } + else + { + Reporter.Output.WriteLine($" Using {dependency.Library.Identity.Type.Value.Cyan().Bold()} dependency {dependency.Library.Identity.ToString().Cyan().Bold()}"); + Reporter.Output.WriteLine($" Path: {dependency.Library.Path}"); + + foreach (var metadataReference in dependency.CompilationAssemblies) + { + Reporter.Output.WriteLine($" Assembly: {metadataReference}"); + } + + foreach (var sourceReference in dependency.SourceReferences) + { + Reporter.Output.WriteLine($" Source: {sourceReference}"); + } + Reporter.Output.WriteLine(""); + } + } } } } diff --git a/src/Microsoft.DotNet.Tools.Compiler/Reporter.cs b/src/Microsoft.DotNet.Tools.Compiler/Reporter.cs new file mode 100644 index 000000000..f09de206f --- /dev/null +++ b/src/Microsoft.DotNet.Tools.Compiler/Reporter.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +using Microsoft.Dnx.Runtime.Common.CommandLine; + +namespace Microsoft.DotNet.Cli.Utils +{ + // Stupid-simple console manager + internal static class Reporter + { + public static AnsiConsole Output { get; } = AnsiConsole.GetOutput(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + public static AnsiConsole Error { get; } = AnsiConsole.GetError(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + } +} diff --git a/src/Microsoft.DotNet.Tools.Compiler/project.json b/src/Microsoft.DotNet.Tools.Compiler/project.json index 1f414115c..29cdb86e7 100644 --- a/src/Microsoft.DotNet.Tools.Compiler/project.json +++ b/src/Microsoft.DotNet.Tools.Compiler/project.json @@ -1,27 +1,31 @@ { - "version": "1.0.0-*", - "compilationOptions": { - "emitEntryPoint": true - }, - "commands": { - "dotnet-compile": "Microsoft.DotNet.Cli" - }, - "dependencies": { - "System.Console": "4.0.0-*", - "System.Collections": "4.0.11-*", - "System.Linq": "4.0.1-*", - "System.Diagnostics.Process": "4.1.0-*", - "System.IO.FileSystem": "4.0.1-*", - "Microsoft.DotNet.Cli.Utils": { - "type": "build", - "version": "1.0.0-*" + "version": "1.0.0-*", + "compilationOptions": { + "emitEntryPoint": true }, - "Microsoft.Framework.CommandLineUtils.Sources": { - "type": "build", - "version": "1.0.0-*" + "commands": { + "dotnet-compile": "Microsoft.DotNet.Tools.Compiler" + }, + "dependencies": { + "Microsoft.NETCore.ConsoleHost": "1.0.0-*", + "Microsoft.NETCore.Runtime": "1.0.1-*", + + "System.Console": "4.0.0-*", + "System.Collections": "4.0.11-*", + "System.Linq": "4.0.1-*", + "System.Diagnostics.Process": "4.1.0-*", + "System.IO.FileSystem": "4.0.1-*", + "Microsoft.Extensions.ProjectModel": "1.0.0-*", + "Microsoft.DotNet.Cli.Utils": { + "type": "build", + "version": "1.0.0-*" + }, + "Microsoft.Extensions.CommandLineUtils.Sources": { + "type": "build", + "version": "1.0.0-*" + } + }, + "frameworks": { + "dnxcore50": { } } - }, - "frameworks": { - "dnxcore50": { } - } } diff --git a/src/Microsoft.DotNet.Tools.DependencyResolver/Microsoft.DotNet.Tools.DependencyResolver.xproj b/src/Microsoft.DotNet.Tools.DependencyResolver/Microsoft.DotNet.Tools.DependencyResolver.xproj deleted file mode 100644 index a4e69355f..000000000 --- a/src/Microsoft.DotNet.Tools.DependencyResolver/Microsoft.DotNet.Tools.DependencyResolver.xproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - 4298df4a-e04c-4ed9-95f8-fbb7cb32721f - Microsoft.DotNet.Tools.DependencyResolver - ..\..\artifacts\obj\$(MSBuildProjectName) - ..\..\artifacts\bin\$(MSBuildProjectName)\ - - - - 2.0 - - - \ No newline at end of file diff --git a/src/Microsoft.DotNet.Tools.DependencyResolver/Program.cs b/src/Microsoft.DotNet.Tools.DependencyResolver/Program.cs deleted file mode 100644 index 093b60d5a..000000000 --- a/src/Microsoft.DotNet.Tools.DependencyResolver/Program.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using Microsoft.Dnx.Runtime.Common.CommandLine; -using NuGet.Frameworks; - -namespace Microsoft.DotNet.Tools.DependencyResolver -{ - public class Program - { - public void Main(string[] args) - { - var app = new CommandLineApplication(); - app.Name = "dotnet resolve-references"; - app.Description = "Resolves the absolute path of all dependencies for a project"; - app.HelpOption("-h|--help"); - - var packages = app.Option("-p|--packages ", "Path to the directories containing packages to resolve.", CommandOptionType.MultipleValue); - var framework = app.Option("-f|--framework ", "The framework to resolve dependencies for.", CommandOptionType.SingleValue); - var runtime = app.Option("-r|--runtime ", "The runtime to resolve dependencies for.", CommandOptionType.SingleValue); - var output = app.Option("-o|--output ", "The path in which to write the output file (formatted as text with one line per dependency)", CommandOptionType.SingleValue); - var assetType = app.Option("-a|--assets ", "The type of assets to resolve (common values include: compile, runtime, native)", CommandOptionType.MultipleValue); - var project = app.Argument("PROJECT", "The project to resolve. A directory or a path to a project.lock.json may be used. Defaults to the current directory"); - - app.OnExecute(() => - { - // Check required args - if (!framework.HasValue()) - { - Console.Error.WriteLine("Missing required argument: --framework"); - app.ShowHelp(); - return 1; - } - if (!assetType.HasValue()) - { - Console.Error.WriteLine("Missing required argument: --assets"); - app.ShowHelp(); - return 1; - } - - // Build target name - var fx = NuGetFramework.Parse(framework.Value()); - var target = fx.DotNetFrameworkName; - if (runtime.HasValue()) - { - target += "/" + runtime.Value(); - } - Console.Error.WriteLine($"Using lock file target: {target}"); - - // Determine packages folder - var packagesDirs = packages.Values; - if (!packagesDirs.Any()) - { - var defaultDir = GetDefaultPackagesFolder(); - if (string.IsNullOrEmpty(defaultDir)) - { - Console.Error.WriteLine("Unable to locate packages directory! Try using --packages to specify it manually."); - app.ShowHelp(); - return 1; - } - packagesDirs.Add(defaultDir); - } - foreach (var packagesDir in packagesDirs) - { - Console.Error.WriteLine($"Using packages directory: {packagesDir}"); - } - - var path = project.Value ?? Directory.GetCurrentDirectory(); - if (path.EndsWith("project.json")) - { - path = Path.Combine(Path.GetDirectoryName(path), "project.lock.json"); - } - else if (!path.EndsWith("project.lock.json")) - { - path = Path.Combine(path, "project.lock.json"); - } - return Resolver.Execute(packagesDirs, target, output.Value(), assetType.Values, path); - }); - - app.Execute(args); - } - - private string GetDefaultPackagesFolder() - { - // TODO: Read DNX_PACKAGES (or equivalent)? - // TODO: Read global.json - string userProfile = Environment.GetEnvironmentVariable("USERPROFILE"); - if (string.IsNullOrEmpty(userProfile)) - { - userProfile = Environment.GetEnvironmentVariable("HOME"); - } - if (string.IsNullOrEmpty(userProfile)) - { - return null; - } - - // TODO: Use NuGet folder, and AppData on Windows. - return Path.Combine(userProfile, ".dnx", "packages"); - } - } -} diff --git a/src/Microsoft.DotNet.Tools.DependencyResolver/Resolver.cs b/src/Microsoft.DotNet.Tools.DependencyResolver/Resolver.cs deleted file mode 100644 index cf51c8175..000000000 --- a/src/Microsoft.DotNet.Tools.DependencyResolver/Resolver.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using Newtonsoft.Json.Linq; - -namespace Microsoft.DotNet.Tools.DependencyResolver -{ - public static class Resolver - { - public static int Execute(IEnumerable packageDirectories, string targetName, string output, IEnumerable assetTypes, string lockFilePath) - { - // Open the lock file - var lockFile = JObject.Parse(File.ReadAllText(lockFilePath)); - - // Locate the target - var target = lockFile["targets"][targetName] as JObject; - if (target == null) - { - Console.Error.WriteLine($"Could not find target in lock file: {target}"); - return 1; - } - - // Iterate over each package and prepare the dependency data - bool success = true; - List files = new List(); - foreach (var dependency in target) - { - // Parse the input string - var splat = dependency.Key.Split('/'); - var id = splat[0]; - var version = splat[1]; - - string packageRoot = null; - foreach (var dir in packageDirectories) - { - var candidate = Path.Combine(dir, id, version); - if (Directory.Exists(candidate)) - { - packageRoot = candidate; - break; - } - } - - if (packageRoot == null) - { - Console.Error.WriteLine($"WARNING: Unable to locate {id} {version}"); - success = false; - } - - // Locate all the assets - foreach (var assetType in assetTypes) - { - var assetList = dependency.Value[assetType] as JObject; - if (assetList != null) - { - foreach (var asset in assetList) - { - var pathified = Path.Combine(asset.Key.Split('/')); - if (!Path.GetFileName(pathified).Equals("_._", StringComparison.Ordinal)) - { - var file = Path.Combine(packageRoot, pathified); - if (!File.Exists(file)) - { - Console.Error.WriteLine($"WARNING: Missing asset: {file}"); - success = false; - } - files.Add(file); - Console.WriteLine(file); - } - } - } - } - } - - if (!string.IsNullOrEmpty(output)) - { - File.WriteAllLines(output, files); - } - - return success ? 0 : 1; - } - } -} \ No newline at end of file diff --git a/src/Microsoft.DotNet.Tools.DependencyResolver/project.json b/src/Microsoft.DotNet.Tools.DependencyResolver/project.json deleted file mode 100644 index 257496ff9..000000000 --- a/src/Microsoft.DotNet.Tools.DependencyResolver/project.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "version": "1.0.0-*", - - "dependencies": { - "System.Collections": "4.0.10-beta-*", - "System.Console": "4.0.0-beta-*", - "System.Linq": "4.0.0-beta-*", - "System.Threading": "4.0.10-beta-*", - "System.IO.FileSystem": "4.0.1-beta-*", - - "Microsoft.CSharp": "4.0.0-beta-23109", - "Microsoft.Framework.CommandLineUtils.Sources": "1.0.0-*", - - "NuGet.Frameworks": "3.2.0", - - "Newtonsoft.Json": "7.0.1" - }, - - "commands": { - "dotnet-resolve-dependencies": "" - }, - - "frameworks": { - "dnxcore50": { } - } -} diff --git a/src/Microsoft.DotNet.Tools.Publish/Program.cs b/src/Microsoft.DotNet.Tools.Publish/Program.cs index da9bb1fc8..b7e749815 100644 --- a/src/Microsoft.DotNet.Tools.Publish/Program.cs +++ b/src/Microsoft.DotNet.Tools.Publish/Program.cs @@ -1,7 +1,11 @@ using System; +using System.Collections.Generic; using System.IO; +using System.Linq; using Microsoft.Dnx.Runtime.Common.CommandLine; using Microsoft.DotNet.Cli.Utils; +using Microsoft.Extensions.ProjectModel; +using NuGet.Frameworks; namespace Microsoft.DotNet.Tools.Publish { @@ -9,23 +13,24 @@ namespace Microsoft.DotNet.Tools.Publish { public static int Main(string[] args) { + DebugHelper.HandleDebugSwitch(ref args); + var app = new CommandLineApplication(); app.Name = "dotnet publish"; app.FullName = ".NET Publisher"; app.Description = "Publisher for the .NET Platform"; app.HelpOption("-h|--help"); - var verbose = app.Option("-v|--verbose", "Be more verbose", CommandOptionType.NoValue); var framework = app.Option("-f|--framework ", "Target framework to compile for", CommandOptionType.SingleValue); var runtime = app.Option("-r|--runtime ", "Target runtime to publish for", CommandOptionType.SingleValue); var output = app.Option("-o|--output ", "Path in which to publish the app", CommandOptionType.SingleValue); - var project = app.Argument("", "The project to compile, defaults to the current directory. Can be a path to a project.json or a project directory"); + var configuration = app.Option("-c|--configuration ", "Configuration under which to build", CommandOptionType.SingleValue); + var project = app.Argument("", "The project to publish, defaults to the current directory. Can be a path to a project.json or a project directory"); app.OnExecute(() => { - // Validate arguments - CheckArg(framework, "--framework"); - CheckArg(runtime, "--runtime"); + CheckArg(framework); + CheckArg(runtime); // Locate the project and get the name and full path var path = project.Value; @@ -33,18 +38,10 @@ namespace Microsoft.DotNet.Tools.Publish { path = Directory.GetCurrentDirectory(); } - if (!string.Equals(Path.GetFileName(path), "project.json", StringComparison.OrdinalIgnoreCase)) - { - path = Path.Combine(path, "project.json"); - } - if (!File.Exists(path)) - { - Console.Error.WriteLine($"Could not find project: {path}"); - return 1; - } - var dir = new FileInfo(path).Directory; - return Publish(path, framework.Value(), runtime.Value(), dir, output.Value()); + // Load project context and publish it + var context = ProjectContext.Create(path, NuGetFramework.Parse(framework.Value()), new[] { runtime.Value() }); + return Publish(context, output.Value(), configuration.Value() ?? Constants.DefaultConfiguration); }); try @@ -58,32 +55,36 @@ namespace Microsoft.DotNet.Tools.Publish } } - private static void CheckArg(CommandOption argument, string name) + private static void CheckArg(CommandOption argument) { if (!argument.HasValue()) { // TODO: GROOOOOOSS - throw new OperationCanceledException($"Missing required argument: {name}"); + throw new OperationCanceledException($"Missing required argument: {argument.LongName}"); } } - private static int Publish(string path, string framework, string runtime, DirectoryInfo projectDir, string outputPath) + private static int Publish(ProjectContext context, string outputPath, string configuration) { - // Make output directory - // TODO(anurse): per-framework and per-configuration output dir - // TODO(anurse): configurable base output dir? (maybe dotnet compile doesn't support that?) + Reporter.Output.WriteLine($"Publishing {context.RootProject.Identity.Name.Yellow()} for {context.TargetFramework.DotNetFrameworkName.Yellow()}/{context.RuntimeIdentifier}"); + + // Hackily generate the output path if (string.IsNullOrEmpty(outputPath)) { - outputPath = Path.Combine(projectDir.FullName, "bin", "publish"); + outputPath = Path.Combine( + context.Project.ProjectDirectory, + "bin", + configuration, + context.TargetFramework.GetTwoDigitShortFolderName(), + "publish"); } - if (!Directory.Exists(outputPath)) { Directory.CreateDirectory(outputPath); } - // Compile the project - var result = Command.Create("dotnet-compile", $"--framework {framework} --output {outputPath} {path}") + // Compile the project (and transitively, all it's dependencies) + var result = Command.Create("dotnet-compile", $"--framework {context.TargetFramework.DotNetFrameworkName} {context.Project.ProjectDirectory}") .ForwardStdErr() .ForwardStdOut() .RunAsync() @@ -94,26 +95,18 @@ namespace Microsoft.DotNet.Tools.Publish return result.ExitCode; } - // Collect the things needed to publish - result = Command.Create("dotnet-resolve-references", $"--framework {framework} --runtime {runtime} --assets runtime --assets native {path}") - .CaptureStdOut() - .ForwardStdErr(Console.Error) - .RunAsync() - .Result; - if (result.ExitCode != 0) + // Use a library exporter to collect publish assets + var exporter = context.CreateExporter(configuration); + foreach (var export in exporter.GetAllExports()) { - Console.Error.WriteLine("Failed to resolve references"); - return result.ExitCode; - } - var references = result.StdOut.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); + Reporter.Output.WriteLine($"Publishing {export.Library.Identity.ToString().Green().Bold()} ..."); - // Copy everything to the output - foreach (var reference in references) - { - Console.Error.WriteLine($"Publishing {reference} ..."); - File.Copy(reference, Path.Combine(outputPath, Path.GetFileName(reference)), overwrite: true); + PublishFiles(export.RuntimeAssemblies, outputPath); + PublishFiles(export.NativeLibraries, outputPath); } + // Publishing for windows, TODO(anurse): Publish for Mac/Linux/etc. + // CoreConsole should be there... var coreConsole = Path.Combine(outputPath, Constants.CoreConsoleName); if (!File.Exists(coreConsole)) @@ -121,14 +114,42 @@ namespace Microsoft.DotNet.Tools.Publish Console.Error.WriteLine($"Unable to find {Constants.CoreConsoleName} at {coreConsole}. You must have an explicit dependency on Microsoft.NETCore.ConsoleHost (for now ;))"); return 1; } - var outputExe = Path.Combine(outputPath, projectDir.Name + Constants.ExeSuffix); + + // Use the 'command' field to generate the name + var outputExe = Path.Combine(outputPath, context.Project.Name + ".exe"); if (File.Exists(outputExe)) { File.Delete(outputExe); } File.Move(coreConsole, outputExe); + + // Check if the a command name is specified, and rename the necessary files + if(context.Project.Commands.Count == 1) + { + var commandName = context.Project.Commands.Single().Key; + + // Move coreconsole and the matching dll + var renamedExe = Path.Combine(outputPath, commandName + ".exe"); + var renamedDll = Path.ChangeExtension(renamedExe, ".dll"); + if(File.Exists(renamedExe)) + { + File.Delete(renamedExe); + } + File.Move(outputExe, renamedExe); + File.Move(Path.ChangeExtension(outputExe, ".dll"), renamedDll); + outputExe = Path.Combine(outputPath, commandName + ".exe"); + } + Console.Error.WriteLine($"Published to {outputExe}"); return 0; } + + private static void PublishFiles(IEnumerable files, string outputPath) + { + foreach (var file in files) + { + File.Copy(file, Path.Combine(outputPath, Path.GetFileName(file)), overwrite: true); + } + } } } diff --git a/src/Microsoft.DotNet.Tools.Publish/Reporter.cs b/src/Microsoft.DotNet.Tools.Publish/Reporter.cs new file mode 100644 index 000000000..f09de206f --- /dev/null +++ b/src/Microsoft.DotNet.Tools.Publish/Reporter.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +using Microsoft.Dnx.Runtime.Common.CommandLine; + +namespace Microsoft.DotNet.Cli.Utils +{ + // Stupid-simple console manager + internal static class Reporter + { + public static AnsiConsole Output { get; } = AnsiConsole.GetOutput(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + public static AnsiConsole Error { get; } = AnsiConsole.GetError(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + } +} diff --git a/src/Microsoft.DotNet.Tools.Publish/project.json b/src/Microsoft.DotNet.Tools.Publish/project.json index 1f414115c..bf4a36d8c 100644 --- a/src/Microsoft.DotNet.Tools.Publish/project.json +++ b/src/Microsoft.DotNet.Tools.Publish/project.json @@ -1,27 +1,31 @@ { - "version": "1.0.0-*", - "compilationOptions": { - "emitEntryPoint": true - }, - "commands": { - "dotnet-compile": "Microsoft.DotNet.Cli" - }, - "dependencies": { - "System.Console": "4.0.0-*", - "System.Collections": "4.0.11-*", - "System.Linq": "4.0.1-*", - "System.Diagnostics.Process": "4.1.0-*", - "System.IO.FileSystem": "4.0.1-*", - "Microsoft.DotNet.Cli.Utils": { - "type": "build", - "version": "1.0.0-*" + "version": "1.0.0-*", + "compilationOptions": { + "emitEntryPoint": true }, - "Microsoft.Framework.CommandLineUtils.Sources": { - "type": "build", - "version": "1.0.0-*" + "commands": { + "dotnet-publish": "Microsoft.DotNet.Tools.Publish" + }, + "dependencies": { + "Microsoft.NETCore.ConsoleHost": "1.0.0-*", + "Microsoft.NETCore.Runtime": "1.0.1-*", + + "System.Console": "4.0.0-*", + "System.Collections": "4.0.11-*", + "System.Linq": "4.0.1-*", + "System.Diagnostics.Process": "4.1.0-*", + "System.IO.FileSystem": "4.0.1-*", + "Microsoft.Extensions.ProjectModel": "1.0.0-*", + "Microsoft.DotNet.Cli.Utils": { + "type": "build", + "version": "1.0.0-*" + }, + "Microsoft.Framework.CommandLineUtils.Sources": { + "type": "build", + "version": "1.0.0-*" + } + }, + "frameworks": { + "dnxcore50": { } } - }, - "frameworks": { - "dnxcore50": { } - } } diff --git a/src/Microsoft.DotNet.Tools.Run/Program.cs b/src/Microsoft.DotNet.Tools.Run/Program.cs deleted file mode 100644 index 484dc9504..000000000 --- a/src/Microsoft.DotNet.Tools.Run/Program.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using Microsoft.Dnx.Runtime.Common.CommandLine; -using Microsoft.DotNet.Cli.Utils; - -namespace Microsoft.DotNet.Tools.Run -{ - public class Program - { - public static int Main(string[] args) - { - var app = new CommandLineApplication(throwOnUnexpectedArg: false); - app.Name = "dotnet run"; - app.FullName = ".NET Executer"; - app.Description = "Executer for the .NET Platform"; - app.HelpOption("-h|--help"); - - var framework = app.Option("-f|--framework ", "Target framework to compile for", CommandOptionType.SingleValue); - var runtime = app.Option("-r|--runtime ", "Target runtime on which to run", CommandOptionType.SingleValue); - var output = app.Option("-o|--output ", "Directory in which to compile the application", CommandOptionType.SingleValue); - var project = app.Argument("", "The project to compile, defaults to the current directory. Can be a path to a project.json or a project directory"); - - app.OnExecute(() => - { - // Validate arguments - CheckArg(framework, "--framework"); - CheckArg(runtime, "--runtime"); - - // Locate the project and get the name and full path - var path = project.Value; - if (string.IsNullOrEmpty(path)) - { - path = Directory.GetCurrentDirectory(); - } - if (!string.Equals(Path.GetFileName(path), "project.json", StringComparison.OrdinalIgnoreCase)) - { - path = Path.Combine(path, "project.json"); - } - if (!File.Exists(path)) - { - Console.Error.WriteLine($"Could not find project: {path}"); - return 1; - } - var dir = new FileInfo(path).Directory; - - return Run(path, framework.Value(), runtime.Value(), dir, output.Value(), app.RemainingArguments); - }); - - try - { - return app.Execute(args); - } - catch (OperationCanceledException ex) - { - Console.Error.WriteLine(ex.Message); - return 1; - } - } - - private static void CheckArg(CommandOption argument, string name) - { - if (!argument.HasValue()) - { - // TODO: GROOOOOOSS - throw new OperationCanceledException($"Missing required argument: {name}"); - } - } - - private static int Run(string path, string framework, string runtime, DirectoryInfo projectDir, string outputPath, IEnumerable remainingArgs) - { - // Make output directory - // TODO(anurse): per-framework and per-configuration output dir - // TODO(anurse): configurable base output dir? (maybe dotnet compile doesn't support that?) - if (string.IsNullOrEmpty(outputPath)) - { - outputPath = Path.Combine(projectDir.FullName, "bin", "publish"); - } - - if (!Directory.Exists(outputPath)) - { - Directory.CreateDirectory(outputPath); - } - - // Publish the app - var result = Command.Create("dotnet-publish", $"--framework {framework} --runtime {runtime} --output {outputPath} {path}") - .ForwardStdErr() - .ForwardStdOut() - .RunAsync() - .Result; - if(result.ExitCode != 0) - { - Console.Error.WriteLine("Error publishing app"); - return result.ExitCode; - } - - // Run the output! - var output = Path.Combine(outputPath, projectDir.Name + Constants.ExeSuffix); - if(!File.Exists(output)) - { - Console.Error.WriteLine($"Could not find output: {output}"); - return 1; - } - return Command.Create(output, remainingArgs) - .ForwardStdErr() - .ForwardStdOut() - .RunAsync() - .Result - .ExitCode; - } - } -} diff --git a/src/Microsoft.DotNet.Tools.Run/project.json b/src/Microsoft.DotNet.Tools.Run/project.json deleted file mode 100644 index 1f414115c..000000000 --- a/src/Microsoft.DotNet.Tools.Run/project.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "version": "1.0.0-*", - "compilationOptions": { - "emitEntryPoint": true - }, - "commands": { - "dotnet-compile": "Microsoft.DotNet.Cli" - }, - "dependencies": { - "System.Console": "4.0.0-*", - "System.Collections": "4.0.11-*", - "System.Linq": "4.0.1-*", - "System.Diagnostics.Process": "4.1.0-*", - "System.IO.FileSystem": "4.0.1-*", - "Microsoft.DotNet.Cli.Utils": { - "type": "build", - "version": "1.0.0-*" - }, - "Microsoft.Framework.CommandLineUtils.Sources": { - "type": "build", - "version": "1.0.0-*" - } - }, - "frameworks": { - "dnxcore50": { } - } -} diff --git a/src/Microsoft.DotNet.Tools.SourceResolver/Microsoft.DotNet.Tools.SourceResolver.xproj b/src/Microsoft.DotNet.Tools.SourceResolver/Microsoft.DotNet.Tools.SourceResolver.xproj deleted file mode 100644 index eae696faf..000000000 --- a/src/Microsoft.DotNet.Tools.SourceResolver/Microsoft.DotNet.Tools.SourceResolver.xproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - 7108e4fb-e2f1-4682-8464-1dd6efb17035 - Microsoft.DotNet.Tools.SourceResolver - ..\..\artifacts\obj\$(MSBuildProjectName) - ..\..\artifacts\bin\$(MSBuildProjectName)\ - - - - 2.0 - - - \ No newline at end of file diff --git a/src/Microsoft.DotNet.Tools.SourceResolver/Program.cs b/src/Microsoft.DotNet.Tools.SourceResolver/Program.cs deleted file mode 100644 index a5b21de10..000000000 --- a/src/Microsoft.DotNet.Tools.SourceResolver/Program.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.IO; -using Microsoft.Dnx.Runtime.Common.CommandLine; - -namespace Microsoft.DotNet.Tools.SourceResolver -{ - public class Program - { - public void Main(string[] args) - { - var app = new CommandLineApplication(); - app.Name = "dotnet resolve-sources"; - app.Description = "Resolves the absolute path of all source files used by a project"; - app.HelpOption("-h|--help"); - - var output = app.Option("-o|--output ", "The path in which to write the output file (formatted as text with one line per dependency)", CommandOptionType.SingleValue); - var project = app.Argument("PROJECT", "The project to resolve. A directory or a path to a project.json may be used. Defaults to the current directory"); - - app.OnExecute(() => - { - var path = project.Value ?? Directory.GetCurrentDirectory(); - if (!path.EndsWith("project.json")) - { - path = Path.Combine(path, "project.json"); - } - return Resolver.Execute(path, output.Value()); - }); - - app.Execute(args); - } - } -} diff --git a/src/Microsoft.DotNet.Tools.SourceResolver/Resolver.cs b/src/Microsoft.DotNet.Tools.SourceResolver/Resolver.cs deleted file mode 100644 index 02351c227..000000000 --- a/src/Microsoft.DotNet.Tools.SourceResolver/Resolver.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using Microsoft.Dnx.Runtime; - -namespace Microsoft.DotNet.Tools.SourceResolver -{ - public static class Resolver - { - public static int Execute(string projectPath, string output) - { - var projectFile = new FileInfo(projectPath); - var reader = new ProjectReader(); - var diagnostics = new List(); - Project project; - using (var stream = File.OpenRead(projectPath)) - { - project = reader.ReadProject( - stream, - projectFile.Directory.Name, - projectFile.FullName, - diagnostics); - } - - foreach (var diagnostic in diagnostics) - { - WriteDiagnostic(diagnostic); - } - - if (diagnostics.HasErrors()) - { - return 1; - } - - foreach (var file in project.Files.SourceFiles) - { - Console.WriteLine(file); - } - - if (!string.IsNullOrEmpty(output)) - { - File.WriteAllLines(output, project.Files.SourceFiles); - } - - return 0; - } - - private static void WriteDiagnostic(DiagnosticMessage diagnostic) - { - Console.Error.WriteLine($"{diagnostic.Severity}: {diagnostic.FormattedMessage}"); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.DotNet.Tools.SourceResolver/project.json b/src/Microsoft.DotNet.Tools.SourceResolver/project.json deleted file mode 100644 index 10cbde1f7..000000000 --- a/src/Microsoft.DotNet.Tools.SourceResolver/project.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "version": "1.0.0-*", - - "dependencies": { - "System.Collections": "4.0.10-beta-*", - "System.Console": "4.0.0-beta-*", - "System.Linq": "4.0.0-beta-*", - "System.Threading": "4.0.10-beta-*", - "System.IO.FileSystem": "4.0.1-beta-*", - - "Microsoft.CSharp": "4.0.0-beta-23109", - "Microsoft.Framework.CommandLineUtils.Sources": "1.0.0-*", - "Microsoft.Dnx.Runtime": "1.0.0-*", - - "Newtonsoft.Json": "7.0.1" - }, - - "commands": { - "dotnet-resolve-dependencies": "" - }, - - "frameworks": { - "dnxcore50": { } - } -} diff --git a/src/Microsoft.Extensions.ProjectModel/Compilation/LibraryExport.cs b/src/Microsoft.Extensions.ProjectModel/Compilation/LibraryExport.cs new file mode 100644 index 000000000..0ae09796d --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Compilation/LibraryExport.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.Extensions.ProjectModel.Compilation +{ + public class LibraryExport + { + /// + /// Gets the library that produced this export + /// + public LibraryDescription Library { get; } + + /// + /// Gets a list of fully-qualified paths to MSIL binaries required to run + /// + public IEnumerable RuntimeAssemblies { get; } + + /// + /// Gets a list of fully-qualified paths to native binaries required to run + /// + public IEnumerable NativeLibraries { get; } + + /// + /// Gets a list of fully-qualified paths to MSIL metadata references + /// + public IEnumerable CompilationAssemblies { get; } + + /// + /// Gets a list of fully-qualified paths to source code file references + /// + public IEnumerable SourceReferences { get; } + + public LibraryExport(LibraryDescription library, IEnumerable compileAssemblies, IEnumerable sourceReferences, IEnumerable runtimeAssemblies, IEnumerable nativeLibraries) + { + Library = library; + CompilationAssemblies = compileAssemblies; + SourceReferences = sourceReferences; + RuntimeAssemblies = runtimeAssemblies; + NativeLibraries = nativeLibraries; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/Compilation/LibraryExporter.cs b/src/Microsoft.Extensions.ProjectModel/Compilation/LibraryExporter.cs new file mode 100644 index 000000000..1206a34af --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Compilation/LibraryExporter.cs @@ -0,0 +1,257 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using Microsoft.Extensions.ProjectModel.Graph; +using Microsoft.Extensions.ProjectModel.Resolution; +using Microsoft.Extensions.ProjectModel.Utilities; +using NuGet.Frameworks; + +namespace Microsoft.Extensions.ProjectModel.Compilation +{ + public class LibraryExporter + { + private readonly string _configuration; + private readonly ProjectDescription _rootProject; + + public LibraryExporter(ProjectDescription rootProject, LibraryManager manager, string configuration) + { + if (string.IsNullOrEmpty(configuration)) + { + throw new ArgumentNullException(nameof(configuration)); + } + + LibraryManager = manager; + _configuration = configuration; + _rootProject = rootProject; + } + + public LibraryManager LibraryManager { get; } + + public IEnumerable GetAllExports() + { + // Export all but the main project + return ExportLibraries(_ => true); + } + + public IEnumerable GetCompilationDependencies() + { + // Export all but the main project + return ExportLibraries(l => !string.Equals(l.Identity.Name, _rootProject.Identity.Name, StringComparison.OrdinalIgnoreCase)); + } + + /// + /// Retrieves a list of objects representing the assets + /// required from other libraries to compile this project. + /// + private IEnumerable ExportLibraries(Func condition) + { + var seenMetadataReferences = new HashSet(); + var seenRuntimeReferences = new HashSet(); + + // Iterate over libraries in the library manager + foreach (var library in LibraryManager.GetLibraries()) + { + if(!condition(library)) + { + continue; + } + + var compilationAssemblies = new List(); + var sourceReferences = new List(); + + var libraryExport = GetExport(library); + + if (libraryExport != null) + { + // We need to filter out source references from non-root libraries, + // so we rebuild the library export + foreach (var reference in libraryExport.CompilationAssemblies) + { + if (seenMetadataReferences.Add(Path.GetFileNameWithoutExtension(reference))) + { + compilationAssemblies.Add(reference); + } + } + + if (library.Parent != null && Equals(library.Parent.Identity, _rootProject.Identity)) + { + // Only process source references for direct dependencies + foreach (var sourceReference in libraryExport.SourceReferences) + { + sourceReferences.Add(sourceReference); + } + } + + yield return new LibraryExport(library, compilationAssemblies, sourceReferences, libraryExport.RuntimeAssemblies, libraryExport.NativeLibraries); + } + } + } + + private void QueueDependencies(Queue queue, Node node) + { + // Queue up all the dependencies to be exported + foreach (var dependency in node.Library.Dependencies) + { + var childNode = new Node + { + Library = LibraryManager.GetLibrary(dependency.Name), + Parent = node + }; + + queue.Enqueue(childNode); + } + } + + private LibraryExport GetExport(LibraryDescription library) + { + // Don't even try to export unresolved libraries + if (!library.Resolved) + { + return null; + } + + if (Equals(LibraryType.Package, library.Identity.Type)) + { + return ExportPackage((PackageDescription)library); + } + else if (Equals(LibraryType.Project, library.Identity.Type)) + { + return ExportProject((ProjectDescription)library); + } + else + { + return ExportFrameworkLibrary(library); + } + } + + private LibraryExport ExportPackage(PackageDescription package) + { + var nativeLibraries = new List(); + PopulateAssets(package, package.Target.NativeLibraries, nativeLibraries); + + var runtimeAssemblies = new List(); + PopulateAssets(package, package.Target.RuntimeAssemblies, runtimeAssemblies); + + var compileAssemblies = new List(); + PopulateAssets(package, package.Target.CompileTimeAssemblies, compileAssemblies); + + var sourceReferences = new List(); + foreach (var sharedSource in GetSharedSources(package)) + { + sourceReferences.Add(sharedSource); + } + + return new LibraryExport(package, compileAssemblies, sourceReferences, runtimeAssemblies, nativeLibraries); + } + + private LibraryExport ExportProject(ProjectDescription project) + { + var compileAssemblies = new List(); + var sourceReferences = new List(); + + if (!string.IsNullOrEmpty(project.TargetFrameworkInfo?.AssemblyPath)) + { + // Project specifies a pre-compiled binary. We're done! + var assemblyPath = ResolvePath(project.Project, _configuration, project.TargetFrameworkInfo.AssemblyPath); + compileAssemblies.Add(assemblyPath); + } + else + { + // Add the project output to the metadata references, if there is source code + var outputPath = GetOutputPath(project); + if (project.Project.Files.SourceFiles.Any()) + { + compileAssemblies.Add(outputPath); + } + + // Add shared sources + foreach (var sharedFile in project.Project.Files.SharedFiles) + { + sourceReferences.Add(sharedFile); + } + } + + // No support for ref or native in projects, so runtimeAssemblies is just the same as compileAssemblies and nativeLibraries are empty + return new LibraryExport(project, compileAssemblies, sourceReferences, compileAssemblies, Enumerable.Empty()); + } + + private string GetOutputPath(ProjectDescription project) + { + return Path.Combine( + project.Project.ProjectDirectory, + "bin", + _configuration, + project.Framework.GetTwoDigitShortFolderName(), + project.Project.Name + ".dll"); + } + + private static string ResolvePath(Project project, string configuration, string path) + { + if (string.IsNullOrEmpty(path)) + { + return null; + } + + path = PathUtility.GetPathWithDirectorySeparator(path); + + path = path.Replace("{configuration}", configuration); + + return Path.Combine(project.ProjectDirectory, path); + } + + private LibraryExport ExportFrameworkLibrary(LibraryDescription library) + { + if (string.IsNullOrEmpty(library.Path)) + { + return null; + } + + // We assume the path is to an assembly. Framework libraries only export compile-time stuff + // since they assume the runtime library is present already + return new LibraryExport( + library, + new[] { library.Path }, + Enumerable.Empty(), + Enumerable.Empty(), + Enumerable.Empty()); + } + + private IEnumerable GetSharedSources(PackageDescription package) + { + var directory = Path.Combine(package.Path, "shared"); + + return package + .Library + .Files + .Where(path => path.StartsWith("shared" + Path.DirectorySeparatorChar)) + .Select(path => Path.Combine(package.Path, path)); + } + + + private void PopulateAssets(PackageDescription package, IEnumerable section, IList paths) + { + foreach (var assemblyPath in section) + { + if (PathUtility.IsPlaceholderFile(assemblyPath)) + { + continue; + } + + var path = Path.Combine(package.Path, assemblyPath); + paths.Add(path); + } + } + + private class Node + { + public LibraryDescription Library { get; set; } + + public Node Parent { get; set; } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/CompilerOptions.cs b/src/Microsoft.Extensions.ProjectModel/CompilerOptions.cs new file mode 100644 index 000000000..b7e76f79c --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/CompilerOptions.cs @@ -0,0 +1,98 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.Extensions.ProjectModel +{ + public class CompilerOptions + { + public IEnumerable Defines { get; set; } + + public string LanguageVersion { get; set; } + + public string Platform { get; set; } + + public bool? AllowUnsafe { get; set; } + + public bool? WarningsAsErrors { get; set; } + + public bool? Optimize { get; set; } + + public string KeyFile { get; set; } + + public bool? DelaySign { get; set; } + + public bool? StrongName { get; set; } + + public bool? EmitEntryPoint { get; set; } + + public static CompilerOptions Combine(params CompilerOptions[] options) + { + var result = new CompilerOptions(); + foreach (var option in options) + { + // Skip null options + if (option == null) + { + continue; + } + + // Defines are always combined + if (option.Defines != null) + { + var existing = result.Defines ?? Enumerable.Empty(); + result.Defines = existing.Concat(option.Defines).Distinct(); + } + + if (option.LanguageVersion != null) + { + result.LanguageVersion = option.LanguageVersion; + } + + if (option.Platform != null) + { + result.Platform = option.Platform; + } + + if (option.AllowUnsafe != null) + { + result.AllowUnsafe = option.AllowUnsafe; + } + + if (option.WarningsAsErrors != null) + { + result.WarningsAsErrors = option.WarningsAsErrors; + } + + if (option.Optimize != null) + { + result.Optimize = option.Optimize; + } + + if (option.KeyFile != null) + { + result.KeyFile = option.KeyFile; + } + + if (option.DelaySign != null) + { + result.DelaySign = option.DelaySign; + } + + if (option.StrongName != null) + { + result.StrongName = option.StrongName; + } + + if (option.EmitEntryPoint != null) + { + result.EmitEntryPoint = option.EmitEntryPoint; + } + } + + return result; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/DiagnosticMessage.cs b/src/Microsoft.Extensions.ProjectModel/DiagnosticMessage.cs new file mode 100644 index 000000000..1186fa62e --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/DiagnosticMessage.cs @@ -0,0 +1,148 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Newtonsoft.Json; + +namespace Microsoft.Extensions.ProjectModel +{ + /// + /// Represents a single diagnostic message, such as a compilation error or a project.json parsing error. + /// + public class DiagnosticMessage + { + public DiagnosticMessage(string errorCode, string message, string filePath, DiagnosticMessageSeverity severity) + : this(errorCode, message, filePath, severity, startLine: 1, startColumn: 0) + { } + + public DiagnosticMessage(string errorCode, string message, string filePath, DiagnosticMessageSeverity severity, IJsonLineInfo token) + : this( + errorCode, + message, + $"{filePath}({token.LineNumber},{token.LinePosition}): {severity.ToString().ToLowerInvariant()} {errorCode}: {message}", + filePath, + severity, + token.LineNumber, + token.LinePosition, + endLine: token.LineNumber, + endColumn: token.LinePosition, + source: null) + { } + + public DiagnosticMessage(string errorCode, string message, string filePath, DiagnosticMessageSeverity severity, int startLine, int startColumn) + : this( + errorCode, + message, + $"{filePath}({startLine},{startColumn}): {severity.ToString().ToLowerInvariant()} {errorCode}: {message}", + filePath, + severity, + startLine, + startColumn, + endLine: startLine, + endColumn: startColumn, + source: null) + { } + + public DiagnosticMessage(string errorCode, string message, string filePath, DiagnosticMessageSeverity severity, int startLine, int startColumn, object source) + : this( + errorCode, + message, + $"{filePath}({startLine},{startColumn}): {severity.ToString().ToLowerInvariant()} {errorCode}: {message}", + filePath, + severity, + startLine, + startColumn, + endLine: startLine, + endColumn: startColumn, + source: source) + { } + + public DiagnosticMessage(string errorCode, string message, string formattedMessage, string filePath, + DiagnosticMessageSeverity severity, int startLine, int startColumn, int endLine, int endColumn) + : this(errorCode, + message, + formattedMessage, + filePath, + severity, + startLine, + startColumn, + endLine, + endColumn, + source: null) + { + } + + public DiagnosticMessage( + string errorCode, + string message, + string formattedMessage, + string filePath, + DiagnosticMessageSeverity severity, + int startLine, + int startColumn, + int endLine, + int endColumn, + object source) + { + ErrorCode = errorCode; + Message = message; + SourceFilePath = filePath; + Severity = severity; + StartLine = startLine; + EndLine = endLine; + StartColumn = startColumn; + EndColumn = endColumn; + FormattedMessage = formattedMessage; + Source = source; + } + + /// + /// The moniker associated with the error message + /// + public string ErrorCode { get; } + + /// + /// Path of the file that produced the message. + /// + public string SourceFilePath { get; } + + /// + /// Gets the error message. + /// + public string Message { get; } + + /// + /// Gets the . + /// + public DiagnosticMessageSeverity Severity { get; } + + /// + /// Gets the one-based line index for the start of the compilation error. + /// + public int StartLine { get; } + + /// + /// Gets the zero-based column index for the start of the compilation error. + /// + public int StartColumn { get; } + + /// + /// Gets the one-based line index for the end of the compilation error. + /// + public int EndLine { get; } + + /// + /// Gets the zero-based column index for the end of the compilation error. + /// + public int EndColumn { get; } + + /// + /// Gets the formatted error message. + /// + public string FormattedMessage { get; } + + /// + /// Gets the source of this message + /// + public object Source { get; } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/DiagnosticMessageExtensions.cs b/src/Microsoft.Extensions.ProjectModel/DiagnosticMessageExtensions.cs new file mode 100644 index 000000000..87a81b7ba --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/DiagnosticMessageExtensions.cs @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.Extensions.ProjectModel +{ + public static class DiagnosticMessageExtensions + { + /// + /// Returns true if has at least one message with . + /// + /// Sequence of objects. + /// true if any messages is an error message, false otherwise. + public static bool HasErrors(this IEnumerable messages) + { + return messages.Any(m => m.Severity == DiagnosticMessageSeverity.Error); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/DiagnosticMessageSeverity.cs b/src/Microsoft.Extensions.ProjectModel/DiagnosticMessageSeverity.cs new file mode 100644 index 000000000..3b6d0b3ed --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/DiagnosticMessageSeverity.cs @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.Extensions.ProjectModel +{ + /// + /// Specifies the severity of a . + /// + public enum DiagnosticMessageSeverity + { + Info, + Warning, + Error, + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/DiagnosticMonikers.cs b/src/Microsoft.Extensions.ProjectModel/DiagnosticMonikers.cs new file mode 100644 index 000000000..97c33d64c --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/DiagnosticMonikers.cs @@ -0,0 +1,41 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.Extensions.ProjectModel +{ + public static class ErrorCodes + { + // The dependency A could not be resolved. + public static readonly string NU1001 = nameof(NU1001); + + // The dependency A in project B does not support framework C." + public static readonly string NU1002 = nameof(NU1002); + + // Invalid A section. The target B is invalid, targets must either be a file name or a directory suffixed with '/'. The root directory of the package can be specified by using a single '/' character. + public static readonly string NU1003 = nameof(NU1003); + + // Invalid A section. The target B contains path-traversal characters ('.' or '..'). These characters are not permitted in target paths. + public static readonly string NU1004 = nameof(NU1004); + + // Invalid A section. The target B refers to a single file, but the pattern C produces multiple files. To mark the target as a directory, suffix it with '/'. + public static readonly string NU1005 = nameof(NU1005); + + // A. Please run \"dnu restore\" to generate a new lock file. + public static readonly string NU1006 = nameof(NU1006); + + // Dependency specified was A but ended up with B. + public static readonly string NU1007 = nameof(NU1007); + + // A is an unsupported framework. + public static readonly string NU1008 = nameof(NU1008); + + // The expected lock file doesn't exist. Please run \"dnu restore\" to generate a new lock file. + public static readonly string NU1009 = nameof(NU1009); + + // The dependency type was changed + public static readonly string NU1010 = nameof(NU1010); + + // The dependency target '{0}' is unsupported. + public static readonly string NU1011 = nameof(NU1011); + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/EnvironmentNames.cs b/src/Microsoft.Extensions.ProjectModel/EnvironmentNames.cs new file mode 100644 index 000000000..0381b5cf2 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/EnvironmentNames.cs @@ -0,0 +1,7 @@ +namespace Microsoft.Extensions.ProjectModel +{ + public class EnvironmentNames + { + public static readonly string PackagesCache = "NUGET_PACKAGES"; + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/FileFormatException.cs b/src/Microsoft.Extensions.ProjectModel/FileFormatException.cs new file mode 100644 index 000000000..873f825ca --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/FileFormatException.cs @@ -0,0 +1,124 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Extensions.ProjectModel +{ + public sealed class FileFormatException : Exception + { + private FileFormatException(string message) : + base(message) + { + } + + private FileFormatException(string message, Exception innerException) : + base(message, innerException) + { + } + + public string Path { get; private set; } + public int Line { get; private set; } + public int Column { get; private set; } + + public override string ToString() + { + return $"{Path}({Line},{Column}): Error: {base.ToString()}"; + } + + internal static FileFormatException Create(Exception exception, string filePath) + { + if (exception is JsonReaderException) + { + return new FileFormatException(exception.Message, exception) + .WithFilePath(filePath) + .WithLineInfo((JsonReaderException)exception); + } + else + { + return new FileFormatException(exception.Message, exception) + .WithFilePath(filePath); + } + } + + internal static FileFormatException Create(Exception exception, JToken jsonValue, string filePath) + { + var result = Create(exception, jsonValue) + .WithFilePath(filePath); + + return result; + } + + internal static FileFormatException Create(Exception exception, IJsonLineInfo jsonValue) + { + var result = new FileFormatException(exception.Message, exception) + .WithLineInfo(jsonValue); + + return result; + } + + internal static FileFormatException Create(string message, IJsonLineInfo jsonValue, string filePath) + { + var result = Create(message, jsonValue) + .WithFilePath(filePath); + + return result; + } + + internal static FileFormatException Create(string message, string filePath) + { + var result = new FileFormatException(message) + .WithFilePath(filePath); + + return result; + } + + internal static FileFormatException Create(string message, IJsonLineInfo jsonValue) + { + var result = new FileFormatException(message) + .WithLineInfo(jsonValue); + + return result; + } + + internal FileFormatException WithFilePath(string path) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + Path = path; + + return this; + } + + private FileFormatException WithLineInfo(IJsonLineInfo value) + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + Line = value.LineNumber; + Column = value.LinePosition; + + return this; + } + + private FileFormatException WithLineInfo(JsonReaderException exception) + { + if (exception == null) + { + throw new ArgumentNullException(nameof(exception)); + } + + Line = exception.LineNumber; + Column = exception.LinePosition; + + return this; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/GlobalSettings.cs b/src/Microsoft.Extensions.ProjectModel/GlobalSettings.cs new file mode 100644 index 000000000..cd53734cc --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/GlobalSettings.cs @@ -0,0 +1,84 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IO; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Extensions.ProjectModel +{ + public class GlobalSettings + { + public const string GlobalFileName = "global.json"; + + public IList ProjectSearchPaths { get; private set; } + public string PackagesPath { get; private set; } + public string FilePath { get; private set; } + public string DirectoryPath + { + get + { + return Path.GetFullPath(Path.GetDirectoryName(FilePath)); + } + } + + public static bool TryGetGlobalSettings(string path, out GlobalSettings globalSettings) + { + globalSettings = null; + string globalJsonPath = null; + + if (Path.GetFileName(path) == GlobalFileName) + { + globalJsonPath = path; + path = Path.GetDirectoryName(path); + } + else if (!HasGlobalFile(path)) + { + return false; + } + else + { + globalJsonPath = Path.Combine(path, GlobalFileName); + } + + globalSettings = new GlobalSettings(); + + try + { + using (var fs = File.OpenRead(globalJsonPath)) + { + var reader = new StreamReader(fs); + var jobject = JObject.Parse(reader.ReadToEnd()); + + if (jobject == null) + { + throw new InvalidOperationException("The JSON file can't be deserialized to a JSON object."); + } + + var projectSearchPaths = jobject.ValueAsStringArray("projects") ?? + jobject.ValueAsStringArray("sources") ?? + new string[] { }; + + globalSettings.ProjectSearchPaths = new List(projectSearchPaths); + globalSettings.PackagesPath = jobject.Value("packages"); + globalSettings.FilePath = globalJsonPath; + } + } + catch (Exception ex) + { + throw FileFormatException.Create(ex, globalJsonPath); + } + + return true; + } + + public static bool HasGlobalFile(string path) + { + string projectPath = Path.Combine(path, GlobalFileName); + + return File.Exists(projectPath); + } + + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/Graph/LibraryDependencyType.cs b/src/Microsoft.Extensions.ProjectModel/Graph/LibraryDependencyType.cs new file mode 100644 index 000000000..a4ef3d7f8 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Graph/LibraryDependencyType.cs @@ -0,0 +1,47 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; + +namespace Microsoft.Extensions.ProjectModel.Graph +{ + public struct LibraryDependencyType + { + private readonly LibraryDependencyTypeFlag _flags; + + public static LibraryDependencyType Default = new LibraryDependencyType(); + + private LibraryDependencyType(LibraryDependencyTypeFlag flags) + { + _flags = flags; + } + + public static LibraryDependencyType Parse(string keyword) + { + if (string.Equals(keyword, "default", StringComparison.OrdinalIgnoreCase) || + string.IsNullOrEmpty(keyword)) // Need the default value of the struct to behave like "default" + { + return new LibraryDependencyType( + LibraryDependencyTypeFlag.MainReference | + LibraryDependencyTypeFlag.MainSource | + LibraryDependencyTypeFlag.MainExport | + LibraryDependencyTypeFlag.RuntimeComponent | + LibraryDependencyTypeFlag.BecomesNupkgDependency); + } + + if (string.Equals(keyword, "build", StringComparison.OrdinalIgnoreCase)) + { + return new LibraryDependencyType( + LibraryDependencyTypeFlag.MainSource | + LibraryDependencyTypeFlag.PreprocessComponent); + } + + throw new InvalidOperationException(string.Format("unknown keyword {0}", keyword)); + } + + public bool HasFlag(LibraryDependencyTypeFlag flag) + { + return (_flags & flag) != 0; + } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/Graph/LibraryDependencyTypeFlag.cs b/src/Microsoft.Extensions.ProjectModel/Graph/LibraryDependencyTypeFlag.cs new file mode 100644 index 000000000..48859eb5d --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Graph/LibraryDependencyTypeFlag.cs @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; + +namespace Microsoft.Extensions.ProjectModel.Graph +{ + [Flags] + public enum LibraryDependencyTypeFlag + { + None = 0, + MainReference = 1 << 0, + MainSource = 1 << 1, + MainExport = 1 << 2, + PreprocessReference = 1 << 3, + RuntimeComponent = 1 << 4, + DevComponent = 1 << 5, + PreprocessComponent = 1 << 6, + BecomesNupkgDependency = 1 << 7, + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/Graph/LibraryIdentity.cs b/src/Microsoft.Extensions.ProjectModel/Graph/LibraryIdentity.cs new file mode 100644 index 000000000..7325032be --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Graph/LibraryIdentity.cs @@ -0,0 +1,86 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using NuGet; +using NuGet.Versioning; + +namespace Microsoft.Extensions.ProjectModel.Graph +{ + public struct LibraryIdentity : IEquatable + { + public string Name { get; } + + public NuGetVersion Version { get; } + + public LibraryType Type { get; } + + public LibraryIdentity(string name, LibraryType type) + : this(name, null, type) + { } + + public LibraryIdentity(string name, NuGetVersion version, LibraryType type) + { + Name = name; + Version = version; + Type = type; + } + + public override string ToString() + { + return $"{Name} {Version?.ToString()}"; + } + + public bool Equals(LibraryIdentity other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return string.Equals(Name, other.Name) && + Equals(Version, other.Version) && + Equals(Type, other.Type); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((LibraryIdentity)obj); + } + + public override int GetHashCode() + { + unchecked + { + return ((Name != null ? Name.GetHashCode() : 0) * 397) ^ + (Version != null ? Version.GetHashCode() : 0) ^ + (Type.GetHashCode()); + } + } + + public static bool operator ==(LibraryIdentity left, LibraryIdentity right) + { + return Equals(left, right); + } + + public static bool operator !=(LibraryIdentity left, LibraryIdentity right) + { + return !Equals(left, right); + } + + public LibraryRange ToLibraryRange() + { + return new LibraryRange(Name, CreateVersionRange(Version), Type, LibraryDependencyType.Default); + } + + private static VersionRange CreateVersionRange(NuGetVersion version) + { + return version == null ? null : new VersionRange(version, new FloatRange(NuGetVersionFloatBehavior.None)); + } + + public LibraryIdentity ChangeName(string name) + { + return new LibraryIdentity(name, Version, Type); + } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/Graph/LibraryRange.cs b/src/Microsoft.Extensions.ProjectModel/Graph/LibraryRange.cs new file mode 100644 index 000000000..e7ed15b40 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Graph/LibraryRange.cs @@ -0,0 +1,109 @@ +using System; +using System.Text; +using Microsoft.Extensions.Internal; +using NuGet.Versioning; + +namespace Microsoft.Extensions.ProjectModel.Graph +{ + public struct LibraryRange : IEquatable + { + public string Name { get; } + public VersionRange VersionRange { get; } + public LibraryType Target { get; } + public LibraryDependencyType Type { get; } + + public string SourceFilePath { get; } + public int SourceLine { get; } + public int SourceColumn { get; } + + public LibraryRange(string name, LibraryType target) + : this(name, null, target, LibraryDependencyType.Default, sourceFilePath: string.Empty, sourceLine: 0, sourceColumn: 0) + { } + + public LibraryRange(string name, LibraryType target, LibraryDependencyType type) + : this(name, null, target, type, sourceFilePath: string.Empty, sourceLine: 0, sourceColumn: 0) + { } + + public LibraryRange(string name, VersionRange versionRange, LibraryType target, LibraryDependencyType type) + : this(name, versionRange, target, type, sourceFilePath: string.Empty, sourceLine: 0, sourceColumn: 0) + { } + + public LibraryRange(string name, VersionRange versionRange, LibraryType target, LibraryDependencyType type, string sourceFilePath, int sourceLine, int sourceColumn) + { + Name = name; + VersionRange = versionRange; + Target = target; + Type = type; + SourceFilePath = sourceFilePath; + SourceLine = sourceLine; + SourceColumn = sourceColumn; + } + + public bool Equals(LibraryRange other) + { + return string.Equals(other.Name, Name, StringComparison.OrdinalIgnoreCase) && + Equals(VersionRange, other.VersionRange) && + Equals(Target, other.Target) && + Equals(Type, other.Type); + // SourceFilePath, SourceLine, SourceColumn are irrelevant for equality, they are diagnostic + } + + public override bool Equals(object obj) + { + return obj is LibraryRange && Equals((LibraryRange)obj); + } + + public static bool operator ==(LibraryRange left, LibraryRange right) + { + return Equals(left, right); + } + + public static bool operator !=(LibraryRange left, LibraryRange right) + { + return !Equals(left, right); + } + + public override int GetHashCode() + { + var combiner = HashCodeCombiner.Start(); + combiner.Add(Name); + combiner.Add(VersionRange); + combiner.Add(Target); + combiner.Add(Type); + return combiner.CombinedHash; + } + + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append(Name); + + if (VersionRange != null) + { + sb.Append(" "); + sb.Append(VersionRange); + } + + if (!Equals(Type, LibraryDependencyType.Default)) + { + sb.Append(" ("); + sb.Append(Type); + sb.Append(")"); + } + + if (!Equals(Target, LibraryType.Unspecified)) + { + sb.Append(" (Target: "); + sb.Append(Target); + sb.Append(")"); + } + + return sb.ToString(); + } + + public bool HasFlag(LibraryDependencyTypeFlag flag) + { + return Type.HasFlag(flag); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/Graph/LibraryType.cs b/src/Microsoft.Extensions.ProjectModel/Graph/LibraryType.cs new file mode 100644 index 000000000..875e747eb --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Graph/LibraryType.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; + +namespace Microsoft.Extensions.ProjectModel.Graph +{ + public struct LibraryType : IEquatable + { + public static readonly LibraryType Package = new LibraryType(nameof(Package)); + public static readonly LibraryType Project = new LibraryType(nameof(Project)); + public static readonly LibraryType ReferenceAssembly = new LibraryType(nameof(ReferenceAssembly)); + + // Default value + public static readonly LibraryType Unspecified = new LibraryType(); + + public string Value { get; } + + private LibraryType(string value) + { + Value = value; + } + + public static bool TryParse(string value, out LibraryType type) + { + // We only support values we know about + if(string.Equals(Package.Value, value, StringComparison.OrdinalIgnoreCase)) + { + type = Package; + return true; + } + else if(string.Equals(Project.Value, value, StringComparison.OrdinalIgnoreCase)) + { + type = Project; + return true; + } + type = Unspecified; + return false; + } + + public override string ToString() + { + return Value; + } + + public bool CanSatisfyConstraint(LibraryType constraint) + { + // Reference assemblies must be explicitly asked for + if (Equals(ReferenceAssembly, constraint)) + { + return Equals(ReferenceAssembly, this); + } + else if (Equals(constraint, Unspecified)) + { + return true; + } + else + { + return string.Equals(constraint.Value, Value, StringComparison.OrdinalIgnoreCase); + } + } + + public bool Equals(LibraryType other) + { + return string.Equals(other.Value, Value, StringComparison.OrdinalIgnoreCase); + } + + public override bool Equals(object obj) + { + return obj is LibraryType && Equals((LibraryType)obj); + } + + public static bool operator ==(LibraryType left, LibraryType right) + { + return Equals(left, right); + } + + public static bool operator !=(LibraryType left, LibraryType right) + { + return !Equals(left, right); + } + + public override int GetHashCode() + { + return StringComparer.OrdinalIgnoreCase.GetHashCode(Value); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/Graph/LockFile.cs b/src/Microsoft.Extensions.ProjectModel/Graph/LockFile.cs new file mode 100644 index 000000000..5007b8b1e --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Graph/LockFile.cs @@ -0,0 +1,134 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NuGet.Versioning; + +namespace Microsoft.Extensions.ProjectModel.Graph +{ + public class LockFile + { + public static readonly int CurrentVersion = 2; + public static readonly string FileName = "project.lock.json"; + + public int Version { get; set; } + public IList ProjectFileDependencyGroups { get; set; } = new List(); + public IList PackageLibraries { get; set; } = new List(); + public IList ProjectLibraries { get; set; } = new List(); + public IList Targets { get; set; } = new List(); + + public bool IsValidForProject(Project project) + { + string message; + return IsValidForProject(project, out message); + } + + public bool IsValidForProject(Project project, out string message) + { + if (Version != CurrentVersion) + { + message = $"The expected lock file version does not match the actual version"; + return false; + } + + message = $"Dependencies in {Project.FileName} were modified"; + + var actualTargetFrameworks = project.GetTargetFrameworks(); + + // The lock file should contain dependencies for each framework plus dependencies shared by all frameworks + if (ProjectFileDependencyGroups.Count != actualTargetFrameworks.Count() + 1) + { + return false; + } + + foreach (var group in ProjectFileDependencyGroups) + { + IOrderedEnumerable actualDependencies; + var expectedDependencies = group.Dependencies.OrderBy(x => x); + + // If the framework name is empty, the associated dependencies are shared by all frameworks + if (group.FrameworkName == null) + { + actualDependencies = project.Dependencies.Select(RenderDependency).OrderBy(x => x); + } + else + { + var framework = actualTargetFrameworks + .FirstOrDefault(f => Equals(f.FrameworkName, group.FrameworkName)); + if (framework == null) + { + return false; + } + + actualDependencies = framework.Dependencies.Select(RenderDependency).OrderBy(x => x); + } + + if (!actualDependencies.SequenceEqual(expectedDependencies)) + { + return false; + } + } + + message = null; + return true; + } + + private string RenderDependency(LibraryRange arg) + { + return $"{arg.Name} {RenderVersion(arg.VersionRange)}"; + } + + private string RenderVersion(VersionRange range) + { + if (range.MinVersion == range.MaxVersion && + (range.Float == null || range.Float.FloatBehavior == NuGetVersionFloatBehavior.None)) + { + return range.MinVersion.ToString(); + } + + var sb = new StringBuilder(); + sb.Append(">= "); + switch (range?.Float?.FloatBehavior) + { + case null: + case NuGetVersionFloatBehavior.None: + sb.Append(range.MinVersion); + break; + case NuGetVersionFloatBehavior.Prerelease: + sb.AppendFormat("{0}-*", range.MinVersion); + break; + case NuGetVersionFloatBehavior.Revision: + sb.AppendFormat("{0}.{1}.{2}.*", + range.MinVersion.Version.Major, + range.MinVersion.Version.Minor, + range.MinVersion.Version.Build); + break; + case NuGetVersionFloatBehavior.Patch: + sb.AppendFormat("{0}.{1}.*", + range.MinVersion.Version.Major, + range.MinVersion.Version.Minor); + break; + case NuGetVersionFloatBehavior.Minor: + sb.AppendFormat("{0}.{1}.*", + range.MinVersion.Version.Major); + break; + case NuGetVersionFloatBehavior.Major: + sb.AppendFormat("*"); + break; + default: + break; + } + + if (range.MaxVersion != null) + { + sb.Append(range.IsMaxInclusive ? " <= " : " < "); + sb.Append(range.MaxVersion); + } + + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/Graph/LockFileItem.cs b/src/Microsoft.Extensions.ProjectModel/Graph/LockFileItem.cs new file mode 100644 index 000000000..4792d4531 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Graph/LockFileItem.cs @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; + +namespace Microsoft.Extensions.ProjectModel.Graph +{ + public class LockFileItem + { + public string Path { get; set; } + + public IDictionary Properties { get; } = new Dictionary(); + + public static implicit operator string (LockFileItem item) => item.Path; + + public static implicit operator LockFileItem(string path) => new LockFileItem { Path = path }; + + public override string ToString() => Path; + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/Graph/LockFileLookup.cs b/src/Microsoft.Extensions.ProjectModel/Graph/LockFileLookup.cs new file mode 100644 index 000000000..c24c07258 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Graph/LockFileLookup.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using NuGet.Versioning; + +namespace Microsoft.Extensions.ProjectModel.Graph +{ + public class LockFileLookup + { + // REVIEW: Case sensitivity? + private readonly Dictionary, LockFilePackageLibrary> _packages; + private readonly Dictionary _projects; + + public LockFileLookup(LockFile lockFile) + { + _packages = new Dictionary, LockFilePackageLibrary>(); + _projects = new Dictionary(); + + foreach (var library in lockFile.PackageLibraries) + { + _packages[Tuple.Create(library.Name, library.Version)] = library; + } + + foreach (var libary in lockFile.ProjectLibraries) + { + _projects[libary.Name] = libary; + } + } + + public LockFileProjectLibrary GetProject(string name) + { + LockFileProjectLibrary project; + if (_projects.TryGetValue(name, out project)) + { + return project; + } + + return null; + } + + public LockFilePackageLibrary GetPackage(string id, NuGetVersion version) + { + LockFilePackageLibrary package; + if (_packages.TryGetValue(Tuple.Create(id, version), out package)) + { + return package; + } + + return null; + } + + public void Clear() + { + _packages.Clear(); + _projects.Clear(); + } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/Graph/LockFilePackageLibrary.cs b/src/Microsoft.Extensions.ProjectModel/Graph/LockFilePackageLibrary.cs new file mode 100644 index 000000000..47d8a822e --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Graph/LockFilePackageLibrary.cs @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using NuGet.Versioning; + +namespace Microsoft.Extensions.ProjectModel.Graph +{ + public class LockFilePackageLibrary + { + public string Name { get; set; } + + public NuGetVersion Version { get; set; } + + public bool IsServiceable { get; set; } + + public string Sha512 { get; set; } + + public IList Files { get; set; } = new List(); + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/Graph/LockFileProjectLibrary.cs b/src/Microsoft.Extensions.ProjectModel/Graph/LockFileProjectLibrary.cs new file mode 100644 index 000000000..740a870d9 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Graph/LockFileProjectLibrary.cs @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using NuGet.Versioning; + +namespace Microsoft.Extensions.ProjectModel.Graph +{ + public class LockFileProjectLibrary + { + public string Name { get; set; } + + public NuGetVersion Version { get; set; } + + public string Path { get; set; } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/Graph/LockFileReader.cs b/src/Microsoft.Extensions.ProjectModel/Graph/LockFileReader.cs new file mode 100644 index 000000000..528242b2a --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Graph/LockFileReader.cs @@ -0,0 +1,492 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.Versioning; +using Microsoft.Extensions.ProjectModel.Utilities; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using NuGet.Frameworks; +using NuGet.Packaging; +using NuGet.Packaging.Core; +using NuGet.Versioning; + +namespace Microsoft.Extensions.ProjectModel.Graph +{ + public static class LockFileReader + { + public static LockFile Read(string path) + { + using(var fs = FileSystemUtility.OpenFileStream(path)) + { + return Read(fs); + } + } + + public static LockFile Read(Stream stream) + { + using (var textReader = new StreamReader(stream)) + { + try + { + using (var jsonReader = new JsonTextReader(textReader)) + { + while (jsonReader.TokenType != JsonToken.StartObject) + { + if (!jsonReader.Read()) + { + throw new InvalidDataException(); + } + } + var token = JToken.Load(jsonReader); + return ReadLockFile(token as JObject); + } + } + catch + { + // Ran into parsing errors, mark it as unlocked and out-of-date + return new LockFile + { + Version = int.MinValue + }; + } + } + } + + public static void Write(Stream stream, LockFile lockFile) + { + using (var textWriter = new StreamWriter(stream)) + { + using (var jsonWriter = new JsonTextWriter(textWriter)) + { + jsonWriter.Formatting = Formatting.Indented; + + var json = WriteLockFile(lockFile); + json.WriteTo(jsonWriter); + } + } + } + + private static LockFile ReadLockFile(JObject cursor) + { + var lockFile = new LockFile(); + lockFile.Version = ReadInt(cursor, "version", defaultValue: int.MinValue); + lockFile.Targets = ReadObject(cursor["targets"] as JObject, ReadTarget); + lockFile.ProjectFileDependencyGroups = ReadObject(cursor["projectFileDependencyGroups"] as JObject, ReadProjectFileDependencyGroup); + ReadLibrary(cursor["libraries"] as JObject, lockFile); + return lockFile; + } + + private static JObject WriteLockFile(LockFile lockFile) + { + var json = new JObject(); + json["locked"] = new JValue(false); + json["version"] = new JValue(LockFile.CurrentVersion); + json["targets"] = WriteObject(lockFile.Targets, WriteTarget); + json["libraries"] = WriteLibraries(lockFile); + json["projectFileDependencyGroups"] = WriteObject(lockFile.ProjectFileDependencyGroups, WriteProjectFileDependencyGroup); + return json; + } + + private static void ReadLibrary(JObject json, LockFile lockFile) + { + if (json == null) + { + return; + } + + foreach (var property in json) + { + var value = property.Value as JObject; + if (value == null) + { + continue; + } + + var parts = property.Key.Split(new[] { '/' }, 2); + var name = parts[0]; + var version = parts.Length == 2 ? NuGetVersion.Parse(parts[1]) : null; + + var type = value["type"]?.Value(); + + if (type == null || type == "package") + { + lockFile.PackageLibraries.Add(new LockFilePackageLibrary + { + Name = name, + Version = version, + IsServiceable = ReadBool(value, "serviceable", defaultValue: false), + Sha512 = ReadString(value["sha512"]), + Files = ReadPathArray(value["files"] as JArray, ReadString) + }); + } + else if (type == "project") + { + lockFile.ProjectLibraries.Add(new LockFileProjectLibrary + { + Name = name, + Version = version, + Path = ReadString(value["path"]) + }); + } + } + } + + private static JObject WriteLibraries(LockFile lockFile) + { + var result = new JObject(); + + foreach (var library in lockFile.ProjectLibraries) + { + var value = new JObject(); + value["type"] = WriteString("project"); + value["path"] = WriteString(library.Path); + + result[$"{library.Name}/{library.Version.ToString()}"] = value; + } + + foreach (var library in lockFile.PackageLibraries) + { + var value = new JObject(); + value["type"] = WriteString("package"); + + if (library.IsServiceable) + { + WriteBool(value, "serviceable", library.IsServiceable); + } + + value["sha512"] = WriteString(library.Sha512); + WritePathArray(value, "files", library.Files.OrderBy(f => f), WriteString); + + result[$"{library.Name}/{library.Version.ToString()}"] = value; + } + + return result; + } + + private static JProperty WriteTarget(LockFileTarget target) + { + var json = WriteObject(target.Libraries, WriteTargetLibrary); + + var key = target.TargetFramework + (target.RuntimeIdentifier == null ? "" : "/" + target.RuntimeIdentifier); + + return new JProperty(key, json); + } + + private static LockFileTarget ReadTarget(string property, JToken json) + { + var target = new LockFileTarget(); + var parts = property.Split(new[] { '/' }, 2); + target.TargetFramework = NuGetFramework.Parse(parts[0]); + if (parts.Length == 2) + { + target.RuntimeIdentifier = parts[1]; + } + + target.Libraries = ReadObject(json as JObject, ReadTargetLibrary); + + return target; + } + + private static LockFileTargetLibrary ReadTargetLibrary(string property, JToken json) + { + var library = new LockFileTargetLibrary(); + + var parts = property.Split(new[] { '/' }, 2); + library.Name = parts[0]; + if (parts.Length == 2) + { + library.Version = NuGetVersion.Parse(parts[1]); + } + + var type = json["type"]; + if (type != null) + { + library.Type = ReadString(type); + } + + var framework = json["framework"]; + if (framework != null) + { + library.TargetFramework = NuGetFramework.Parse(ReadString(framework)); + } + + library.Dependencies = ReadObject(json["dependencies"] as JObject, ReadPackageDependency); + library.FrameworkAssemblies = new HashSet(ReadArray(json["frameworkAssemblies"] as JArray, ReadFrameworkAssemblyReference), StringComparer.OrdinalIgnoreCase); + library.RuntimeAssemblies = ReadObject(json["runtime"] as JObject, ReadFileItem); + library.CompileTimeAssemblies = ReadObject(json["compile"] as JObject, ReadFileItem); + library.ResourceAssemblies = ReadObject(json["resource"] as JObject, ReadFileItem); + library.NativeLibraries = ReadObject(json["native"] as JObject, ReadFileItem); + + return library; + } + + private static JProperty WriteTargetLibrary(LockFileTargetLibrary library) + { + var json = new JObject(); + + json["type"] = WriteString(library.Type); + + if (library.TargetFramework != null) + { + json["framework"] = WriteString(library.TargetFramework.ToString()); + } + + if (library.Dependencies.Count > 0) + { + json["dependencies"] = WriteObject(library.Dependencies.OrderBy(p => p.Id), WritePackageDependency); + } + + if (library.FrameworkAssemblies.Count > 0) + { + json["frameworkAssemblies"] = WriteArray(library.FrameworkAssemblies.OrderBy(f => f), WriteFrameworkAssemblyReference); + } + + if (library.CompileTimeAssemblies.Count > 0) + { + json["compile"] = WriteObject(library.CompileTimeAssemblies, WriteFileItem); + } + + if (library.RuntimeAssemblies.Count > 0) + { + json["runtime"] = WriteObject(library.RuntimeAssemblies, WriteFileItem); + } + + if (library.ResourceAssemblies.Count > 0) + { + json["resource"] = WriteObject(library.ResourceAssemblies, WriteFileItem); + } + + if (library.NativeLibraries.Count > 0) + { + json["native"] = WriteObject(library.NativeLibraries, WriteFileItem); + } + + return new JProperty(library.Name + "/" + library.Version, json); + } + + private static ProjectFileDependencyGroup ReadProjectFileDependencyGroup(string property, JToken json) + { + return new ProjectFileDependencyGroup( + NuGetFramework.Parse(property), + ReadArray(json as JArray, ReadString)); + } + + private static JProperty WriteProjectFileDependencyGroup(ProjectFileDependencyGroup frameworkInfo) + { + return new JProperty( + frameworkInfo.FrameworkName?.DotNetFrameworkName ?? string.Empty, + WriteArray(frameworkInfo.Dependencies, WriteString)); + } + + private static PackageDependencyGroup ReadPackageDependencySet(string property, JToken json) + { + var targetFramework = string.Equals(property, "*") ? null : NuGetFramework.Parse(property); + return new PackageDependencyGroup( + targetFramework, + ReadObject(json as JObject, ReadPackageDependency)); + } + + private static JProperty WritePackageDependencySet(PackageDependencyGroup item) + { + return new JProperty( + item.TargetFramework?.ToString() ?? "*", + WriteObject(item.Packages, WritePackageDependency)); + } + + + private static PackageDependency ReadPackageDependency(string property, JToken json) + { + var versionStr = json.Value(); + return new PackageDependency( + property, + versionStr == null ? null : VersionRange.Parse(versionStr)); + } + + private static JProperty WritePackageDependency(PackageDependency item) + { + return new JProperty( + item.Id, + WriteString(item.VersionRange?.ToString())); + } + + private static LockFileItem ReadFileItem(string property, JToken json) + { + var item = new LockFileItem { Path = PathUtility.GetPathWithDirectorySeparator(property) }; + foreach (var subProperty in json.OfType()) + { + item.Properties[subProperty.Name] = subProperty.Value.Value(); + } + return item; + } + + private static JProperty WriteFileItem(LockFileItem item) + { + return new JProperty( + item.Path, + new JObject(item.Properties.Select(x => new JProperty(x.Key, x.Value)))); + } + + private static string ReadFrameworkAssemblyReference(JToken json) + { + return json.Value(); + } + + private static JToken WriteFrameworkAssemblyReference(string item) + { + return new JValue(item); + } + + private static FrameworkSpecificGroup ReadPackageReferenceSet(JToken json) + { + var frameworkName = json["targetFramework"]?.ToString(); + return new FrameworkSpecificGroup( + string.IsNullOrEmpty(frameworkName) ? null : NuGetFramework.Parse(frameworkName), + ReadArray(json["references"] as JArray, ReadString)); + } + + private static JToken WritePackageReferenceSet(FrameworkSpecificGroup item) + { + var json = new JObject(); + json["targetFramework"] = item.TargetFramework?.ToString(); + json["references"] = WriteArray(item.Items, WriteString); + return json; + } + + private static IList ReadArray(JArray json, Func readItem) + { + if (json == null) + { + return new List(); + } + var items = new List(); + foreach (var child in json) + { + items.Add(readItem(child)); + } + return items; + } + + private static IList ReadPathArray(JArray json, Func readItem) + { + return ReadArray(json, readItem).Select(f => PathUtility.GetPathWithDirectorySeparator(f)).ToList(); + } + + private static void WriteArray(JToken json, string property, IEnumerable items, Func writeItem) + { + if (items.Any()) + { + json[property] = WriteArray(items, writeItem); + } + } + + private static void WritePathArray(JToken json, string property, IEnumerable items, Func writeItem) + { + WriteArray(json, property, items.Select(f => PathUtility.GetPathWithForwardSlashes(f)), writeItem); + } + + private static JArray WriteArray(IEnumerable items, Func writeItem) + { + var array = new JArray(); + foreach (var item in items) + { + array.Add(writeItem(item)); + } + return array; + } + + private static JArray WritePathArray(IEnumerable items, Func writeItem) + { + return WriteArray(items.Select(f => PathUtility.GetPathWithForwardSlashes(f)), writeItem); + } + + private static IList ReadObject(JObject json, Func readItem) + { + if (json == null) + { + return new List(); + } + var items = new List(); + foreach (var child in json) + { + items.Add(readItem(child.Key, child.Value)); + } + return items; + } + + private static void WriteObject(JToken json, string property, IEnumerable items, Func writeItem) + { + if (items.Any()) + { + json[property] = WriteObject(items, writeItem); + } + } + + private static JObject WriteObject(IEnumerable items, Func writeItem) + { + var array = new JObject(); + foreach (var item in items) + { + array.Add(writeItem(item)); + } + return array; + } + + private static bool ReadBool(JToken cursor, string property, bool defaultValue) + { + var valueToken = cursor[property]; + if (valueToken == null) + { + return defaultValue; + } + return valueToken.Value(); + } + + private static int ReadInt(JToken cursor, string property, int defaultValue) + { + var valueToken = cursor[property]; + if (valueToken == null) + { + return defaultValue; + } + return valueToken.Value(); + } + + private static string ReadString(JToken json) + { + return json.Value(); + } + + private static NuGetVersion ReadSemanticVersion(JToken json, string property) + { + var valueToken = json[property]; + if (valueToken == null) + { + throw new ArgumentException($"lock file missing required property '{property}'", nameof(property)); + } + return NuGetVersion.Parse(valueToken.Value()); + } + + private static void WriteBool(JToken token, string property, bool value) + { + token[property] = new JValue(value); + } + + private static JToken WriteString(string item) + { + return item != null ? new JValue(item) : JValue.CreateNull(); + } + + private static NuGetFramework ReadFrameworkName(JToken json) + { + return json == null ? null : NuGetFramework.Parse(json.Value()); + } + private static JToken WriteFrameworkName(NuGetFramework item) + { + return item != null ? new JValue(item.DotNetFrameworkName) : JValue.CreateNull(); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/Graph/LockFileTarget.cs b/src/Microsoft.Extensions.ProjectModel/Graph/LockFileTarget.cs new file mode 100644 index 000000000..341aca3a5 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Graph/LockFileTarget.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using NuGet.Frameworks; + +namespace Microsoft.Extensions.ProjectModel.Graph +{ + public class LockFileTarget + { + public NuGetFramework TargetFramework { get; set; } + + public string RuntimeIdentifier { get; set; } + + public IList Libraries { get; set; } = new List(); + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/Graph/LockFileTargetLibrary.cs b/src/Microsoft.Extensions.ProjectModel/Graph/LockFileTargetLibrary.cs new file mode 100644 index 000000000..13163cb38 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Graph/LockFileTargetLibrary.cs @@ -0,0 +1,34 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using NuGet.Frameworks; +using NuGet.Packaging.Core; +using NuGet.Versioning; + +namespace Microsoft.Extensions.ProjectModel.Graph +{ + public class LockFileTargetLibrary + { + public string Name { get; set; } + + public string Type { get; set; } + + public NuGetFramework TargetFramework { get; set; } + + public NuGetVersion Version { get; set; } + + public IList Dependencies { get; set; } = new List(); + + public ISet FrameworkAssemblies { get; set; } = new HashSet(StringComparer.OrdinalIgnoreCase); + + public IList RuntimeAssemblies { get; set; } = new List(); + + public IList CompileTimeAssemblies { get; set; } = new List(); + + public IList ResourceAssemblies { get; set; } = new List(); + + public IList NativeLibraries { get; set; } = new List(); + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/LibraryDescription.cs b/src/Microsoft.Extensions.ProjectModel/LibraryDescription.cs new file mode 100644 index 000000000..e380ba31a --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/LibraryDescription.cs @@ -0,0 +1,49 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Linq; +using Microsoft.Extensions.ProjectModel.Graph; +using NuGet.Frameworks; + +namespace Microsoft.Extensions.ProjectModel +{ + /// + /// Represents the result of resolving the library + /// + public class LibraryDescription + { + public LibraryDescription( + LibraryRange requestedRange, + LibraryIdentity identity, + string path, + IEnumerable dependencies, + NuGetFramework framework, + bool resolved, + bool compatible) + { + Path = path; + RequestedRange = requestedRange; + Identity = identity; + Dependencies = dependencies ?? Enumerable.Empty(); + Framework = framework; + Resolved = resolved; + Compatible = compatible; + } + + public LibraryRange RequestedRange { get; } + public LibraryIdentity Identity { get; } + public LibraryDescription Parent { get; set; } + public string Path { get; } + public IEnumerable Dependencies { get; } + public bool Compatible { get; } + + public NuGetFramework Framework { get; set; } + public bool Resolved { get; set; } + + public override string ToString() + { + return $"{Identity} = {Path}"; + } + } +} diff --git a/src/Microsoft.DotNet.Tools.Run/Microsoft.DotNet.Tools.Run.xproj b/src/Microsoft.Extensions.ProjectModel/Microsoft.Extensions.ProjectModel.xproj similarity index 87% rename from src/Microsoft.DotNet.Tools.Run/Microsoft.DotNet.Tools.Run.xproj rename to src/Microsoft.Extensions.ProjectModel/Microsoft.Extensions.ProjectModel.xproj index a091ff410..8552ea4ea 100644 --- a/src/Microsoft.DotNet.Tools.Run/Microsoft.DotNet.Tools.Run.xproj +++ b/src/Microsoft.Extensions.ProjectModel/Microsoft.Extensions.ProjectModel.xproj @@ -4,10 +4,11 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + - 8b23b5ec-6740-447c-92d9-1f10692f232d - Microsoft.DotNet.Tools.Run + 303677d5-7312-4c3f-baee-beb1a9bd9fe6 + Microsoft.Extensions.ProjectModel ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ @@ -16,4 +17,4 @@ 2.0 - \ No newline at end of file + diff --git a/src/Microsoft.Extensions.ProjectModel/PackIncludeEntry.cs b/src/Microsoft.Extensions.ProjectModel/PackIncludeEntry.cs new file mode 100644 index 000000000..9b3d60019 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/PackIncludeEntry.cs @@ -0,0 +1,41 @@ +using System.Linq; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Extensions.ProjectModel +{ + public class PackIncludeEntry + { + public string Target { get; } + public string[] SourceGlobs { get; } + public int Line { get; } + public int Column { get; } + + internal PackIncludeEntry(string target, JToken json) + : this(target, ExtractValues(json), ((IJsonLineInfo)json).LineNumber, ((IJsonLineInfo)json).LinePosition) + { + } + + public PackIncludeEntry(string target, string[] sourceGlobs, int line, int column) + { + Target = target; + SourceGlobs = sourceGlobs; + Line = line; + Column = column; + } + + private static string[] ExtractValues(JToken json) + { + if (json.Type == JTokenType.String) + { + return new string[] { json.Value() }; + } + + if(json.Type == JTokenType.Array) + { + return json.Value().Select(v => v.ToString()).ToArray(); + } + return new string[0]; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/PackageDescription.cs b/src/Microsoft.Extensions.ProjectModel/PackageDescription.cs new file mode 100644 index 000000000..fd49f2df7 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/PackageDescription.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using Microsoft.Extensions.ProjectModel.Graph; + +namespace Microsoft.Extensions.ProjectModel +{ + public class PackageDescription : LibraryDescription + { + public PackageDescription( + LibraryRange requestedRange, + string path, + LockFilePackageLibrary package, + LockFileTargetLibrary lockFileLibrary, + IEnumerable dependencies, + bool compatible) + : base( + requestedRange, + new LibraryIdentity(package.Name, package.Version, LibraryType.Package), + path, + dependencies: dependencies, + framework: null, + resolved: true, + compatible: compatible) + { + Library = package; + Target = lockFileLibrary; + } + + public LockFileTargetLibrary Target { get; set; } + public LockFilePackageLibrary Library { get; set; } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/PatternGroup.cs b/src/Microsoft.Extensions.ProjectModel/PatternGroup.cs new file mode 100644 index 000000000..9269f848e --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/PatternGroup.cs @@ -0,0 +1,123 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.Extensions.FileSystemGlobbing; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Extensions.ProjectModel +{ + public class PatternGroup + { + private readonly List _excludeGroups = new List(); + private readonly Matcher _matcher = new Matcher(); + + internal PatternGroup(IEnumerable includePatterns) + { + IncludeLiterals = Enumerable.Empty(); + IncludePatterns = includePatterns; + ExcludePatterns = Enumerable.Empty(); + _matcher.AddIncludePatterns(IncludePatterns); + } + + internal PatternGroup(IEnumerable includePatterns, IEnumerable excludePatterns, IEnumerable includeLiterals) + { + IncludeLiterals = includeLiterals; + IncludePatterns = includePatterns; + ExcludePatterns = excludePatterns; + + _matcher.AddIncludePatterns(IncludePatterns); + _matcher.AddExcludePatterns(ExcludePatterns); + } + + internal static PatternGroup Build(JObject rawProject, + string projectDirectory, + string projectFilePath, + string name, + IEnumerable fallbackIncluding = null, + IEnumerable additionalIncluding = null, + IEnumerable additionalExcluding = null, + bool includePatternsOnly = false, + ICollection warnings = null) + { + string includePropertyName = name; + additionalIncluding = additionalIncluding ?? Enumerable.Empty(); + var includePatterns = PatternsCollectionHelper.GetPatternsCollection(rawProject, projectDirectory, projectFilePath, includePropertyName, defaultPatterns: fallbackIncluding) + .Concat(additionalIncluding) + .Distinct(); + + if (includePatternsOnly) + { + return new PatternGroup(includePatterns); + } + + additionalExcluding = additionalExcluding ?? Enumerable.Empty(); + var excludePatterns = PatternsCollectionHelper.GetPatternsCollection(rawProject, projectDirectory, projectFilePath, propertyName: name + "Exclude") + .Concat(additionalExcluding) + .Distinct(); + + var includeLiterals = PatternsCollectionHelper.GetPatternsCollection(rawProject, projectDirectory, projectFilePath, propertyName: name + "Files", literalPath: true) + .Distinct(); + + return new PatternGroup(includePatterns, excludePatterns, includeLiterals); + } + + public IEnumerable IncludeLiterals { get; } + + public IEnumerable IncludePatterns { get; } + + public IEnumerable ExcludePatterns { get; } + + public IEnumerable ExcludePatternsGroup { get { return _excludeGroups; } } + + public PatternGroup ExcludeGroup(PatternGroup group) + { + _excludeGroups.Add(group); + + return this; + } + + public IEnumerable SearchFiles(string rootPath) + { + // literal included files are added at the last, but the search happens early + // so as to make the process fail early in case there is missing file. fail early + // helps to avoid unnecessary globing for performance optimization + var literalIncludedFiles = new List(); + foreach (var literalRelativePath in IncludeLiterals) + { + var fullPath = Path.GetFullPath(Path.Combine(rootPath, literalRelativePath)); + + if (!File.Exists(fullPath)) + { + throw new InvalidOperationException(string.Format("Can't find file {0}", literalRelativePath)); + } + + // TODO: extract utility like NuGet.PathUtility.GetPathWithForwardSlashes() + literalIncludedFiles.Add(fullPath.Replace('\\', '/')); + } + + // globing files + var globbingResults = _matcher.GetResultsInFullPath(rootPath); + + // if there is no results generated in globing, skip excluding other groups + // for performance optimization. + if (globbingResults.Any()) + { + foreach (var group in _excludeGroups) + { + globbingResults = globbingResults.Except(group.SearchFiles(rootPath)); + } + } + + return globbingResults.Concat(literalIncludedFiles).Distinct(); + } + + public override string ToString() + { + return string.Format("Pattern group: Literals [{0}] Includes [{1}] Excludes [{2}]", string.Join(", ", IncludeLiterals), string.Join(", ", IncludePatterns), string.Join(", ", ExcludePatterns)); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/PatternsCollectionHelper.cs b/src/Microsoft.Extensions.ProjectModel/PatternsCollectionHelper.cs new file mode 100644 index 000000000..6233a9c71 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/PatternsCollectionHelper.cs @@ -0,0 +1,107 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Extensions.ProjectModel +{ + internal static class PatternsCollectionHelper + { + private static readonly char[] PatternSeparator = new[] { ';' }; + + public static IEnumerable GetPatternsCollection(JObject rawProject, + string projectDirectory, + string projectFilePath, + string propertyName, + IEnumerable defaultPatterns = null, + bool literalPath = false) + { + defaultPatterns = defaultPatterns ?? Enumerable.Empty(); + + var prop = rawProject.Property(propertyName); + if (prop == null) + { + return CreateCollection(projectDirectory, propertyName, defaultPatterns, literalPath); + } + + try + { + var valueInString = prop.Value.Value(); + if (valueInString != null) + { + return CreateCollection(projectDirectory, propertyName, new string[] { valueInString }, literalPath); + } + + var valuesInArray = prop.Value.Value(); + if (valuesInArray != null) + { + return CreateCollection(projectDirectory, propertyName, valuesInArray.Select(s => s.ToString()), literalPath); + } + } + catch (Exception ex) + { + throw FileFormatException.Create(ex, prop.Value, projectFilePath); + } + + throw FileFormatException.Create("Value must be either string or array.", prop.Value, projectFilePath); + } + + private static IEnumerable CreateCollection(string projectDirectory, string propertyName, IEnumerable patternsStrings, bool literalPath) + { + var patterns = patternsStrings.SelectMany(patternsString => GetSourcesSplit(patternsString)) + .Select(patternString => patternString.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar)); + + foreach (var pattern in patterns) + { + if (Path.IsPathRooted(pattern)) + { + throw new InvalidOperationException($"The '{propertyName}' property cannot be a rooted path."); + } + + if (literalPath && pattern.Contains('*')) + { + throw new InvalidOperationException($"The '{propertyName}' property cannot contain wildcard characters."); + } + } + + return new List(patterns.Select(pattern => FolderToPattern(pattern, projectDirectory))); + } + + private static IEnumerable GetSourcesSplit(string sourceDescription) + { + if (string.IsNullOrEmpty(sourceDescription)) + { + return Enumerable.Empty(); + } + + return sourceDescription.Split(PatternSeparator, StringSplitOptions.RemoveEmptyEntries); + } + + private static string FolderToPattern(string candidate, string projectDir) + { + // This conversion is needed to support current template + + // If it's already a pattern, no change is needed + if (candidate.Contains('*')) + { + return candidate; + } + + // If the given string ends with a path separator, or it is an existing directory + // we convert this folder name to a pattern matching all files in the folder + if (candidate.EndsWith(@"\") || + candidate.EndsWith("/") || + Directory.Exists(Path.Combine(projectDir, candidate))) + { + return Path.Combine(candidate, "**", "*"); + } + + // Otherwise, it represents a single file + return candidate; + } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/Project.cs b/src/Microsoft.Extensions.ProjectModel/Project.cs new file mode 100644 index 000000000..f093077de --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Project.cs @@ -0,0 +1,200 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IO; +using Microsoft.Extensions.ProjectModel.Graph; +using Microsoft.Extensions.ProjectModel.Utilities; +using NuGet.Frameworks; +using NuGet.Versioning; + +namespace Microsoft.Extensions.ProjectModel +{ + public class Project + { + public static readonly string FileName = "project.json"; + + // REVIEW: It's kinda hacky making these internal but the reader needs to set them + internal Dictionary _targetFrameworks = new Dictionary(); + internal Dictionary _compilerOptionsByFramework = new Dictionary(); + internal Dictionary _compilerOptionsByConfiguration = new Dictionary(StringComparer.OrdinalIgnoreCase); + + internal CompilerOptions _defaultCompilerOptions; + internal TargetFrameworkInformation _defaultTargetFrameworkConfiguration; + + public Project() + { + } + + public string ProjectFilePath { get; set; } + + public string ProjectDirectory + { + get + { + return Path.GetDirectoryName(ProjectFilePath); + } + } + + public string Name { get; set; } + + public string Title { get; set; } + + public string Description { get; set; } + + public string Copyright { get; set; } + + public string Summary { get; set; } + + public string Language { get; set; } + + public string ReleaseNotes { get; set; } + + public string[] Authors { get; set; } + + public string[] Owners { get; set; } + + public bool EmbedInteropTypes { get; set; } + + public NuGetVersion Version { get; set; } + + public Version AssemblyFileVersion { get; set; } + + public IList Dependencies { get; set; } + + public string WebRoot { get; set; } + + public string EntryPoint { get; set; } + + public string ProjectUrl { get; set; } + + public string LicenseUrl { get; set; } + + public string IconUrl { get; set; } + + public bool RequireLicenseAcceptance { get; set; } + + public string[] Tags { get; set; } + + public bool IsLoadable { get; set; } + + public ProjectFilesCollection Files { get; set; } + + public IDictionary Commands { get; } = new Dictionary(StringComparer.OrdinalIgnoreCase); + + public IDictionary> Scripts { get; } = new Dictionary>(StringComparer.OrdinalIgnoreCase); + + public IEnumerable GetTargetFrameworks() + { + return _targetFrameworks.Values; + } + + public IEnumerable GetConfigurations() + { + return _compilerOptionsByConfiguration.Keys; + } + + public static bool HasProjectFile(string path) + { + string projectPath = Path.Combine(path, FileName); + + return File.Exists(projectPath); + } + + public static bool TryGetProject(string path, out Project project, ICollection diagnostics = null) + { + project = null; + + string projectPath = null; + + if (string.Equals(Path.GetFileName(path), FileName, StringComparison.OrdinalIgnoreCase)) + { + projectPath = path; + path = Path.GetDirectoryName(path); + } + else if (!HasProjectFile(path)) + { + return false; + } + else + { + projectPath = Path.Combine(path, FileName); + } + + // Assume the directory name is the project name if none was specified + var projectName = PathUtility.GetDirectoryName(path); + projectPath = Path.GetFullPath(projectPath); + + if (!File.Exists(projectPath)) + { + return false; + } + + try + { + using (var stream = File.OpenRead(projectPath)) + { + var reader = new ProjectReader(); + project = reader.ReadProject(stream, projectName, projectPath, diagnostics); + } + } + catch (Exception ex) + { + throw FileFormatException.Create(ex, projectPath); + } + + return true; + } + + public CompilerOptions GetCompilerOptions(NuGetFramework targetFramework, + string configurationName) + { + // Get all project options and combine them + var rootOptions = GetCompilerOptions(); + var configurationOptions = configurationName != null ? GetCompilerOptions(configurationName) : null; + var targetFrameworkOptions = targetFramework != null ? GetCompilerOptions(targetFramework) : null; + + // Combine all of the options + return CompilerOptions.Combine(rootOptions, configurationOptions, targetFrameworkOptions); + } + + public TargetFrameworkInformation GetTargetFramework(NuGetFramework targetFramework) + { + TargetFrameworkInformation targetFrameworkInfo = null; + if (targetFramework != null && _targetFrameworks.TryGetValue(targetFramework, out targetFrameworkInfo)) + { + return targetFrameworkInfo; + } + + return targetFrameworkInfo ?? _defaultTargetFrameworkConfiguration; + } + + private CompilerOptions GetCompilerOptions() + { + return _defaultCompilerOptions; + } + + private CompilerOptions GetCompilerOptions(string configurationName) + { + CompilerOptions options; + if (_compilerOptionsByConfiguration.TryGetValue(configurationName, out options)) + { + return options; + } + + return null; + } + + private CompilerOptions GetCompilerOptions(NuGetFramework frameworkName) + { + CompilerOptions options; + if (_compilerOptionsByFramework.TryGetValue(frameworkName, out options)) + { + return options; + } + + return null; + } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/ProjectContext.cs b/src/Microsoft.Extensions.ProjectModel/ProjectContext.cs new file mode 100644 index 000000000..df5a4da33 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/ProjectContext.cs @@ -0,0 +1,114 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.Versioning; +using Microsoft.Extensions.ProjectModel.Compilation; +using Microsoft.Extensions.ProjectModel.Graph; +using Microsoft.Extensions.ProjectModel.Resolution; +using NuGet.Frameworks; + +namespace Microsoft.Extensions.ProjectModel +{ + // NOTE(anurse): Copied from ApplicationHostContext in DNX. This name seemed more appropriate for this :) + public class ProjectContext + { + public Project Project { get; } + + public GlobalSettings GlobalSettings { get; } + + // TODO: Remove this, it's kinda hacky + public ProjectDescription RootProject { get; } + + public NuGetFramework TargetFramework { get; } + + public string RuntimeIdentifier { get; } + + public string RootDirectory => GlobalSettings.DirectoryPath; + + public string ProjectDirectory => Project.ProjectDirectory; + + public string PackagesDirectory { get; } + + public FrameworkReferenceResolver FrameworkResolver { get; } + + public LibraryManager LibraryManager { get; } + + internal ProjectContext( + Project project, + GlobalSettings globalSettings, + ProjectDescription rootProject, + NuGetFramework targetFramework, + string runtimeIdentifier, + string packagesDirectory, + FrameworkReferenceResolver frameworkResolver, + LibraryManager libraryManager) + { + Project = project; + GlobalSettings = globalSettings; + RootProject = rootProject; + TargetFramework = targetFramework; + RuntimeIdentifier = runtimeIdentifier; + PackagesDirectory = packagesDirectory; + FrameworkResolver = frameworkResolver; + LibraryManager = libraryManager; + } + + public LibraryExporter CreateExporter(string configuration) + { + return new LibraryExporter(RootProject, LibraryManager, configuration); + } + + /// + /// Creates a project context for the project located at , + /// specifically in the context of the framework specified in + /// + public static ProjectContext Create(string projectPath, NuGetFramework framework) + { + return Create(projectPath, framework, Enumerable.Empty()); + } + + /// + /// Creates a project context for the project located at , + /// specifically in the context of the framework specified in + /// and the candidate runtime identifiers specified in + /// + public static ProjectContext Create(string projectPath, NuGetFramework framework, IEnumerable runtimeIdentifiers) + { + if(projectPath.EndsWith(Project.FileName)) + { + projectPath = Path.GetDirectoryName(projectPath); + } + return new ProjectContextBuilder() + { + ProjectDirectory = projectPath, + TargetFramework = framework, + RuntimeIdentifiers = runtimeIdentifiers + }.Build(); + } + + /// + /// Creates a project context for each framework located in the project at + /// + public static IEnumerable CreateContextForEachFramework(string projectPath) + { + if(!projectPath.EndsWith(Project.FileName)) + { + projectPath = Path.Combine(projectPath, Project.FileName); + } + var project = ProjectReader.GetProject(projectPath); + + foreach(var framework in project.GetTargetFrameworks()) + { + yield return new ProjectContextBuilder() + { + Project = project, + TargetFramework = framework.FrameworkName + }.Build(); + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/ProjectContextBuilder.cs b/src/Microsoft.Extensions.ProjectModel/ProjectContextBuilder.cs new file mode 100644 index 000000000..f7176b3c5 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/ProjectContextBuilder.cs @@ -0,0 +1,231 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.Extensions.ProjectModel.Graph; +using Microsoft.Extensions.ProjectModel.Resolution; +using NuGet.Frameworks; + +namespace Microsoft.Extensions.ProjectModel +{ + public class ProjectContextBuilder + { + public Project Project { get; set; } + + public LockFile LockFile { get; set; } + + public GlobalSettings GlobalSettings { get; set; } + + public NuGetFramework TargetFramework { get; set; } + + public IEnumerable RuntimeIdentifiers { get; set; } = Enumerable.Empty(); + + public string RootDirectory { get; set; } + + public string ProjectDirectory { get; set; } + + public string PackagesDirectory { get; set; } + + public ProjectContext Build() + { + ProjectDirectory = Project?.ProjectDirectory ?? ProjectDirectory; + + if (GlobalSettings == null) + { + GlobalSettings globalSettings; + if (GlobalSettings.TryGetGlobalSettings(ProjectDirectory, out globalSettings)) + { + GlobalSettings = globalSettings; + } + } + + RootDirectory = GlobalSettings?.DirectoryPath ?? RootDirectory; + PackagesDirectory = PackagesDirectory ?? PackageDependencyProvider.ResolveRepositoryPath(RootDirectory, GlobalSettings); + + LockFileLookup lockFileLookup = null; + + EnsureProjectLoaded(); + + var projectLockJsonPath = Path.Combine(ProjectDirectory, LockFile.FileName); + + if (LockFile == null && File.Exists(projectLockJsonPath)) + { + LockFile = LockFileReader.Read(projectLockJsonPath); + } + + var validLockFile = true; + string lockFileValidationMessage = null; + + if (LockFile != null) + { + validLockFile = (LockFile.Version == LockFile.CurrentVersion) && LockFile.IsValidForProject(Project, out lockFileValidationMessage); + + lockFileLookup = new LockFileLookup(LockFile); + } + + var libraries = new Dictionary(); + var projectResolver = new ProjectDependencyProvider(); + + var mainProject = projectResolver.GetDescription(TargetFramework, Project); + + // Add the main project + libraries.Add(mainProject.Identity.Name, mainProject); + + LockFileTarget target = null; + if (lockFileLookup != null) + { + target = SelectTarget(LockFile); + if (target != null) + { + var packageResolver = new PackageDependencyProvider(PackagesDirectory); + ScanLibraries(target, lockFileLookup, libraries, packageResolver, projectResolver); + } + } + + var frameworkReferenceResolver = new FrameworkReferenceResolver(); + var referenceAssemblyDependencyResolver = new ReferenceAssemblyDependencyResolver(frameworkReferenceResolver); + var unresolvedDependencyProvider = new UnresolvedDependencyProvider(); + + // Resolve the dependencies + ResolveDependencies(libraries, referenceAssemblyDependencyResolver, unresolvedDependencyProvider); + + // Create a library manager + var libraryManager = new LibraryManager(Project.ProjectFilePath, TargetFramework, libraries.Values.ToList()); + + AddLockFileDiagnostics(libraryManager, LockFile != null, validLockFile, lockFileValidationMessage); + + return new ProjectContext( + Project, + GlobalSettings, + mainProject, + TargetFramework, + target?.RuntimeIdentifier, + PackagesDirectory, + frameworkReferenceResolver, + libraryManager); + } + + private void AddLockFileDiagnostics(LibraryManager libraryManager, bool lockFileExists, bool validLockFile, string lockFileValidationMessage) + { + if (!lockFileExists) + { + libraryManager.AddGlobalDiagnostics(new DiagnosticMessage( + ErrorCodes.NU1009, + $"The expected lock file doesn't exist. Please run \"dnu restore\" to generate a new lock file.", + Path.Combine(Project.ProjectDirectory, LockFile.FileName), + DiagnosticMessageSeverity.Error)); + } + + if (!validLockFile) + { + libraryManager.AddGlobalDiagnostics(new DiagnosticMessage( + ErrorCodes.NU1006, + $"{lockFileValidationMessage}. Please run \"dnu restore\" to generate a new lock file.", + Path.Combine(Project.ProjectDirectory, LockFile.FileName), + DiagnosticMessageSeverity.Error)); + } + } + + private void ResolveDependencies(Dictionary libraries, ReferenceAssemblyDependencyResolver referenceAssemblyDependencyResolver, UnresolvedDependencyProvider unresolvedDependencyProvider) + { + foreach (var library in libraries.Values.ToList()) + { + if (Equals(library.Identity.Type, LibraryType.Package) && + !Directory.Exists(library.Path)) + { + // If the package path doesn't exist then mark this dependency as unresolved + library.Resolved = false; + } + + library.Framework = library.Framework ?? TargetFramework; + foreach (var dependency in library.Dependencies) + { + LibraryDescription dep; + if (!libraries.TryGetValue(dependency.Name, out dep)) + { + if (Equals(LibraryType.ReferenceAssembly, dependency.Type)) + { + dep = referenceAssemblyDependencyResolver.GetDescription(dependency, TargetFramework) ?? + unresolvedDependencyProvider.GetDescription(dependency, TargetFramework); + + dep.Framework = TargetFramework; + libraries[dependency.Name] = dep; + } + else + { + dep = unresolvedDependencyProvider.GetDescription(dependency, TargetFramework); + libraries[dependency.Name] = dep; + } + } + + dep.Parent = library; + } + } + } + + private void ScanLibraries(LockFileTarget target, LockFileLookup lockFileLookup, Dictionary libraries, PackageDependencyProvider packageResolver, ProjectDependencyProvider projectResolver) + { + foreach (var library in target.Libraries) + { + if (string.Equals(library.Type, "project")) + { + var projectLibrary = lockFileLookup.GetProject(library.Name); + + var path = Path.GetFullPath(Path.Combine(ProjectDirectory, projectLibrary.Path)); + + var projectDescription = projectResolver.GetDescription(library.Name, path, library); + + libraries.Add(projectDescription.Identity.Name, projectDescription); + } + else + { + var packageEntry = lockFileLookup.GetPackage(library.Name, library.Version); + + var packageDescription = packageResolver.GetDescription(packageEntry, library); + + libraries.Add(packageDescription.Identity.Name, packageDescription); + } + } + } + + private void EnsureProjectLoaded() + { + if (Project == null) + { + Project project; + if (Project.TryGetProject(ProjectDirectory, out project)) + { + Project = project; + } + else + { + throw new InvalidOperationException($"Unable to resolve project from {ProjectDirectory}"); + } + } + } + + private LockFileTarget SelectTarget(LockFile lockFile) + { + foreach (var runtimeIdentifier in RuntimeIdentifiers) + { + foreach (var scanTarget in lockFile.Targets) + { + if (Equals(scanTarget.TargetFramework, TargetFramework) && string.Equals(scanTarget.RuntimeIdentifier, runtimeIdentifier, StringComparison.Ordinal)) + { + return scanTarget; + } + } + } + + foreach (var scanTarget in lockFile.Targets) + { + if (Equals(scanTarget.TargetFramework, TargetFramework) && string.IsNullOrEmpty(scanTarget.RuntimeIdentifier)) + { + return scanTarget; + } + } + + return null; + } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/ProjectDescription.cs b/src/Microsoft.Extensions.ProjectModel/ProjectDescription.cs new file mode 100644 index 000000000..2d88bb2bf --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/ProjectDescription.cs @@ -0,0 +1,48 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Linq; +using Microsoft.Extensions.ProjectModel.Graph; + +namespace Microsoft.Extensions.ProjectModel +{ + public class ProjectDescription : LibraryDescription + { + // Create an unresolved project description + public ProjectDescription(string name, string path) + : base( + new LibraryRange(name, LibraryType.Unspecified), + new LibraryIdentity(name, LibraryType.Project), + path, + Enumerable.Empty(), + framework: null, + resolved: false, + compatible: false) + { } + + public ProjectDescription( + LibraryRange libraryRange, + Project project, + IEnumerable dependencies, + IEnumerable assemblies, + TargetFrameworkInformation targetFrameworkInfo, + bool resolved) : + base( + libraryRange, + new LibraryIdentity(project.Name, project.Version, LibraryType.Project), + project.ProjectFilePath, + dependencies, + targetFrameworkInfo.FrameworkName, + resolved, + compatible: true) + { + Project = project; + TargetFrameworkInfo = targetFrameworkInfo; + } + + public Project Project { get; } + + public TargetFrameworkInformation TargetFrameworkInfo { get; } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/ProjectFileDependencyGroup.cs b/src/Microsoft.Extensions.ProjectModel/ProjectFileDependencyGroup.cs new file mode 100644 index 000000000..8f9dbf1a3 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/ProjectFileDependencyGroup.cs @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using NuGet.Frameworks; + +namespace Microsoft.Extensions.ProjectModel +{ + public class ProjectFileDependencyGroup + { + public ProjectFileDependencyGroup(NuGetFramework frameworkName, IEnumerable dependencies) + { + FrameworkName = frameworkName; + Dependencies = dependencies; + } + + public NuGetFramework FrameworkName { get; } + + public IEnumerable Dependencies { get; } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/ProjectFilesCollection.cs b/src/Microsoft.Extensions.ProjectModel/ProjectFilesCollection.cs new file mode 100644 index 000000000..eea1009b2 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/ProjectFilesCollection.cs @@ -0,0 +1,201 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Linq; +using Microsoft.Extensions.ProjectModel.Utilities; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Extensions.ProjectModel +{ + public class ProjectFilesCollection + { + public static readonly string[] DefaultCompileBuiltInPatterns = new[] { @"**/*.cs" }; + public static readonly string[] DefaultPublishExcludePatterns = new[] { @"obj/**/*.*", @"bin/**/*.*", @"**/.*/**", @"**/global.json" }; + public static readonly string[] DefaultPreprocessPatterns = new[] { @"compiler/preprocess/**/*.cs" }; + public static readonly string[] DefaultSharedPatterns = new[] { @"compiler/shared/**/*.cs" }; + public static readonly string[] DefaultResourcesBuiltInPatterns = new[] { @"compiler/resources/**/*", "**/*.resx" }; + public static readonly string[] DefaultContentsBuiltInPatterns = new[] { @"**/*" }; + + public static readonly string[] DefaultBuiltInExcludePatterns = new[] { "bin/**", "obj/**", "**/*.xproj" }; + + public static readonly string PackIncludePropertyName = "packInclude"; + + private PatternGroup _sharedPatternsGroup; + private PatternGroup _resourcePatternsGroup; + private PatternGroup _preprocessPatternsGroup; + private PatternGroup _compilePatternsGroup; + private PatternGroup _contentPatternsGroup; + private IDictionary _namedResources; + private IEnumerable _publishExcludePatterns; + private IEnumerable _packInclude; + + private readonly string _projectDirectory; + private readonly string _projectFilePath; + + private JObject _rawProject; + private bool _initialized; + + internal ProjectFilesCollection(JObject rawProject, string projectDirectory, string projectFilePath) + { + _projectDirectory = projectDirectory; + _projectFilePath = projectFilePath; + _rawProject = rawProject; + } + + internal void EnsureInitialized() + { + if (_initialized) + { + return; + } + + var excludeBuiltIns = PatternsCollectionHelper.GetPatternsCollection(_rawProject, _projectDirectory, _projectFilePath, "excludeBuiltIn", DefaultBuiltInExcludePatterns); + var excludePatterns = PatternsCollectionHelper.GetPatternsCollection(_rawProject, _projectDirectory, _projectFilePath, "exclude") + .Concat(excludeBuiltIns); + var contentBuiltIns = PatternsCollectionHelper.GetPatternsCollection(_rawProject, _projectDirectory, _projectFilePath, "contentBuiltIn", DefaultContentsBuiltInPatterns); + var compileBuiltIns = PatternsCollectionHelper.GetPatternsCollection(_rawProject, _projectDirectory, _projectFilePath, "compileBuiltIn", DefaultCompileBuiltInPatterns); + var resourceBuiltIns = PatternsCollectionHelper.GetPatternsCollection(_rawProject, _projectDirectory, _projectFilePath, "resourceBuiltIn", DefaultResourcesBuiltInPatterns); + + _publishExcludePatterns = PatternsCollectionHelper.GetPatternsCollection(_rawProject, _projectDirectory, _projectFilePath, "publishExclude", DefaultPublishExcludePatterns); + + _sharedPatternsGroup = PatternGroup.Build(_rawProject, _projectDirectory, _projectFilePath, "shared", fallbackIncluding: DefaultSharedPatterns, additionalExcluding: excludePatterns); + + _resourcePatternsGroup = PatternGroup.Build(_rawProject, _projectDirectory, _projectFilePath, "resource", additionalIncluding: resourceBuiltIns, additionalExcluding: excludePatterns); + + _preprocessPatternsGroup = PatternGroup.Build(_rawProject, _projectDirectory, _projectFilePath, "preprocess", fallbackIncluding: DefaultPreprocessPatterns, additionalExcluding: excludePatterns) + .ExcludeGroup(_sharedPatternsGroup) + .ExcludeGroup(_resourcePatternsGroup); + + _compilePatternsGroup = PatternGroup.Build(_rawProject, _projectDirectory, _projectFilePath, "compile", additionalIncluding: compileBuiltIns, additionalExcluding: excludePatterns) + .ExcludeGroup(_sharedPatternsGroup) + .ExcludeGroup(_preprocessPatternsGroup) + .ExcludeGroup(_resourcePatternsGroup); + + _contentPatternsGroup = PatternGroup.Build(_rawProject, _projectDirectory, _projectFilePath, "content", additionalIncluding: contentBuiltIns, additionalExcluding: excludePatterns.Concat(_publishExcludePatterns)) + .ExcludeGroup(_compilePatternsGroup) + .ExcludeGroup(_preprocessPatternsGroup) + .ExcludeGroup(_sharedPatternsGroup) + .ExcludeGroup(_resourcePatternsGroup); + + _namedResources = NamedResourceReader.ReadNamedResources(_rawProject, _projectFilePath); + + // Files to be packed along with the project + var packIncludeJson = _rawProject[PackIncludePropertyName] as JObject; + if (packIncludeJson != null) + { + _packInclude = packIncludeJson + .Properties() + .Select(prop => new PackIncludeEntry(prop.Name, prop.Value)) + .ToList(); + } + else + { + _packInclude = new List(); + } + + _initialized = true; + _rawProject = null; + } + + public IEnumerable PackInclude + { + get + { + EnsureInitialized(); + return _packInclude; + } + } + + public IEnumerable SourceFiles + { + get { return CompilePatternsGroup.SearchFiles(_projectDirectory).Distinct(); } + } + + public IEnumerable PreprocessSourceFiles + { + get { return PreprocessPatternsGroup.SearchFiles(_projectDirectory).Distinct(); } + } + + public IDictionary ResourceFiles + { + get + { + var resources = ResourcePatternsGroup + .SearchFiles(_projectDirectory) + .Distinct() + .ToDictionary(res => res, res => (string)null); + + NamedResourceReader.ApplyNamedResources(_namedResources, resources); + + return resources; + } + } + + public IEnumerable SharedFiles + { + get { return SharedPatternsGroup.SearchFiles(_projectDirectory).Distinct(); } + } + + public IEnumerable GetFilesForBundling(bool includeSource, IEnumerable additionalExcludePatterns) + { + var patternGroup = new PatternGroup(ContentPatternsGroup.IncludePatterns, + ContentPatternsGroup.ExcludePatterns.Concat(additionalExcludePatterns), + ContentPatternsGroup.IncludeLiterals); + if (!includeSource) + { + foreach (var excludedGroup in ContentPatternsGroup.ExcludePatternsGroup) + { + patternGroup.ExcludeGroup(excludedGroup); + } + } + + return patternGroup.SearchFiles(_projectDirectory); + } + + internal PatternGroup CompilePatternsGroup + { + get + { + EnsureInitialized(); + return _compilePatternsGroup; + } + } + + internal PatternGroup SharedPatternsGroup + { + get + { + EnsureInitialized(); + return _sharedPatternsGroup; + } + } + + internal PatternGroup ResourcePatternsGroup + { + get + { + EnsureInitialized(); + return _resourcePatternsGroup; + } + } + + internal PatternGroup PreprocessPatternsGroup + { + get + { + EnsureInitialized(); + return _preprocessPatternsGroup; + } + } + + internal PatternGroup ContentPatternsGroup + { + get + { + EnsureInitialized(); + return _contentPatternsGroup; + } + } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/ProjectReader.cs b/src/Microsoft.Extensions.ProjectModel/ProjectReader.cs new file mode 100644 index 000000000..0ab646374 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/ProjectReader.cs @@ -0,0 +1,519 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.Extensions.ProjectModel.Graph; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using NuGet.Frameworks; +using NuGet.Versioning; + +namespace Microsoft.Extensions.ProjectModel +{ + internal class ProjectReader + { + public static Project GetProject(string projectFile) + { + return GetProject(projectFile, new List()); + } + + public static Project GetProject(string projectFile, ICollection diagnostics) + { + var name = Path.GetFileName(Path.GetDirectoryName(projectFile)); + using (var stream = new FileStream(projectFile, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + return new ProjectReader().ReadProject(stream, name, projectFile, diagnostics); + } + } + + public Project ReadProject(Stream stream, string projectName, string projectPath, ICollection diagnostics) + { + var project = new Project(); + + JObject rawProject; + using (var reader = new StreamReader(stream)) + { + rawProject = JObject.Parse(reader.ReadToEnd()); + } + if (rawProject == null) + { + throw FileFormatException.Create( + "The JSON file can't be deserialized to a JSON object.", + projectPath); + } + + // Meta-data properties + project.Name = projectName; + project.ProjectFilePath = Path.GetFullPath(projectPath); + + var version = rawProject["version"]; + if (version == null) + { + project.Version = new NuGetVersion("1.0.0"); + } + else + { + try + { + var buildVersion = Environment.GetEnvironmentVariable("DNX_BUILD_VERSION"); + project.Version = SpecifySnapshot(version.Value(), buildVersion); + } + catch (Exception ex) + { + throw FileFormatException.Create(ex, version, project.ProjectFilePath); + } + } + + var fileVersion = Environment.GetEnvironmentVariable("DNX_ASSEMBLY_FILE_VERSION"); + if (string.IsNullOrWhiteSpace(fileVersion)) + { + project.AssemblyFileVersion = project.Version.Version; + } + else + { + try + { + var simpleVersion = project.Version.Version; + project.AssemblyFileVersion = new Version(simpleVersion.Major, + simpleVersion.Minor, + simpleVersion.Build, + int.Parse(fileVersion)); + } + catch (FormatException ex) + { + throw new FormatException("The assembly file version is invalid: " + fileVersion, ex); + } + } + + project.Description = rawProject.Value("description"); + project.Summary = rawProject.Value("summary"); + project.Copyright = rawProject.Value("copyright"); + project.Title = rawProject.Value("title"); + project.WebRoot = rawProject.Value("webroot"); + project.EntryPoint = rawProject.Value("entryPoint"); + project.ProjectUrl = rawProject.Value("projectUrl"); + project.LicenseUrl = rawProject.Value("licenseUrl"); + project.IconUrl = rawProject.Value("iconUrl"); + + project.Authors = rawProject.ValueAsStringArray("authors"); + project.Owners = rawProject.ValueAsStringArray("owners"); + project.Tags = rawProject.ValueAsStringArray("tags"); + + project.Language = rawProject.Value("language"); + project.ReleaseNotes = rawProject.Value("releaseNotes"); + + project.RequireLicenseAcceptance = rawProject.Value("requireLicenseAcceptance") ?? false; + project.IsLoadable = rawProject.Value("loadable") ?? true; + + project.Dependencies = new List(); + + // Project files + project.Files = new ProjectFilesCollection(rawProject, project.ProjectDirectory, project.ProjectFilePath); + + var commands = rawProject.Value("commands"); + if (commands != null) + { + foreach (var prop in commands.Properties()) + { + var value = prop.Value.Value(); + if (value != null) + { + project.Commands[prop.Name] = value; + } + } + } + + var scripts = rawProject.Value("scripts"); + if (scripts != null) + { + foreach (var prop in scripts.Properties()) + { + var stringValue = prop.Value(); + if (stringValue != null) + { + project.Scripts[prop.Name] = new string[] { stringValue }; + continue; + } + + var arrayValue = scripts.ValueAsStringArray(prop.Name); + if (arrayValue != null) + { + project.Scripts[prop.Name] = arrayValue; + continue; + } + + throw FileFormatException.Create( + string.Format("The value of a script in {0} can only be a string or an array of strings", Project.FileName), + prop.Value, + project.ProjectFilePath); + } + } + + BuildTargetFrameworksAndConfigurations(project, rawProject, diagnostics); + + PopulateDependencies( + project.ProjectFilePath, + project.Dependencies, + rawProject, + "dependencies", + isGacOrFrameworkReference: false); + + return project; + } + + private static NuGetVersion SpecifySnapshot(string version, string snapshotValue) + { + if (version.EndsWith("-*")) + { + if (string.IsNullOrEmpty(snapshotValue)) + { + version = version.Substring(0, version.Length - 2); + } + else + { + version = version.Substring(0, version.Length - 1) + snapshotValue; + } + } + + return NuGetVersion.Parse(version); + } + + private static void PopulateDependencies( + string projectPath, + IList results, + JObject settings, + string propertyName, + bool isGacOrFrameworkReference) + { + var dependencies = settings.Value(propertyName); + if (dependencies != null) + { + foreach (var dependencyKey in dependencies.Properties()) + { + if (string.IsNullOrEmpty(dependencyKey.Name)) + { + throw FileFormatException.Create( + "Unable to resolve dependency ''.", + dependencyKey.Value, + projectPath); + } + + var dependencyValue = dependencyKey.Value; + string dependencyVersionAsString = null; + LibraryDependencyType dependencyTypeValue = LibraryDependencyType.Default; + LibraryType target = isGacOrFrameworkReference ? LibraryType.ReferenceAssembly : LibraryType.Unspecified; + + if (dependencyValue.Type == JTokenType.Object) + { + // "dependencies" : { "Name" : { "version": "1.0", "type": "build", "target": "project" } } + var dependencyValueAsObject = (JObject)dependencyValue; + dependencyVersionAsString = dependencyValueAsObject.Value("version"); + + // Remove support for flags (we only support build and nothing right now) + var type = dependencyValueAsObject.Value("type"); + if (type != null) + { + dependencyTypeValue = LibraryDependencyType.Parse(type); + } + + // Read the target if specified + if (!isGacOrFrameworkReference) + { + LibraryType parsedTarget; + var targetStr = dependencyValueAsObject.Value("target"); + if (!string.IsNullOrEmpty(targetStr) && LibraryType.TryParse(targetStr, out parsedTarget)) + { + target = parsedTarget; + } + } + } + else if (dependencyValue.Type == JTokenType.String) + { + // "dependencies" : { "Name" : "1.0" } + dependencyVersionAsString = dependencyValue.Value(); + } + else + { + throw FileFormatException.Create( + string.Format("Invalid dependency version: {0}. The format is not recognizable.", dependencyKey), + dependencyValue, + projectPath); + } + + VersionRange dependencyVersionRange = null; + if (!string.IsNullOrEmpty(dependencyVersionAsString)) + { + try + { + dependencyVersionRange = VersionRange.Parse(dependencyVersionAsString); + } + catch (Exception ex) + { + throw FileFormatException.Create( + ex, + dependencyValue, + projectPath); + } + } + + results.Add(new LibraryRange( + dependencyKey.Name, + dependencyVersionRange, + target, + dependencyTypeValue, + projectPath, + ((IJsonLineInfo)dependencyKey.Value).LineNumber, + ((IJsonLineInfo)dependencyKey.Value).LinePosition)); + + //{ + // LibraryRange = new LibraryRange(dependencyKey, isGacOrFrameworkReference) + // { + // VersionRange = dependencyVersionRange, + // FileName = projectPath, + // Line = dependencyValue.Line, + // Column = dependencyValue.Column, + // Target = target + // }, + // Type = dependencyTypeValue + //}); + } + } + } + + private static bool TryGetStringEnumerable(JObject parent, string property, out IEnumerable result) + { + var collection = new List(); + var value = parent[property]; + if (value.Type == JTokenType.String) + { + collection.Add(value.Value()); + } + else if (value.Type == JTokenType.Array) + { + collection.AddRange(value.Value()); + } + else + { + result = null; + return false; + } + + result = collection.SelectMany(v => v.Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries)); + return true; + } + + private void BuildTargetFrameworksAndConfigurations(Project project, JObject projectJsonObject, ICollection diagnostics) + { + // Get the shared compilationOptions + project._defaultCompilerOptions = GetCompilationOptions(projectJsonObject) ?? new CompilerOptions(); + + project._defaultTargetFrameworkConfiguration = new TargetFrameworkInformation + { + Dependencies = new List().AsReadOnly() + }; + + // Add default configurations + project._compilerOptionsByConfiguration["Debug"] = new CompilerOptions + { + Defines = new[] { "DEBUG", "TRACE" }, + Optimize = false + }; + + project._compilerOptionsByConfiguration["Release"] = new CompilerOptions + { + Defines = new[] { "RELEASE", "TRACE" }, + Optimize = true + }; + + // The configuration node has things like debug/release compiler settings + /* + { + "configurations": { + "Debug": { + }, + "Release": { + } + } + } + */ + + var configurationsSection = projectJsonObject.Value("configurations"); + if (configurationsSection != null) + { + foreach (var configKey in configurationsSection.Properties()) + { + var compilerOptions = GetCompilationOptions(configKey.Value()); + + // Only use this as a configuration if it's not a target framework + project._compilerOptionsByConfiguration[configKey.Name] = compilerOptions; + } + } + + // The frameworks node is where target frameworks go + /* + { + "frameworks": { + "net45": { + }, + "dnxcore50": { + } + } + } + */ + + var frameworks = projectJsonObject.Value("frameworks"); + if (frameworks != null) + { + foreach (var frameworkKey in frameworks.Properties()) + { + try + { + var frameworkToken = frameworks.Value(frameworkKey.Name); + var success = BuildTargetFrameworkNode(project, frameworkKey.Name, frameworkToken); + if (!success) + { + diagnostics?.Add( + new DiagnosticMessage( + ErrorCodes.NU1008, + $"\"{frameworkKey}\" is an unsupported framework.", + project.ProjectFilePath, + DiagnosticMessageSeverity.Error, + frameworkToken)); + } + } + catch (Exception ex) + { + throw FileFormatException.Create(ex, frameworkKey.Value, project.ProjectFilePath); + } + } + } + } + + /// + /// Parse a Json object which represents project configuration for a specified framework + /// + /// The name of the framework + /// The Json object represent the settings + /// Returns true if it successes. + private bool BuildTargetFrameworkNode(Project project, string frameworkKey, JObject frameworkValue) + { + // If no compilation options are provided then figure them out from the node + var compilerOptions = GetCompilationOptions(frameworkValue) ?? + new CompilerOptions(); + + var frameworkName = NuGetFramework.Parse(frameworkKey); + + // If it's not unsupported then keep it + if (frameworkName.IsUnsupported) + { + // REVIEW: Should we skip unsupported target frameworks + return false; + } + + // Add the target framework specific define + var defines = new HashSet(compilerOptions.Defines ?? Enumerable.Empty()); + var frameworkDefine = MakeDefaultTargetFrameworkDefine(frameworkName); + + if (!string.IsNullOrEmpty(frameworkDefine)) + { + defines.Add(frameworkDefine); + } + + compilerOptions.Defines = defines; + + var targetFrameworkInformation = new TargetFrameworkInformation + { + FrameworkName = frameworkName, + Dependencies = new List() + }; + + var frameworkDependencies = new List(); + + PopulateDependencies( + project.ProjectFilePath, + frameworkDependencies, + frameworkValue, + "dependencies", + isGacOrFrameworkReference: false); + + var frameworkAssemblies = new List(); + PopulateDependencies( + project.ProjectFilePath, + frameworkAssemblies, + frameworkValue, + "frameworkAssemblies", + isGacOrFrameworkReference: true); + + frameworkDependencies.AddRange(frameworkAssemblies); + targetFrameworkInformation.Dependencies = frameworkDependencies; + + targetFrameworkInformation.WrappedProject = frameworkValue.Value("wrappedProject"); + + var binNode = frameworkValue.Value("bin"); + if (binNode != null) + { + targetFrameworkInformation.AssemblyPath = binNode.Value("assembly"); + targetFrameworkInformation.PdbPath = binNode.Value("pdb"); + } + + project._compilerOptionsByFramework[frameworkName] = compilerOptions; + project._targetFrameworks[frameworkName] = targetFrameworkInformation; + + return true; + } + + private static CompilerOptions GetCompilationOptions(JObject rawObject) + { + var rawOptions = rawObject.Value("compilationOptions"); + if (rawOptions == null) + { + return null; + } + + return new CompilerOptions + { + Defines = rawOptions.Value("define"), + LanguageVersion = rawOptions.Value("languageVersion"), + AllowUnsafe = rawOptions.Value("allowUnsafe"), + Platform = rawOptions.Value("platform"), + WarningsAsErrors = rawOptions.Value("warningsAsErrors"), + Optimize = rawOptions.Value("optimize"), + KeyFile = rawOptions.Value("keyFile"), + DelaySign = rawOptions.Value("delaySign"), + StrongName = rawOptions.Value("strongName"), + EmitEntryPoint = rawOptions.Value("emitEntryPoint") + }; + } + + public static string MakeDefaultTargetFrameworkDefine(NuGetFramework targetFramework) + { + var shortName = targetFramework.GetTwoDigitShortFolderName(); + + if (targetFramework.IsPCL) + { + return null; + } + + var candidateName = shortName.ToUpperInvariant(); + + // Replace '-', '.', and '+' in the candidate name with '_' because TFMs with profiles use those (like "net40-client") + // and we want them representable as defines (i.e. "NET40_CLIENT") + candidateName = candidateName.Replace('-', '_').Replace('+', '_').Replace('.', '_'); + + // We require the following from our Target Framework Define names + // Starts with A-Z or _ + // Contains only A-Z, 0-9 and _ + if (!string.IsNullOrEmpty(candidateName) && + (char.IsLetter(candidateName[0]) || candidateName[0] == '_') && + candidateName.All(c => Char.IsLetterOrDigit(c) || c == '_')) + { + return candidateName; + } + + return null; + } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/ProjectRootResolver.cs b/src/Microsoft.Extensions.ProjectModel/ProjectRootResolver.cs new file mode 100644 index 000000000..4e4d5757d --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/ProjectRootResolver.cs @@ -0,0 +1,31 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.IO; + +namespace Microsoft.Extensions.ProjectModel +{ + public static class ProjectRootResolver + { + public static readonly string GlobalFileName = "global.json"; + public static string ResolveRootDirectory(string projectPath) + { + var di = new DirectoryInfo(projectPath); + + while (di.Parent != null) + { + var globalJsonPath = Path.Combine(di.FullName, GlobalFileName); + + if (File.Exists(globalJsonPath)) + { + return di.FullName; + } + + di = di.Parent; + } + + // If we don't find any files then make the project folder the root + return projectPath; + } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/Properties/AssemblyInfo.cs b/src/Microsoft.Extensions.ProjectModel/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..cff2ded09 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Properties/AssemblyInfo.cs @@ -0,0 +1,23 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Microsoft.Extensions.ProjectModel")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Microsoft.Extensions.ProjectModel")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("303677d5-7312-4c3f-baee-beb1a9bd9fe6")] diff --git a/src/Microsoft.Extensions.ProjectModel/Resolution/FrameworkDefinitions.cs b/src/Microsoft.Extensions.ProjectModel/Resolution/FrameworkDefinitions.cs new file mode 100644 index 000000000..cdb4d7660 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Resolution/FrameworkDefinitions.cs @@ -0,0 +1,992 @@ +using System; +using System.IO; +using System.Runtime.CompilerServices; +using NuGet.Frameworks; + +namespace Microsoft.Extensions.ProjectModel.Resolution +{ + internal static class FrameworkDefinitions + { + private const string NetFrameworkIdentifier = ".NETFramework"; + + public static bool TryPopulateFrameworkFastPath(NuGetFramework framework, string referenceAssembliesPath, out FrameworkInformation frameworkInfo) + { + if(!string.IsNullOrEmpty(framework.Profile)) + { + // We don't have embedded framework info for Client Profile + frameworkInfo = null; + return false; + } + + // 4.6 + if (Equals(framework, FrameworkConstants.CommonFrameworks.Net46)) + { + frameworkInfo = PopulateNet46(referenceAssembliesPath); + return true; + } + + // 4.5.2 + if (Equals(framework, FrameworkConstants.CommonFrameworks.Net452)) + { + frameworkInfo = PopulateNet452(referenceAssembliesPath); + return true; + } + + // 4.5.1 + if (Equals(framework, FrameworkConstants.CommonFrameworks.Net451)) + { + frameworkInfo = PopulateNet451(referenceAssembliesPath); + return true; + } + + // 4.5 + if (Equals(framework, FrameworkConstants.CommonFrameworks.Net45)) + { + frameworkInfo = PopulateNet45(referenceAssembliesPath); + return true; + } + + // 4.0 + if (Equals(framework, FrameworkConstants.CommonFrameworks.Net4)) + { + frameworkInfo = PopulateNet40(referenceAssembliesPath); + return true; + } + + frameworkInfo = null; + return false; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static FrameworkInformation PopulateNet46(string referenceAssembliesPath) + { + // Generated framework information for .NETFramework,Version=v4.6 + var frameworkInfo = new FrameworkInformation(); + frameworkInfo.Path = Path.Combine(referenceAssembliesPath, ".NETFramework", "v4.6"); + frameworkInfo.RedistListPath = Path.Combine(referenceAssembliesPath, ".NETFramework", "v4.6", "RedistList", "FrameworkList.xml"); + frameworkInfo.Name = ".NET Framework 4.6"; + frameworkInfo.SearchPaths = new[] + { + frameworkInfo.Path, + Path.Combine(frameworkInfo.Path, "Facades") + }; + frameworkInfo.Assemblies["Accessibility"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Accessibility.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["CustomMarshalers"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "CustomMarshalers.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["ISymWrapper"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "ISymWrapper.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Activities.Build"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Activities.Build.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Conversion.v4.0"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Conversion.v4.0.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Engine"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Engine.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Framework"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Framework.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Tasks.v4.0"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Tasks.v4.0.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Utilities.v4.0"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Utilities.v4.0.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.CSharp"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.CSharp.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.JScript"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.JScript.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualBasic"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualBasic.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualBasic.Compatibility"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualBasic.Compatibility.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualBasic.Compatibility.Data"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualBasic.Compatibility.Data.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualC"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualC.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualC.STLCLR"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualC.STLCLR.dll"), Version = new Version(2, 0, 0, 0) }; + frameworkInfo.Assemblies["mscorlib"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "mscorlib.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationBuildTasks"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationBuildTasks.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationCore"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationCore.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Aero"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Aero.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Aero2"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Aero2.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.AeroLite"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.AeroLite.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Classic"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Classic.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Luna"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Luna.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Royale"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Royale.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["ReachFramework"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "ReachFramework.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["sysglobl"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "sysglobl.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities.Core.Presentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.Core.Presentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities.DurableInstancing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.DurableInstancing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities.Presentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.Presentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities.Statements"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.Statements.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.AddIn.Contract"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.AddIn.Contract.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.AddIn"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.AddIn.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.Composition"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ComponentModel.Composition.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.Composition.Registration"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ComponentModel.Composition.Registration.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.DataAnnotations"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ComponentModel.DataAnnotations.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Configuration"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Configuration.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Configuration.Install"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Configuration.Install.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Core"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Core.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.DataSetExtensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.DataSetExtensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Entity.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Entity.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Entity"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Entity.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Linq"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Linq.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.OracleClient"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.OracleClient.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Services.Client"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Services.Client.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Services.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Services.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Services"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Services.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.SqlXml"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.SqlXml.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Deployment"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Deployment.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Device"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Device.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.DirectoryServices.AccountManagement"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.DirectoryServices.AccountManagement.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.DirectoryServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.DirectoryServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.DirectoryServices.Protocols"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.DirectoryServices.Protocols.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Drawing.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Drawing.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Drawing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Drawing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Dynamic"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Dynamic.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.EnterpriseServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.EnterpriseServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IdentityModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IdentityModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IdentityModel.Selectors"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IdentityModel.Selectors.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IdentityModel.Services"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IdentityModel.Services.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IO.Log"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IO.Log.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IO.Compression"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IO.Compression.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IO.Compression.FileSystem"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IO.Compression.FileSystem.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Management"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Management.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Management.Instrumentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Management.Instrumentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Messaging"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Messaging.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Net.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net.Http"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Net.Http.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net.Http.WebRequest"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Net.Http.WebRequest.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Numerics"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Numerics.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Numerics.Vectors"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Numerics.Vectors.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Printing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Printing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Context"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Reflection.Context.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.DurableInstancing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.DurableInstancing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Caching"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Caching.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Remoting"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Remoting.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Serialization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization.Formatters.Soap"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Serialization.Formatters.Soap.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Security"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Security.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Activation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Activation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Activities"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Activities.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Channels"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Channels.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Discovery"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Discovery.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Routing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Routing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Web"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Web.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceProcess"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceProcess.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Speech"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Speech.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Transactions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Transactions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Abstractions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Abstractions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.ApplicationServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.ApplicationServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DataVisualization.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DataVisualization.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DataVisualization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DataVisualization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DynamicData.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DynamicData.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DynamicData"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DynamicData.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Entity.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Entity.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Entity"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Entity.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Extensions.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Extensions.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Extensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Extensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Mobile"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Mobile.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.RegularExpressions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.RegularExpressions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Routing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Routing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Services"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Services.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Controls.Ribbon"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Controls.Ribbon.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Forms.DataVisualization.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Forms.DataVisualization.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Forms.DataVisualization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Forms.DataVisualization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Forms"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Forms.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Input.Manipulations"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Input.Manipulations.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Presentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Presentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Workflow.Activities"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Workflow.Activities.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Workflow.ComponentModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Workflow.ComponentModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Workflow.Runtime"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Workflow.Runtime.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.WorkflowServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.WorkflowServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xaml"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Xaml.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Xml.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.Linq"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Xml.Linq.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.Serialization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Xml.Serialization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationClient"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationClient.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationClientsideProviders"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationClientsideProviders.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationProvider"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationProvider.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationTypes"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationTypes.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["WindowsBase"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "WindowsBase.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["WindowsFormsIntegration"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "WindowsFormsIntegration.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["XamlBuildTask"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "XamlBuildTask.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Collections"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Collections.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.Collections.Concurrent"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Collections.Concurrent.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ComponentModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.Annotations"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ComponentModel.Annotations.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.EventBasedAsync"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ComponentModel.EventBasedAsync.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Diagnostics.Contracts"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Diagnostics.Contracts.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Diagnostics.Debug"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Diagnostics.Debug.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.Diagnostics.Tools"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Diagnostics.Tools.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Diagnostics.Tracing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Diagnostics.Tracing.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.Dynamic.Runtime"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Dynamic.Runtime.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Globalization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Globalization.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.IO"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.IO.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Linq"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Linq.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Linq.Expressions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Linq.Expressions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Linq.Parallel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Linq.Parallel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Linq.Queryable"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Linq.Queryable.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net.NetworkInformation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Net.NetworkInformation.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.Net.Primitives"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Net.Primitives.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.Net.Requests"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Net.Requests.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ObjectModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ObjectModel.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.Reflection"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.Reflection.Emit"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Emit.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Emit.ILGeneration"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Emit.ILGeneration.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Emit.Lightweight"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Emit.Lightweight.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Extensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Extensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Primitives"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Primitives.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Resources.ResourceManager"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Resources.ResourceManager.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.dll"), Version = new Version(4, 0, 20, 0) }; + frameworkInfo.Assemblies["System.Runtime.Extensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Extensions.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.Runtime.Handles"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Handles.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.InteropServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.InteropServices.dll"), Version = new Version(4, 0, 20, 0) }; + frameworkInfo.Assemblies["System.Runtime.InteropServices.WindowsRuntime"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.InteropServices.WindowsRuntime.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Numerics"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Numerics.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization.Json"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Serialization.Json.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization.Primitives"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Serialization.Primitives.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization.Xml"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Serialization.Xml.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Security.Principal"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Security.Principal.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Duplex"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.Duplex.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Http"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.Http.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.NetTcp"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.NetTcp.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Primitives"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.Primitives.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Security"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.Security.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Text.Encoding"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Text.Encoding.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Text.Encoding.Extensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Text.Encoding.Extensions.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.Text.RegularExpressions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Text.RegularExpressions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Threading"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Threading.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.Threading.Tasks"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Threading.Tasks.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.Threading.Tasks.Parallel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Threading.Tasks.Parallel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Threading.Timer"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Threading.Timer.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.ReaderWriter"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Xml.ReaderWriter.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.Xml.XDocument"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Xml.XDocument.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.XmlSerializer"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Xml.XmlSerializer.dll"), Version = new Version(4, 0, 0, 0) }; + + return frameworkInfo; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static FrameworkInformation PopulateNet452(string referenceAssembliesPath) + { + // Generated framework information for .NETFramework,Version=v4.5.2 + var frameworkInfo = new FrameworkInformation(); + frameworkInfo.Path = Path.Combine(referenceAssembliesPath, ".NETFramework", "v4.5.2"); + frameworkInfo.RedistListPath = Path.Combine(referenceAssembliesPath, ".NETFramework", "v4.5.2", "RedistList", "FrameworkList.xml"); + frameworkInfo.Name = ".NET Framework 4.5.2"; + frameworkInfo.SearchPaths = new[] + { + frameworkInfo.Path, + Path.Combine(frameworkInfo.Path, "Facades") + }; + frameworkInfo.Assemblies["Accessibility"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Accessibility.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["CustomMarshalers"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "CustomMarshalers.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["ISymWrapper"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "ISymWrapper.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Activities.Build"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Activities.Build.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Conversion.v4.0"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Conversion.v4.0.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Engine"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Engine.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Framework"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Framework.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Tasks.v4.0"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Tasks.v4.0.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Utilities.v4.0"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Utilities.v4.0.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.CSharp"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.CSharp.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.JScript"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.JScript.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualBasic"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualBasic.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualBasic.Compatibility"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualBasic.Compatibility.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualBasic.Compatibility.Data"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualBasic.Compatibility.Data.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualC"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualC.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualC.STLCLR"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualC.STLCLR.dll"), Version = new Version(2, 0, 0, 0) }; + frameworkInfo.Assemblies["mscorlib"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "mscorlib.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationBuildTasks"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationBuildTasks.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationCore"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationCore.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Aero"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Aero.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Aero2"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Aero2.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.AeroLite"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.AeroLite.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Classic"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Classic.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Luna"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Luna.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Royale"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Royale.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["ReachFramework"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "ReachFramework.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["sysglobl"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "sysglobl.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities.Core.Presentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.Core.Presentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities.DurableInstancing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.DurableInstancing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities.Presentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.Presentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities.Statements"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.Statements.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.AddIn.Contract"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.AddIn.Contract.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.AddIn"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.AddIn.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.Composition"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ComponentModel.Composition.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.Composition.Registration"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ComponentModel.Composition.Registration.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.DataAnnotations"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ComponentModel.DataAnnotations.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Configuration"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Configuration.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Configuration.Install"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Configuration.Install.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Core"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Core.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.DataSetExtensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.DataSetExtensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Entity.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Entity.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Entity"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Entity.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Linq"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Linq.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.OracleClient"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.OracleClient.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Services.Client"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Services.Client.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Services.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Services.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Services"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Services.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.SqlXml"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.SqlXml.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Deployment"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Deployment.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Device"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Device.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.DirectoryServices.AccountManagement"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.DirectoryServices.AccountManagement.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.DirectoryServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.DirectoryServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.DirectoryServices.Protocols"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.DirectoryServices.Protocols.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Drawing.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Drawing.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Drawing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Drawing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Dynamic"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Dynamic.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.EnterpriseServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.EnterpriseServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IdentityModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IdentityModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IdentityModel.Selectors"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IdentityModel.Selectors.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IdentityModel.Services"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IdentityModel.Services.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IO.Log"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IO.Log.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IO.Compression"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IO.Compression.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IO.Compression.FileSystem"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IO.Compression.FileSystem.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Management"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Management.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Management.Instrumentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Management.Instrumentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Messaging"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Messaging.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Net.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net.Http"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Net.Http.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net.Http.WebRequest"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Net.Http.WebRequest.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Numerics"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Numerics.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Printing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Printing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Context"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Reflection.Context.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.DurableInstancing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.DurableInstancing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Caching"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Caching.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Remoting"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Remoting.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Serialization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization.Formatters.Soap"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Serialization.Formatters.Soap.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Security"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Security.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Activation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Activation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Activities"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Activities.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Channels"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Channels.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Discovery"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Discovery.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Routing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Routing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Web"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Web.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceProcess"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceProcess.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Speech"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Speech.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Transactions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Transactions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Abstractions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Abstractions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.ApplicationServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.ApplicationServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DataVisualization.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DataVisualization.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DataVisualization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DataVisualization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DynamicData.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DynamicData.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DynamicData"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DynamicData.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Entity.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Entity.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Entity"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Entity.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Extensions.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Extensions.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Extensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Extensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Mobile"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Mobile.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.RegularExpressions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.RegularExpressions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Routing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Routing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Services"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Services.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Controls.Ribbon"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Controls.Ribbon.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Forms.DataVisualization.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Forms.DataVisualization.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Forms.DataVisualization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Forms.DataVisualization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Forms"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Forms.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Input.Manipulations"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Input.Manipulations.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Presentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Presentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Workflow.Activities"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Workflow.Activities.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Workflow.ComponentModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Workflow.ComponentModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Workflow.Runtime"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Workflow.Runtime.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.WorkflowServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.WorkflowServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xaml"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Xaml.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Xml.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.Linq"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Xml.Linq.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.Serialization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Xml.Serialization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationClient"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationClient.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationClientsideProviders"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationClientsideProviders.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationProvider"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationProvider.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationTypes"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationTypes.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["WindowsBase"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "WindowsBase.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["WindowsFormsIntegration"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "WindowsFormsIntegration.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["XamlBuildTask"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "XamlBuildTask.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Collections"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Collections.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Collections.Concurrent"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Collections.Concurrent.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ComponentModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.Annotations"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ComponentModel.Annotations.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.EventBasedAsync"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ComponentModel.EventBasedAsync.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Diagnostics.Contracts"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Diagnostics.Contracts.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Diagnostics.Debug"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Diagnostics.Debug.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Diagnostics.Tools"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Diagnostics.Tools.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Diagnostics.Tracing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Diagnostics.Tracing.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.Dynamic.Runtime"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Dynamic.Runtime.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Globalization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Globalization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IO"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.IO.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Linq"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Linq.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Linq.Expressions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Linq.Expressions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Linq.Parallel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Linq.Parallel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Linq.Queryable"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Linq.Queryable.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net.NetworkInformation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Net.NetworkInformation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net.Primitives"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Net.Primitives.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net.Requests"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Net.Requests.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ObjectModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ObjectModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Emit"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Emit.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Emit.ILGeneration"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Emit.ILGeneration.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Emit.Lightweight"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Emit.Lightweight.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Extensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Extensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Primitives"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Primitives.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Resources.ResourceManager"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Resources.ResourceManager.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.Runtime.Extensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Extensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.InteropServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.InteropServices.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.Runtime.InteropServices.WindowsRuntime"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.InteropServices.WindowsRuntime.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Numerics"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Numerics.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization.Json"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Serialization.Json.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization.Primitives"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Serialization.Primitives.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization.Xml"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Serialization.Xml.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Security.Principal"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Security.Principal.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Duplex"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.Duplex.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Http"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.Http.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.NetTcp"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.NetTcp.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Primitives"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.Primitives.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Security"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.Security.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Text.Encoding"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Text.Encoding.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Text.Encoding.Extensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Text.Encoding.Extensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Text.RegularExpressions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Text.RegularExpressions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Threading"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Threading.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Threading.Tasks"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Threading.Tasks.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Threading.Tasks.Parallel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Threading.Tasks.Parallel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Threading.Timer"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Threading.Timer.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.ReaderWriter"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Xml.ReaderWriter.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.XDocument"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Xml.XDocument.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.XmlSerializer"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Xml.XmlSerializer.dll"), Version = new Version(4, 0, 0, 0) }; + + return frameworkInfo; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static FrameworkInformation PopulateNet451(string referenceAssembliesPath) + { + // Generated framework information for .NETFramework,Version=v4.5.1 + var frameworkInfo = new FrameworkInformation(); + frameworkInfo.Path = Path.Combine(referenceAssembliesPath, ".NETFramework", "v4.5.1"); + frameworkInfo.RedistListPath = Path.Combine(referenceAssembliesPath, ".NETFramework", "v4.5.1", "RedistList", "FrameworkList.xml"); + frameworkInfo.Name = ".NET Framework 4.5.1"; + frameworkInfo.SearchPaths = new[] + { + frameworkInfo.Path, + Path.Combine(frameworkInfo.Path, "Facades") + }; + frameworkInfo.Assemblies["Accessibility"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Accessibility.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["CustomMarshalers"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "CustomMarshalers.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["ISymWrapper"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "ISymWrapper.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Activities.Build"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Activities.Build.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Conversion.v4.0"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Conversion.v4.0.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Engine"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Engine.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Framework"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Framework.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Tasks.v4.0"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Tasks.v4.0.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Utilities.v4.0"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Utilities.v4.0.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.CSharp"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.CSharp.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.JScript"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.JScript.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualBasic"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualBasic.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualBasic.Compatibility"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualBasic.Compatibility.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualBasic.Compatibility.Data"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualBasic.Compatibility.Data.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualC"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualC.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualC.STLCLR"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualC.STLCLR.dll"), Version = new Version(2, 0, 0, 0) }; + frameworkInfo.Assemblies["mscorlib"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "mscorlib.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationBuildTasks"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationBuildTasks.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationCore"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationCore.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Aero"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Aero.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Aero2"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Aero2.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.AeroLite"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.AeroLite.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Classic"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Classic.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Luna"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Luna.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Royale"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Royale.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["ReachFramework"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "ReachFramework.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["sysglobl"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "sysglobl.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities.Core.Presentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.Core.Presentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities.DurableInstancing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.DurableInstancing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities.Presentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.Presentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities.Statements"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.Statements.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.AddIn.Contract"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.AddIn.Contract.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.AddIn"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.AddIn.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.Composition"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ComponentModel.Composition.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.Composition.Registration"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ComponentModel.Composition.Registration.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.DataAnnotations"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ComponentModel.DataAnnotations.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Configuration"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Configuration.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Configuration.Install"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Configuration.Install.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Core"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Core.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.DataSetExtensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.DataSetExtensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Entity.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Entity.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Entity"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Entity.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Linq"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Linq.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.OracleClient"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.OracleClient.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Services.Client"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Services.Client.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Services.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Services.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Services"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Services.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.SqlXml"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.SqlXml.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Deployment"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Deployment.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Device"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Device.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.DirectoryServices.AccountManagement"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.DirectoryServices.AccountManagement.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.DirectoryServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.DirectoryServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.DirectoryServices.Protocols"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.DirectoryServices.Protocols.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Drawing.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Drawing.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Drawing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Drawing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Dynamic"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Dynamic.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.EnterpriseServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.EnterpriseServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IdentityModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IdentityModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IdentityModel.Selectors"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IdentityModel.Selectors.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IdentityModel.Services"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IdentityModel.Services.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IO.Log"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IO.Log.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IO.Compression"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IO.Compression.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IO.Compression.FileSystem"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IO.Compression.FileSystem.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Management"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Management.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Management.Instrumentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Management.Instrumentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Messaging"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Messaging.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Net.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net.Http"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Net.Http.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net.Http.WebRequest"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Net.Http.WebRequest.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Numerics"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Numerics.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Printing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Printing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Context"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Reflection.Context.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.DurableInstancing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.DurableInstancing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Caching"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Caching.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Remoting"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Remoting.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Serialization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization.Formatters.Soap"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Serialization.Formatters.Soap.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Security"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Security.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Activation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Activation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Activities"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Activities.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Channels"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Channels.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Discovery"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Discovery.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Routing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Routing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Web"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Web.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceProcess"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceProcess.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Speech"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Speech.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Transactions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Transactions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Abstractions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Abstractions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.ApplicationServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.ApplicationServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DataVisualization.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DataVisualization.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DataVisualization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DataVisualization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DynamicData.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DynamicData.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DynamicData"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DynamicData.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Entity.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Entity.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Entity"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Entity.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Extensions.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Extensions.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Extensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Extensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Mobile"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Mobile.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.RegularExpressions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.RegularExpressions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Routing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Routing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Services"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Services.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Controls.Ribbon"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Controls.Ribbon.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Forms.DataVisualization.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Forms.DataVisualization.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Forms.DataVisualization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Forms.DataVisualization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Forms"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Forms.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Input.Manipulations"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Input.Manipulations.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Presentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Presentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Workflow.Activities"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Workflow.Activities.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Workflow.ComponentModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Workflow.ComponentModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Workflow.Runtime"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Workflow.Runtime.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.WorkflowServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.WorkflowServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xaml"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Xaml.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Xml.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.Linq"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Xml.Linq.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.Serialization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Xml.Serialization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationClient"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationClient.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationClientsideProviders"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationClientsideProviders.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationProvider"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationProvider.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationTypes"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationTypes.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["WindowsBase"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "WindowsBase.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["WindowsFormsIntegration"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "WindowsFormsIntegration.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["XamlBuildTask"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "XamlBuildTask.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Collections"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Collections.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Collections.Concurrent"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Collections.Concurrent.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ComponentModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.Annotations"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ComponentModel.Annotations.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.EventBasedAsync"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ComponentModel.EventBasedAsync.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Diagnostics.Contracts"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Diagnostics.Contracts.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Diagnostics.Debug"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Diagnostics.Debug.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Diagnostics.Tools"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Diagnostics.Tools.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Diagnostics.Tracing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Diagnostics.Tracing.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.Dynamic.Runtime"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Dynamic.Runtime.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Globalization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Globalization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IO"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.IO.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Linq"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Linq.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Linq.Expressions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Linq.Expressions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Linq.Parallel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Linq.Parallel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Linq.Queryable"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Linq.Queryable.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net.NetworkInformation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Net.NetworkInformation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net.Primitives"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Net.Primitives.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net.Requests"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Net.Requests.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ObjectModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ObjectModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Emit"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Emit.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Emit.ILGeneration"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Emit.ILGeneration.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Emit.Lightweight"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Emit.Lightweight.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Extensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Extensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Primitives"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Primitives.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Resources.ResourceManager"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Resources.ResourceManager.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.Runtime.Extensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Extensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.InteropServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.InteropServices.dll"), Version = new Version(4, 0, 10, 0) }; + frameworkInfo.Assemblies["System.Runtime.InteropServices.WindowsRuntime"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.InteropServices.WindowsRuntime.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Numerics"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Numerics.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization.Json"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Serialization.Json.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization.Primitives"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Serialization.Primitives.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization.Xml"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Serialization.Xml.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Security.Principal"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Security.Principal.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Duplex"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.Duplex.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Http"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.Http.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.NetTcp"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.NetTcp.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Primitives"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.Primitives.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Security"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.Security.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Text.Encoding"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Text.Encoding.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Text.Encoding.Extensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Text.Encoding.Extensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Text.RegularExpressions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Text.RegularExpressions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Threading"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Threading.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Threading.Tasks"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Threading.Tasks.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Threading.Tasks.Parallel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Threading.Tasks.Parallel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Threading.Timer"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Threading.Timer.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.ReaderWriter"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Xml.ReaderWriter.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.XDocument"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Xml.XDocument.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.XmlSerializer"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Xml.XmlSerializer.dll"), Version = new Version(4, 0, 0, 0) }; + + return frameworkInfo; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static FrameworkInformation PopulateNet45(string referenceAssembliesPath) + { + var frameworkInfo = new FrameworkInformation(); + // Generated framework information for .NETFramework,Version=v4.5 + frameworkInfo.Path = Path.Combine(referenceAssembliesPath, ".NETFramework", "v4.5"); + frameworkInfo.RedistListPath = Path.Combine(referenceAssembliesPath, ".NETFramework", "v4.5", "RedistList", "FrameworkList.xml"); + frameworkInfo.Name = ".NET Framework 4.5"; + frameworkInfo.SearchPaths = new[] + { + frameworkInfo.Path, + Path.Combine(frameworkInfo.Path, "Facades") + }; + frameworkInfo.Assemblies["Accessibility"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Accessibility.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["CustomMarshalers"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "CustomMarshalers.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["ISymWrapper"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "ISymWrapper.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Activities.Build"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Activities.Build.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Conversion.v4.0"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Conversion.v4.0.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Engine"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Engine.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Framework"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Framework.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Tasks.v4.0"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Tasks.v4.0.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Utilities.v4.0"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Utilities.v4.0.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.CSharp"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.CSharp.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.JScript"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.JScript.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualBasic"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualBasic.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualBasic.Compatibility"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualBasic.Compatibility.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualBasic.Compatibility.Data"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualBasic.Compatibility.Data.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualC"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualC.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualC.STLCLR"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualC.STLCLR.dll"), Version = new Version(2, 0, 0, 0) }; + frameworkInfo.Assemblies["mscorlib"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "mscorlib.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationBuildTasks"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationBuildTasks.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationCore"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationCore.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Aero"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Aero.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Aero2"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Aero2.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.AeroLite"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.AeroLite.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Classic"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Classic.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Luna"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Luna.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Royale"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Royale.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["ReachFramework"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "ReachFramework.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["sysglobl"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "sysglobl.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities.Core.Presentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.Core.Presentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities.DurableInstancing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.DurableInstancing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities.Presentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.Presentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities.Statements"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.Statements.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.AddIn.Contract"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.AddIn.Contract.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.AddIn"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.AddIn.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.Composition"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ComponentModel.Composition.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.Composition.Registration"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ComponentModel.Composition.Registration.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.DataAnnotations"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ComponentModel.DataAnnotations.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Configuration"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Configuration.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Configuration.Install"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Configuration.Install.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Core"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Core.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.DataSetExtensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.DataSetExtensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Entity.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Entity.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Entity"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Entity.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Linq"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Linq.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.OracleClient"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.OracleClient.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Services.Client"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Services.Client.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Services.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Services.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Services"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Services.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.SqlXml"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.SqlXml.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Deployment"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Deployment.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Device"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Device.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.DirectoryServices.AccountManagement"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.DirectoryServices.AccountManagement.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.DirectoryServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.DirectoryServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.DirectoryServices.Protocols"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.DirectoryServices.Protocols.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Drawing.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Drawing.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Drawing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Drawing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Dynamic"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Dynamic.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.EnterpriseServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.EnterpriseServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IdentityModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IdentityModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IdentityModel.Selectors"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IdentityModel.Selectors.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IdentityModel.Services"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IdentityModel.Services.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IO.Log"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IO.Log.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IO.Compression"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IO.Compression.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IO.Compression.FileSystem"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IO.Compression.FileSystem.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Management"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Management.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Management.Instrumentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Management.Instrumentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Messaging"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Messaging.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Net.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net.Http"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Net.Http.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net.Http.WebRequest"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Net.Http.WebRequest.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Numerics"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Numerics.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Printing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Printing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Context"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Reflection.Context.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.DurableInstancing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.DurableInstancing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Caching"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Caching.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Remoting"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Remoting.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Serialization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization.Formatters.Soap"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Serialization.Formatters.Soap.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Security"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Security.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Activation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Activation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Activities"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Activities.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Channels"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Channels.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Discovery"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Discovery.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Routing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Routing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Web"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Web.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceProcess"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceProcess.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Speech"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Speech.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Transactions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Transactions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Abstractions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Abstractions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.ApplicationServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.ApplicationServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DataVisualization.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DataVisualization.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DataVisualization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DataVisualization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DynamicData.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DynamicData.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DynamicData"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DynamicData.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Entity.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Entity.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Entity"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Entity.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Extensions.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Extensions.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Extensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Extensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Mobile"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Mobile.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.RegularExpressions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.RegularExpressions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Routing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Routing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Services"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Services.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Controls.Ribbon"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Controls.Ribbon.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Forms.DataVisualization.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Forms.DataVisualization.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Forms.DataVisualization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Forms.DataVisualization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Forms"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Forms.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Input.Manipulations"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Input.Manipulations.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Presentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Presentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Workflow.Activities"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Workflow.Activities.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Workflow.ComponentModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Workflow.ComponentModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Workflow.Runtime"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Workflow.Runtime.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.WorkflowServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.WorkflowServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xaml"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Xaml.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Xml.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.Linq"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Xml.Linq.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.Serialization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Xml.Serialization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationClient"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationClient.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationClientsideProviders"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationClientsideProviders.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationProvider"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationProvider.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationTypes"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationTypes.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["WindowsBase"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "WindowsBase.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["WindowsFormsIntegration"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "WindowsFormsIntegration.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["XamlBuildTask"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "XamlBuildTask.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Collections"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Collections.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Collections.Concurrent"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Collections.Concurrent.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ComponentModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.Annotations"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ComponentModel.Annotations.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.EventBasedAsync"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ComponentModel.EventBasedAsync.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Diagnostics.Contracts"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Diagnostics.Contracts.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Diagnostics.Debug"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Diagnostics.Debug.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Diagnostics.Tools"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Diagnostics.Tools.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Diagnostics.Tracing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Diagnostics.Tracing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Dynamic.Runtime"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Dynamic.Runtime.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Globalization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Globalization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IO"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.IO.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Linq"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Linq.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Linq.Expressions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Linq.Expressions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Linq.Parallel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Linq.Parallel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Linq.Queryable"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Linq.Queryable.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net.NetworkInformation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Net.NetworkInformation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net.Primitives"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Net.Primitives.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net.Requests"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Net.Requests.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ObjectModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ObjectModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Emit"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Emit.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Emit.ILGeneration"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Emit.ILGeneration.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Emit.Lightweight"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Emit.Lightweight.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Extensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Extensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Reflection.Primitives"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Reflection.Primitives.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Resources.ResourceManager"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Resources.ResourceManager.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Extensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Extensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.InteropServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.InteropServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.InteropServices.WindowsRuntime"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.InteropServices.WindowsRuntime.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Numerics"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Numerics.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization.Json"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Serialization.Json.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization.Primitives"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Serialization.Primitives.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization.Xml"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Runtime.Serialization.Xml.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Security.Principal"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Security.Principal.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Duplex"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.Duplex.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Http"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.Http.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.NetTcp"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.NetTcp.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Primitives"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.Primitives.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Security"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.ServiceModel.Security.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Text.Encoding"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Text.Encoding.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Text.Encoding.Extensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Text.Encoding.Extensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Text.RegularExpressions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Text.RegularExpressions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Threading"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Threading.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Threading.Tasks"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Threading.Tasks.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Threading.Tasks.Parallel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Threading.Tasks.Parallel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.ReaderWriter"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Xml.ReaderWriter.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.XDocument"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Xml.XDocument.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.XmlSerializer"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Facades", "System.Xml.XmlSerializer.dll"), Version = new Version(4, 0, 0, 0) }; + + return frameworkInfo; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static FrameworkInformation PopulateNet40(string referenceAssembliesPath) + { + // Generated framework information for .NETFramework,Version=v4.0 + var frameworkInfo = new FrameworkInformation(); + frameworkInfo.Path = Path.Combine(referenceAssembliesPath, ".NETFramework", "v4.0"); + frameworkInfo.RedistListPath = Path.Combine(referenceAssembliesPath, ".NETFramework", "v4.0", "RedistList", "FrameworkList.xml"); + frameworkInfo.Name = ".NET Framework 4"; + frameworkInfo.SearchPaths = new[] + { + frameworkInfo.Path, + Path.Combine(frameworkInfo.Path, "Facades") + }; + frameworkInfo.Assemblies["Accessibility"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Accessibility.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["CustomMarshalers"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "CustomMarshalers.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["ISymWrapper"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "ISymWrapper.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Conversion.v4.0"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Conversion.v4.0.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Engine"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Engine.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Framework"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Framework.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Tasks.v4.0"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Tasks.v4.0.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.Build.Utilities.v4.0"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.Build.Utilities.v4.0.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.CSharp"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.CSharp.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.JScript"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.JScript.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualBasic"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualBasic.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualBasic.Compatibility"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualBasic.Compatibility.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualBasic.Compatibility.Data"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualBasic.Compatibility.Data.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualC"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualC.dll"), Version = new Version(10, 0, 0, 0) }; + frameworkInfo.Assemblies["Microsoft.VisualC.STLCLR"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "Microsoft.VisualC.STLCLR.dll"), Version = new Version(2, 0, 0, 0) }; + frameworkInfo.Assemblies["mscorlib"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "mscorlib.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationBuildTasks"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationBuildTasks.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationCore"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationCore.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Aero"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Aero.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Classic"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Classic.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Luna"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Luna.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["PresentationFramework.Royale"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "PresentationFramework.Royale.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["ReachFramework"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "ReachFramework.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["sysglobl"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "sysglobl.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities.Core.Presentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.Core.Presentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities.DurableInstancing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.DurableInstancing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Activities.Presentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Activities.Presentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.AddIn.Contract"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.AddIn.Contract.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.AddIn"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.AddIn.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.Composition"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ComponentModel.Composition.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ComponentModel.DataAnnotations"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ComponentModel.DataAnnotations.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Configuration"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Configuration.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Configuration.Install"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Configuration.Install.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Core"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Core.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.DataSetExtensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.DataSetExtensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Entity.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Entity.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Entity"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Entity.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Linq"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Linq.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.OracleClient"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.OracleClient.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Services.Client"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Services.Client.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Services.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Services.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.Services"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.Services.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Data.SqlXml"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Data.SqlXml.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Deployment"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Deployment.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Device"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Device.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.DirectoryServices.AccountManagement"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.DirectoryServices.AccountManagement.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.DirectoryServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.DirectoryServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.DirectoryServices.Protocols"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.DirectoryServices.Protocols.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Drawing.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Drawing.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Drawing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Drawing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Dynamic"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Dynamic.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.EnterpriseServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.EnterpriseServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IdentityModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IdentityModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IdentityModel.Selectors"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IdentityModel.Selectors.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.IO.Log"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.IO.Log.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Management"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Management.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Management.Instrumentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Management.Instrumentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Messaging"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Messaging.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Net"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Net.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Numerics"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Numerics.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Printing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Printing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.DurableInstancing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.DurableInstancing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Caching"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Caching.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Remoting"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Remoting.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Serialization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Runtime.Serialization.Formatters.Soap"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Runtime.Serialization.Formatters.Soap.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Security"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Security.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Activation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Activation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Activities"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Activities.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Channels"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Channels.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Discovery"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Discovery.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Routing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Routing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceModel.Web"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceModel.Web.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.ServiceProcess"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.ServiceProcess.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Speech"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Speech.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Transactions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Transactions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Abstractions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Abstractions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.ApplicationServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.ApplicationServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DataVisualization.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DataVisualization.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DataVisualization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DataVisualization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DynamicData.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DynamicData.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.DynamicData"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.DynamicData.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Entity.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Entity.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Entity"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Entity.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Extensions.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Extensions.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Extensions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Extensions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Mobile"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Mobile.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.RegularExpressions"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.RegularExpressions.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Routing"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Routing.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Web.Services"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Web.Services.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Forms.DataVisualization.Design"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Forms.DataVisualization.Design.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Forms.DataVisualization"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Forms.DataVisualization.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Forms"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Forms.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Input.Manipulations"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Input.Manipulations.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Windows.Presentation"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Windows.Presentation.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Workflow.Activities"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Workflow.Activities.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Workflow.ComponentModel"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Workflow.ComponentModel.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Workflow.Runtime"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Workflow.Runtime.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.WorkflowServices"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.WorkflowServices.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xaml"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Xaml.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Xml.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["System.Xml.Linq"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "System.Xml.Linq.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationClient"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationClient.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationClientsideProviders"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationClientsideProviders.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationProvider"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationProvider.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["UIAutomationTypes"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "UIAutomationTypes.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["WindowsBase"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "WindowsBase.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["WindowsFormsIntegration"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "WindowsFormsIntegration.dll"), Version = new Version(4, 0, 0, 0) }; + frameworkInfo.Assemblies["XamlBuildTask"] = new AssemblyEntry { Path = Path.Combine(frameworkInfo.Path, "XamlBuildTask.dll"), Version = new Version(4, 0, 0, 0) }; + + return frameworkInfo; + } + + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/Resolution/FrameworkInformation.cs b/src/Microsoft.Extensions.ProjectModel/Resolution/FrameworkInformation.cs new file mode 100644 index 000000000..3db26d46f --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Resolution/FrameworkInformation.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace Microsoft.Extensions.ProjectModel.Resolution +{ + internal class FrameworkInformation + { + private bool? _exists; + + public FrameworkInformation() + { + Assemblies = new Dictionary(); + } + + public bool Exists + { + get + { + if (_exists == null) + { + _exists = Directory.Exists(Path); + } + + return _exists.Value; + } + set + { + _exists = true; + } + } + + public string Path { get; set; } + + public IEnumerable SearchPaths { get; set; } + + public string RedistListPath { get; set; } + + public IDictionary Assemblies { get; private set; } + + public string Name { get; set; } + } + + internal class AssemblyEntry + { + public string Path { get; set; } + public Version Version { get; set; } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/Resolution/FrameworkReferenceResolver.cs b/src/Microsoft.Extensions.ProjectModel/Resolution/FrameworkReferenceResolver.cs new file mode 100644 index 000000000..1530ce497 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Resolution/FrameworkReferenceResolver.cs @@ -0,0 +1,369 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Xml.Linq; +using Microsoft.Extensions.ProjectModel.Utilities; +using NuGet.Frameworks; + +namespace Microsoft.Extensions.ProjectModel.Resolution +{ + public class FrameworkReferenceResolver + { + // TODO(anurse): Move the Mono stuff back in. + + // FrameworkConstants doesn't have dnx46 yet + private static readonly NuGetFramework Dnx46 = new NuGetFramework( + FrameworkConstants.FrameworkIdentifiers.Dnx, + new Version(4, 6)); + + private readonly IDictionary _cache = new Dictionary(); + + private static readonly IDictionary _aliases = new Dictionary + { + { FrameworkConstants.CommonFrameworks.Dnx451, new [] { FrameworkConstants.CommonFrameworks.Net451 } }, + { Dnx46, new [] { FrameworkConstants.CommonFrameworks.Net46 } } + }; + + public bool TryGetAssembly(string name, NuGetFramework targetFramework, out string path, out Version version) + { + path = null; + version = null; + + var information = _cache.GetOrAdd(targetFramework, GetFrameworkInformation); + + if (information == null || !information.Exists) + { + return false; + } + + lock (information.Assemblies) + { + AssemblyEntry entry; + if (information.Assemblies.TryGetValue(name, out entry)) + { + if (string.IsNullOrEmpty(entry.Path)) + { + entry.Path = GetAssemblyPath(information.SearchPaths, name); + } + + if (!string.IsNullOrEmpty(entry.Path) && entry.Version == null) + { + // This code path should only run on mono + entry.Version = VersionUtility.GetAssemblyVersion(entry.Path).Version; + } + + path = entry.Path; + version = entry.Version; + } + } + + return !string.IsNullOrEmpty(path); + } + + public IEnumerable GetAttemptedPaths(NuGetFramework targetFramework) + { + var information = _cache.GetOrAdd(targetFramework, GetFrameworkInformation); + + if (information == null || !information.Exists) + { + return null; + } + return information.SearchPaths.Select(s => Path.Combine(s, "{name}.dll")); + } + + public string GetFrameworkRedistListPath(NuGetFramework targetFramework) + { + var information = _cache.GetOrAdd(targetFramework, GetFrameworkInformation); + + if (information == null || !information.Exists) + { + return null; + } + + return information.RedistListPath; + } + + public static string GetReferenceAssembliesPath() + { + // References assemblies are in %ProgramFiles(x86)% on + // 64 bit machines + var programFiles = Environment.GetEnvironmentVariable("ProgramFiles(x86)"); + + if (string.IsNullOrEmpty(programFiles)) + { + // On 32 bit machines they are in %ProgramFiles% + programFiles = Environment.GetEnvironmentVariable("ProgramFiles"); + } + + if (string.IsNullOrEmpty(programFiles)) + { + // Reference assemblies aren't installed + return null; + } + + return Path.Combine( + programFiles, + "Reference Assemblies", "Microsoft", "Framework"); + } + + private static FrameworkInformation GetFrameworkInformation(NuGetFramework targetFramework) + { + string referenceAssembliesPath = GetReferenceAssembliesPath(); + + if (string.IsNullOrEmpty(referenceAssembliesPath)) + { + return null; + } + + FrameworkInformation frameworkInfo; + + // Skip this on mono since it has a slightly different set of reference assemblies at a different + // location + // Also, if the framework we're targetting has a profile (Client profile, basically), don't use the + // fast path because it will be wrong. + if (FrameworkDefinitions.TryPopulateFrameworkFastPath(targetFramework, referenceAssembliesPath, out frameworkInfo)) + { + return frameworkInfo; + } + + NuGetFramework[] candidates; + if (_aliases.TryGetValue(targetFramework, out candidates)) + { + foreach (var framework in candidates) + { + var information = GetFrameworkInformation(framework); + + if (information != null) + { + return information; + } + } + + return null; + } + else + { + return GetFrameworkInformation(targetFramework, referenceAssembliesPath); + } + } + + private static FrameworkInformation GetFrameworkInformation(NuGetFramework targetFramework, string referenceAssembliesPath) + { + // Check for legacy frameworks + if (targetFramework.IsDesktop() && targetFramework.Version <= new Version(3, 5)) + { + return GetLegacyFrameworkInformation(targetFramework, referenceAssembliesPath); + } + + var basePath = Path.Combine(referenceAssembliesPath, + targetFramework.Framework, + "v" + targetFramework.Version); + + if (!string.IsNullOrEmpty(targetFramework.Profile)) + { + basePath = Path.Combine(basePath, "Profile", targetFramework.Profile); + } + + var version = new DirectoryInfo(basePath); + if (!version.Exists) + { + return null; + } + + return GetFrameworkInformation(version, targetFramework); + } + + private static FrameworkInformation GetLegacyFrameworkInformation(NuGetFramework targetFramework, string referenceAssembliesPath) + { + var frameworkInfo = new FrameworkInformation(); + + // Always grab .NET 2.0 data + var searchPaths = new List(); + var net20Dir = Path.Combine(Environment.GetEnvironmentVariable("WINDIR"), "Microsoft.NET", "Framework", "v2.0.50727"); + + if (!Directory.Exists(net20Dir)) + { + return null; + } + + // Grab reference assemblies first, if present for this framework + if (targetFramework.Version.Major == 3) + { + // Most specific first (i.e. 3.5) + if (targetFramework.Version.Minor == 5) + { + var refAsms35Dir = Path.Combine(referenceAssembliesPath, "v3.5"); + if (!string.IsNullOrEmpty(targetFramework.Profile)) + { + // The 3.5 Client Profile assemblies ARE in .NETFramework... it's weird. + refAsms35Dir = Path.Combine(referenceAssembliesPath, ".NETFramework", "v3.5", "Profile", targetFramework.Profile); + } + if (Directory.Exists(refAsms35Dir)) + { + searchPaths.Add(refAsms35Dir); + } + } + + // Always search the 3.0 reference assemblies + if (string.IsNullOrEmpty(targetFramework.Profile)) + { + // a) 3.0 didn't have profiles + // b) When using a profile, we don't want to fall back to 3.0 or 2.0 + var refAsms30Dir = Path.Combine(referenceAssembliesPath, "v3.0"); + if (Directory.Exists(refAsms30Dir)) + { + searchPaths.Add(refAsms30Dir); + } + } + } + + // .NET 2.0 reference assemblies go last (but only if there's no profile in the TFM) + if (string.IsNullOrEmpty(targetFramework.Profile)) + { + searchPaths.Add(net20Dir); + } + + frameworkInfo.Exists = true; + frameworkInfo.Path = searchPaths.First(); + frameworkInfo.SearchPaths = searchPaths; + + // Load the redist list in reverse order (most general -> most specific) + for (int i = searchPaths.Count - 1; i >= 0; i--) + { + var dir = new DirectoryInfo(searchPaths[i]); + if (dir.Exists) + { + PopulateFromRedistList(dir, frameworkInfo); + } + } + + if (string.IsNullOrEmpty(frameworkInfo.Name)) + { + frameworkInfo.Name = SynthesizeFrameworkFriendlyName(targetFramework); + } + return frameworkInfo; + } + + private static string SynthesizeFrameworkFriendlyName(NuGetFramework targetFramework) + { + // Names are not present in the RedistList.xml file for older frameworks or on Mono + // We do some custom version string rendering to match how net40 is rendered (.NET Framework 4) + if (targetFramework.Framework.Equals(FrameworkConstants.FrameworkIdentifiers.Net)) + { + string versionString = targetFramework.Version.Minor == 0 ? + targetFramework.Version.Major.ToString() : + targetFramework.Version.ToString(); + string profileString = string.IsNullOrEmpty(targetFramework.Profile) ? + string.Empty : + $" {targetFramework.Profile} Profile"; + return ".NET Framework " + versionString + profileString; + } + return targetFramework.ToString(); + } + + private static FrameworkInformation GetFrameworkInformation(DirectoryInfo directory, NuGetFramework targetFramework) + { + var frameworkInfo = new FrameworkInformation(); + frameworkInfo.Exists = true; + frameworkInfo.Path = directory.FullName; + frameworkInfo.SearchPaths = new[] { + frameworkInfo.Path, + Path.Combine(frameworkInfo.Path, "Facades") + }; + + PopulateFromRedistList(directory, frameworkInfo); + if (string.IsNullOrEmpty(frameworkInfo.Name)) + { + frameworkInfo.Name = SynthesizeFrameworkFriendlyName(targetFramework); + } + return frameworkInfo; + } + + private static void PopulateFromRedistList(DirectoryInfo directory, FrameworkInformation frameworkInfo) + { + // The redist list contains the list of assemblies for this target framework + string redistList = Path.Combine(directory.FullName, "RedistList", "FrameworkList.xml"); + + if (File.Exists(redistList)) + { + frameworkInfo.RedistListPath = redistList; + + using (var stream = File.OpenRead(redistList)) + { + var frameworkList = XDocument.Load(stream); + + // On mono, the RedistList.xml has an entry pointing to the TargetFrameworkDirectory + // It basically uses the GAC as the reference assemblies for all .NET framework + // profiles + var targetFrameworkDirectory = frameworkList.Root.Attribute("TargetFrameworkDirectory")?.Value; + + if (!string.IsNullOrEmpty(targetFrameworkDirectory)) + { + // For some odd reason, the paths are actually listed as \ so normalize them here + targetFrameworkDirectory = targetFrameworkDirectory.Replace('\\', Path.DirectorySeparatorChar); + + // The specified path is the relative path from the RedistList.xml itself + var resovledPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(redistList), targetFrameworkDirectory)); + + // Update the path to the framework + frameworkInfo.Path = resovledPath; + + PopulateAssemblies(frameworkInfo.Assemblies, resovledPath); + PopulateAssemblies(frameworkInfo.Assemblies, Path.Combine(resovledPath, "Facades")); + } + else + { + foreach (var e in frameworkList.Root.Elements()) + { + var assemblyName = e.Attribute("AssemblyName").Value; + var version = e.Attribute("Version")?.Value; + + var entry = new AssemblyEntry(); + entry.Version = version != null ? Version.Parse(version) : null; + frameworkInfo.Assemblies[assemblyName] = entry; + } + } + + var nameAttribute = frameworkList.Root.Attribute("Name"); + + frameworkInfo.Name = nameAttribute == null ? null : nameAttribute.Value; + } + } + } + + private static void PopulateAssemblies(IDictionary assemblies, string path) + { + if (!Directory.Exists(path)) + { + return; + } + + foreach (var assemblyPath in Directory.GetFiles(path, "*.dll")) + { + var name = Path.GetFileNameWithoutExtension(assemblyPath); + var entry = new AssemblyEntry(); + entry.Path = assemblyPath; + assemblies[name] = entry; + } + } + + private static string GetAssemblyPath(IEnumerable basePaths, string assemblyName) + { + foreach (var basePath in basePaths) + { + var assemblyPath = Path.Combine(basePath, assemblyName + ".dll"); + + if (File.Exists(assemblyPath)) + { + return assemblyPath; + } + } + + return null; + } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/Resolution/LibraryManager.cs b/src/Microsoft.Extensions.ProjectModel/Resolution/LibraryManager.cs new file mode 100644 index 000000000..20de51611 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Resolution/LibraryManager.cs @@ -0,0 +1,292 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.Versioning; +using NuGet.Frameworks; +using NuGet.Versioning; + +namespace Microsoft.Extensions.ProjectModel.Resolution +{ + public class LibraryManager + { + private IList _libraries; + private IList _diagnostics; + + private readonly object _initializeLock = new object(); + private Dictionary> _inverse; + private Dictionary _graph; + private readonly string _projectPath; + private readonly NuGetFramework _targetFramework; + + public LibraryManager(string projectPath, NuGetFramework targetFramework, IList libraries) + { + _projectPath = projectPath; + _targetFramework = targetFramework; + _libraries = libraries; + } + + public void AddGlobalDiagnostics(DiagnosticMessage message) + { + if (_diagnostics == null) + { + _diagnostics = new List(); + } + + _diagnostics.Add(message); + } + + private Dictionary Graph + { + get + { + EnsureGraph(); + return _graph; + } + } + + private Dictionary> InverseGraph + { + get + { + EnsureInverseGraph(); + return _inverse; + } + } + + public IEnumerable GetReferencingLibraries(string name) + { + IEnumerable libraries; + if (InverseGraph.TryGetValue(name, out libraries)) + { + return libraries; + } + + return Enumerable.Empty(); + } + + public LibraryDescription GetLibrary(string name) + { + LibraryDescription library; + if (Graph.TryGetValue(name, out library)) + { + return library; + } + + return null; + } + + public IEnumerable GetLibraries() + { + EnsureGraph(); + return _graph.Values; + } + + public IList GetAllDiagnostics() + { + var messages = new List(); + + if (_diagnostics != null) + { + messages.AddRange(_diagnostics); + } + + foreach (var library in GetLibraries()) + { + string projectPath = library.RequestedRange.SourceFilePath ?? _projectPath; + + if (!library.Resolved) + { + string message; + string errorCode; + if (library.Compatible) + { + errorCode = ErrorCodes.NU1001; + message = $"The dependency {library.RequestedRange.Name} {library.RequestedRange.VersionRange} could not be resolved."; + } + else + { + errorCode = ErrorCodes.NU1002; + var projectName = Directory.GetParent(_projectPath).Name; + message = $"The dependency {library.Identity} in project {projectName} does not support framework {library.Framework}."; + } + + messages.Add( + new DiagnosticMessage( + errorCode, + message, + projectPath, + DiagnosticMessageSeverity.Error, + library.RequestedRange.SourceLine, + library.RequestedRange.SourceColumn, + library)); + } + else + { + // Skip libraries that aren't specified in a project.json + if (string.IsNullOrEmpty(library.RequestedRange.SourceFilePath)) + { + continue; + } + + if (library.RequestedRange.VersionRange == null) + { + // TODO: Show errors/warnings for things without versions + continue; + } + + // If we ended up with a declared version that isn't what was asked for directly + // then report a warning + // Case 1: Non floating version and the minimum doesn't match what was specified + // Case 2: Floating version that fell outside of the range + if ((!library.RequestedRange.VersionRange.IsFloating && + library.RequestedRange.VersionRange.MinVersion != library.Identity.Version) || + (library.RequestedRange.VersionRange.IsFloating && + !library.RequestedRange.VersionRange.EqualsFloating(library.Identity.Version))) + { + var message = string.Format("Dependency specified was {0} but ended up with {1}.", library.RequestedRange, library.Identity); + messages.Add( + new DiagnosticMessage( + ErrorCodes.NU1007, + message, + projectPath, + DiagnosticMessageSeverity.Warning, + library.RequestedRange.SourceLine, + library.RequestedRange.SourceColumn, + library)); + } + } + } + + return messages; + } + + private void EnsureGraph() + { + lock (_initializeLock) + { + if (_graph == null) + { + _graph = _libraries.ToDictionary(l => l.Identity.Name, StringComparer.Ordinal); + _libraries = null; + } + } + } + + private void EnsureInverseGraph() + { + EnsureGraph(); + + lock (_initializeLock) + { + if (_inverse == null) + { + BuildInverseGraph(); + } + } + } + + private void BuildInverseGraph() + { + var firstLevelLookups = new Dictionary>(StringComparer.OrdinalIgnoreCase); + var visited = new HashSet(StringComparer.OrdinalIgnoreCase); + foreach (var item in _graph.Values) + { + Visit(item, firstLevelLookups, visited); + } + + _inverse = new Dictionary>(StringComparer.OrdinalIgnoreCase); + + // Flatten the graph + foreach (var item in _graph.Values) + { + Flatten(item, firstLevelLookups: firstLevelLookups); + } + } + + private void Visit(LibraryDescription item, + Dictionary> inverse, + HashSet visited) + { + if (!visited.Add(item.Identity.Name)) + { + return; + } + + foreach (var dependency in item.Dependencies) + { + List dependents; + if (!inverse.TryGetValue(dependency.Name, out dependents)) + { + dependents = new List(); + inverse[dependency.Name] = dependents; + } + + dependents.Add(item); + Visit(_graph[dependency.Name], inverse, visited); + } + } + + private void Flatten(LibraryDescription info, + Dictionary> firstLevelLookups, + HashSet parentDependents = null) + { + IEnumerable libraryDependents; + if (!_inverse.TryGetValue(info.Identity.Name, out libraryDependents)) + { + List firstLevelDependents; + if (firstLevelLookups.TryGetValue(info.Identity.Name, out firstLevelDependents)) + { + var allDependents = new HashSet(LibraryDescriptionComparer.Instance); + foreach (var dependent in firstLevelDependents) + { + allDependents.Add(dependent); + Flatten(dependent, firstLevelLookups, allDependents); + } + libraryDependents = allDependents; + } + else + { + libraryDependents = Enumerable.Empty(); + } + _inverse[info.Identity.Name] = libraryDependents; + } + AddRange(parentDependents, libraryDependents); + } + + private static Func> GetLibraryInfoThunk(IEnumerable libraries) + { + return () => libraries; + } + + private static void AddRange(HashSet source, IEnumerable values) + { + if (source != null) + { + foreach (var value in values) + { + source.Add(value); + } + } + } + + private class LibraryDescriptionComparer : IEqualityComparer + { + public static readonly LibraryDescriptionComparer Instance = new LibraryDescriptionComparer(); + + private LibraryDescriptionComparer() { } + public bool Equals(LibraryDescription x, LibraryDescription y) + { + return string.Equals(x.Identity.Name, y.Identity.Name, StringComparison.OrdinalIgnoreCase); + } + + public int GetHashCode(LibraryDescription obj) + { + return StringComparer.OrdinalIgnoreCase.GetHashCode(obj.Identity.Name); + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/Resolution/PackageDependencyProvider.cs b/src/Microsoft.Extensions.ProjectModel/Resolution/PackageDependencyProvider.cs new file mode 100644 index 000000000..c8ee2d466 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Resolution/PackageDependencyProvider.cs @@ -0,0 +1,164 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using Microsoft.Extensions.ProjectModel.Graph; +using Microsoft.Extensions.ProjectModel.Utilities; +using NuGet.Packaging; +using NuGet.Versioning; + +namespace Microsoft.Extensions.ProjectModel.Resolution +{ + public class PackageDependencyProvider + { + private readonly string _packagesPath; + + private readonly IEnumerable _cacheResolvers; + private readonly VersionFolderPathResolver _packagePathResolver; + + public PackageDependencyProvider(string packagesPath) + { + _packagesPath = packagesPath; + _cacheResolvers = GetCacheResolvers(); + _packagePathResolver = new VersionFolderPathResolver(packagesPath); + } + + public PackageDescription GetDescription(LockFilePackageLibrary package, LockFileTargetLibrary targetLibrary) + { + // If a NuGet dependency is supposed to provide assemblies but there is no assembly compatible with + // current target framework, we should mark this dependency as unresolved + var containsAssembly = package.Files + .Any(x => x.StartsWith($"ref{Path.DirectorySeparatorChar}") || + x.StartsWith($"lib{Path.DirectorySeparatorChar}")); + + var compatible = targetLibrary.FrameworkAssemblies.Any() || + targetLibrary.CompileTimeAssemblies.Any() || + targetLibrary.RuntimeAssemblies.Any() || + !containsAssembly; + + var resolved = compatible; + var dependencies = new List(targetLibrary.Dependencies.Count + targetLibrary.FrameworkAssemblies.Count); + PopulateDependencies(dependencies, targetLibrary); + + var path = ResolvePackagePath(package); + + var packageDescription = new PackageDescription( + new LibraryRange(package.Name, new VersionRange(package.Version), LibraryType.Package, LibraryDependencyType.Default), + path, + package, + targetLibrary, + dependencies, + compatible); + + return packageDescription; + } + + private void PopulateDependencies(List dependencies, LockFileTargetLibrary targetLibrary) + { + foreach (var dependency in targetLibrary.Dependencies) + { + dependencies.Add(new LibraryRange( + dependency.Id, + dependency.VersionRange, + LibraryType.Unspecified, + LibraryDependencyType.Default)); + } + + foreach (var frameworkAssembly in targetLibrary.FrameworkAssemblies) + { + dependencies.Add(new LibraryRange( + frameworkAssembly, + LibraryType.ReferenceAssembly, + LibraryDependencyType.Default)); + } + } + + private string ResolvePackagePath(LockFilePackageLibrary package) + { + string expectedHash = package.Sha512; + + foreach (var resolver in _cacheResolvers) + { + var cacheHashFile = resolver.GetHashPath(package.Name, package.Version); + + // REVIEW: More efficient compare? + if (File.Exists(cacheHashFile) && + File.ReadAllText(cacheHashFile) == expectedHash) + { + return resolver.GetInstallPath(package.Name, package.Version); + } + } + + return _packagePathResolver.GetInstallPath(package.Name, package.Version); + } + + public static string ResolveRepositoryPath(string rootDirectory, GlobalSettings settings) + { + // Order + // 1. global.json { "packages": "..." } + // 2. EnvironmentNames.Packages environment variable + // 3. NuGet.config repositoryPath (maybe)? + // 4. {DefaultLocalRuntimeHomeDir}\packages + + if (!string.IsNullOrEmpty(settings?.PackagesPath)) + { + return Path.Combine(rootDirectory, settings.PackagesPath); + } + + var runtimePackages = Environment.GetEnvironmentVariable(EnvironmentNames.PackagesCache); + + if (!string.IsNullOrEmpty(runtimePackages)) + { + return runtimePackages; + } + + var profileDirectory = Environment.GetEnvironmentVariable("USERPROFILE"); + + if (string.IsNullOrEmpty(profileDirectory)) + { + profileDirectory = Environment.GetEnvironmentVariable("HOME"); + } + + // TODO(anurse): This should migrate to the NuGet packages directory + return Path.Combine(profileDirectory, ".dnx", "packages"); + } + + private static IEnumerable GetCacheResolvers() + { + var packageCachePathValue = Environment.GetEnvironmentVariable(EnvironmentNames.PackagesCache); + + if (string.IsNullOrEmpty(packageCachePathValue)) + { + return Enumerable.Empty(); + } + + return packageCachePathValue.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries) + .Select(path => new VersionFolderPathResolver(path)); + } + + private class AssemblyNameComparer : IEqualityComparer + { + public static IEqualityComparer OrdinalIgnoreCase = new AssemblyNameComparer(); + + public bool Equals(AssemblyName x, AssemblyName y) + { + return + string.Equals(x.Name, y.Name, StringComparison.OrdinalIgnoreCase) && + string.Equals(x.CultureName ?? "", y.CultureName ?? "", StringComparison.OrdinalIgnoreCase); + } + + public int GetHashCode(AssemblyName obj) + { + var hashCode = 0; + if (obj.Name != null) + { + hashCode ^= obj.Name.ToUpperInvariant().GetHashCode(); + } + + hashCode ^= (obj.CultureName?.ToUpperInvariant() ?? "").GetHashCode(); + return hashCode; + } + } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/Resolution/ProjectDependencyProvider.cs b/src/Microsoft.Extensions.ProjectModel/Resolution/ProjectDependencyProvider.cs new file mode 100644 index 000000000..ec675ed16 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Resolution/ProjectDependencyProvider.cs @@ -0,0 +1,74 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Versioning; +using Microsoft.Extensions.ProjectModel.Graph; +using NuGet; +using NuGet.Frameworks; + +namespace Microsoft.Extensions.ProjectModel.Resolution +{ + public class ProjectDependencyProvider + { + public ProjectDescription GetDescription(string name, string path, LockFileTargetLibrary targetLibrary) + { + Project project; + + // Can't find a project file with the name so bail + if (!Project.TryGetProject(path, out project)) + { + return new ProjectDescription(name, path); + } + + return GetDescription(targetLibrary.TargetFramework, project); + } + + public ProjectDescription GetDescription(NuGetFramework targetFramework, Project project) + { + // This never returns null + var targetFrameworkInfo = project.GetTargetFramework(targetFramework); + var targetFrameworkDependencies = new List(targetFrameworkInfo.Dependencies); + + if (targetFramework != null && targetFramework.IsDesktop()) + { + targetFrameworkDependencies.Add(new LibraryRange("mscorlib", LibraryType.ReferenceAssembly)); + + targetFrameworkDependencies.Add(new LibraryRange("System", LibraryType.ReferenceAssembly)); + + if (targetFramework.Version >= new Version(3, 5)) + { + targetFrameworkDependencies.Add(new LibraryRange("System.Core", LibraryType.ReferenceAssembly)); + + if (targetFramework.Version >= new Version(4, 0)) + { + targetFrameworkDependencies.Add(new LibraryRange("Microsoft.CSharp", LibraryType.ReferenceAssembly)); + } + } + } + + var dependencies = project.Dependencies.Concat(targetFrameworkDependencies).ToList(); + + var loadableAssemblies = new List(); + + if (project.IsLoadable) + { + loadableAssemblies.Add(project.Name); + } + + // Mark the library as unresolved if there were specified frameworks + // and none of them resolved + bool unresolved = targetFrameworkInfo.FrameworkName == null; + + return new ProjectDescription( + new LibraryRange(project.Name, LibraryType.Unspecified), + project, + dependencies, + loadableAssemblies, + targetFrameworkInfo, + !unresolved); + } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/Resolution/ReferenceAssemblyDependencyResolver.cs b/src/Microsoft.Extensions.ProjectModel/Resolution/ReferenceAssemblyDependencyResolver.cs new file mode 100644 index 000000000..25ea02c2a --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Resolution/ReferenceAssemblyDependencyResolver.cs @@ -0,0 +1,56 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Linq; +using System.Runtime.Versioning; +using Microsoft.Extensions.ProjectModel.Graph; +using NuGet; +using NuGet.Frameworks; +using NuGet.Versioning; + +namespace Microsoft.Extensions.ProjectModel.Resolution +{ + public class ReferenceAssemblyDependencyResolver + { + public ReferenceAssemblyDependencyResolver(FrameworkReferenceResolver frameworkReferenceResolver) + { + FrameworkResolver = frameworkReferenceResolver; + } + + private FrameworkReferenceResolver FrameworkResolver { get; set; } + + public LibraryDescription GetDescription(LibraryRange libraryRange, NuGetFramework targetFramework) + { + if (!LibraryType.ReferenceAssembly.CanSatisfyConstraint(libraryRange.Target)) + { + return null; + } + + var name = libraryRange.Name; + var version = libraryRange.VersionRange?.MinVersion; + + string path; + Version assemblyVersion; + + if (!FrameworkResolver.TryGetAssembly(name, targetFramework, out path, out assemblyVersion)) + { + return null; + } + + if (version == null || version.Version == assemblyVersion) + { + return new LibraryDescription( + libraryRange, + new LibraryIdentity(libraryRange.Name, new NuGetVersion(assemblyVersion), LibraryType.ReferenceAssembly), + path, + Enumerable.Empty(), + targetFramework, + resolved: true, + compatible: true); + } + + return null; + } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/Resolution/UnresolvedDependencyProvider.cs b/src/Microsoft.Extensions.ProjectModel/Resolution/UnresolvedDependencyProvider.cs new file mode 100644 index 000000000..146a0c0c2 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Resolution/UnresolvedDependencyProvider.cs @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Linq; +using Microsoft.Extensions.ProjectModel.Graph; +using NuGet.Frameworks; + +namespace Microsoft.Extensions.ProjectModel.Resolution +{ + public class UnresolvedDependencyProvider + { + public LibraryDescription GetDescription(LibraryRange libraryRange, NuGetFramework targetFramework) + { + return new LibraryDescription( + libraryRange, + new LibraryIdentity(libraryRange.Name, libraryRange.VersionRange?.MinVersion, libraryRange.Target), + path: null, + dependencies: Enumerable.Empty(), + framework: targetFramework, + resolved: false, + compatible: false); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/TargetFrameworkInformation.cs b/src/Microsoft.Extensions.ProjectModel/TargetFrameworkInformation.cs new file mode 100644 index 000000000..26a731fcf --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/TargetFrameworkInformation.cs @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using Microsoft.Extensions.ProjectModel.Graph; +using NuGet.Frameworks; + +namespace Microsoft.Extensions.ProjectModel +{ + public class TargetFrameworkInformation : IFrameworkTargetable + { + public NuGetFramework FrameworkName { get; set; } + + public IReadOnlyList Dependencies { get; set; } + + public string WrappedProject { get; set; } + + public string AssemblyPath { get; set; } + + public string PdbPath { get; set; } + + public IEnumerable SupportedFrameworks + { + get + { + return new[] { FrameworkName }; + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/Utilities/DictionaryExtensions.cs b/src/Microsoft.Extensions.ProjectModel/Utilities/DictionaryExtensions.cs new file mode 100644 index 000000000..01f592f22 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Utilities/DictionaryExtensions.cs @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace System.Collections.Generic +{ + internal static class DictionaryExtensions + { + public static TValue GetOrAdd(this IDictionary dictionary, TKey key, Func factory) + { + lock (dictionary) + { + TValue value; + if (!dictionary.TryGetValue(key, out value)) + { + value = factory(key); + dictionary[key] = value; + } + + return value; + } + } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/Utilities/FileSystemUtility.cs b/src/Microsoft.Extensions.ProjectModel/Utilities/FileSystemUtility.cs new file mode 100644 index 000000000..968ccf3ac --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Utilities/FileSystemUtility.cs @@ -0,0 +1,39 @@ +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.Extensions.ProjectModel.Utilities +{ + internal static class FileSystemUtility + { + internal static FileStream OpenFileStream(string filePath) + { + // Retry 3 times before re-throw the exception. + // It mitigates the race condition when DTH read lock file while VS is restoring projects. + + int retry = 3; + while (true) + { + try + { + return new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); + } + catch (Exception) + { + if (retry > 0) + { + retry--; + Thread.Sleep(1000); + } + else + { + throw; + } + } + } + + } + + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/Utilities/FrameworksExtensions.cs b/src/Microsoft.Extensions.ProjectModel/Utilities/FrameworksExtensions.cs new file mode 100644 index 000000000..691463b10 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Utilities/FrameworksExtensions.cs @@ -0,0 +1,20 @@ +using System.Linq; + +namespace NuGet.Frameworks +{ + public static class FrameworksExtensions + { + // HACK(anurse): NuGet.Frameworks turns "dnxcore50" into "dnxcore5" :( + public static string GetTwoDigitShortFolderName(this NuGetFramework self) + { + var original = self.GetShortFolderName(); + + var digits = original.SkipWhile(c => !char.IsDigit(c)).ToArray(); + if(digits.Length == 1) + { + return original + "0"; + } + return original; + } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/Utilities/JsonExtensions.cs b/src/Microsoft.Extensions.ProjectModel/Utilities/JsonExtensions.cs new file mode 100644 index 000000000..16b4d1392 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Utilities/JsonExtensions.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Newtonsoft.Json.Linq +{ + internal static class JsonExtensions + { + public static string[] ValueAsStringArray(this JObject self, string property) + { + var prop = self.Property(property); + if (prop != null) + { + if (prop.Value.Type == JTokenType.String) + { + return new string[] { prop.Value.ToString() }; + } + else if (prop.Value.Type == JTokenType.Array) + { + return ((JArray)prop.Value).Select(t => t.ToString()).ToArray(); + } + } + return new string[0]; + } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/Utilities/NamedResourceReader.cs b/src/Microsoft.Extensions.ProjectModel/Utilities/NamedResourceReader.cs new file mode 100644 index 000000000..aed60ae82 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Utilities/NamedResourceReader.cs @@ -0,0 +1,76 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.IO; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Extensions.ProjectModel.Utilities +{ + internal static class NamedResourceReader + { + public static IDictionary ReadNamedResources(JObject rawProject, string projectFilePath) + { + var prop = rawProject.Property("namedResource"); + if(prop == null) + { + return new Dictionary(); + } + + var namedResourceToken = prop.Value as JObject; + if (namedResourceToken == null) + { + throw FileFormatException.Create("Value must be object.", prop.Value, projectFilePath); + } + + var namedResources = new Dictionary(); + + foreach (var namedResource in namedResourceToken) + { + if (namedResource.Value.Type != JTokenType.String) + { + throw FileFormatException.Create("Value must be string.", namedResource.Value, projectFilePath); + } + var resourcePath = namedResource.Value.Value(); + + if (resourcePath.Contains("*")) + { + throw FileFormatException.Create("Value cannot contain wildcards.", namedResource.Value, projectFilePath); + } + + var resourceFileFullPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(projectFilePath), resourcePath)); + + if (namedResources.ContainsKey(namedResource.Key)) + { + throw FileFormatException.Create( + $"The named resource {namedResource.Key} already exists.", + namedResource.Value, + projectFilePath); + } + + namedResources.Add( + namedResource.Key, + resourceFileFullPath); + } + + return namedResources; + } + + public static void ApplyNamedResources(IDictionary namedResources, IDictionary resources) + { + foreach (var namedResource in namedResources) + { + // The named resources dictionary is like the project file + // key = name, value = path to resource + if (resources.ContainsKey(namedResource.Value)) + { + resources[namedResource.Value] = namedResource.Key; + } + else + { + resources.Add(namedResource.Value, namedResource.Key); + } + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/Utilities/PathUtility.cs b/src/Microsoft.Extensions.ProjectModel/Utilities/PathUtility.cs new file mode 100644 index 000000000..8b3aceeb4 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Utilities/PathUtility.cs @@ -0,0 +1,202 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; +using System.Runtime.InteropServices; + +namespace Microsoft.Extensions.ProjectModel.Utilities +{ + internal static class PathUtility + { + public static bool IsPlaceholderFile(string path) + { + return string.Equals(Path.GetFileName(path), "_._", StringComparison.Ordinal); + } + + public static bool IsChildOfDirectory(string dir, string candidate) + { + if (dir == null) + { + throw new ArgumentNullException(nameof(dir)); + } + if (candidate == null) + { + throw new ArgumentNullException(nameof(candidate)); + } + dir = Path.GetFullPath(dir); + dir = EnsureTrailingSlash(dir); + candidate = Path.GetFullPath(candidate); + return candidate.StartsWith(dir, StringComparison.OrdinalIgnoreCase); + } + + public static string EnsureTrailingSlash(string path) + { + return EnsureTrailingCharacter(path, Path.DirectorySeparatorChar); + } + + public static string EnsureTrailingForwardSlash(string path) + { + return EnsureTrailingCharacter(path, '/'); + } + + private static string EnsureTrailingCharacter(string path, char trailingCharacter) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + // if the path is empty, we want to return the original string instead of a single trailing character. + if (path.Length == 0 || path[path.Length - 1] == trailingCharacter) + { + return path; + } + + return path + trailingCharacter; + } + + public static void EnsureParentDirectory(string filePath) + { + string directory = Path.GetDirectoryName(filePath); + if (!Directory.Exists(directory)) + { + Directory.CreateDirectory(directory); + } + } + + /// + /// Returns path2 relative to path1, with Path.DirectorySeparatorChar as separator + /// + public static string GetRelativePath(string path1, string path2) + { + return GetRelativePath(path1, path2, Path.DirectorySeparatorChar); + } + + /// + /// Returns path2 relative to path1, with given path separator + /// + public static string GetRelativePath(string path1, string path2, char separator) + { + if (string.IsNullOrEmpty(path1)) + { + throw new ArgumentException("Path must have a value", nameof(path1)); + } + + if (string.IsNullOrEmpty(path2)) + { + throw new ArgumentException("Path must have a value", nameof(path2)); + } + + StringComparison compare; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + compare = StringComparison.OrdinalIgnoreCase; + // check if paths are on the same volume + if (!string.Equals(Path.GetPathRoot(path1), Path.GetPathRoot(path2))) + { + // on different volumes, "relative" path is just path2 + return path2; + } + } + else + { + compare = StringComparison.Ordinal; + } + + var index = 0; + var path1Segments = path1.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); + var path2Segments = path2.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); + // if path1 does not end with / it is assumed the end is not a directory + // we will assume that is isn't a directory by ignoring the last split + var len1 = path1Segments.Length - 1; + var len2 = path2Segments.Length; + + // find largest common absolute path between both paths + var min = Math.Min(len1, len2); + while (min > index) + { + if (!string.Equals(path1Segments[index], path2Segments[index], compare)) + { + break; + } + // Handle scenarios where folder and file have same name (only if os supports same name for file and directory) + // e.g. /file/name /file/name/app + else if ((len1 == index && len2 > index + 1) || (len1 > index && len2 == index + 1)) + { + break; + } + ++index; + } + + var path = ""; + + // check if path2 ends with a non-directory separator and if path1 has the same non-directory at the end + if (len1 + 1 == len2 && !string.IsNullOrEmpty(path1Segments[index]) && + string.Equals(path1Segments[index], path2Segments[index], compare)) + { + return path; + } + + for (var i = index; len1 > i; ++i) + { + path += ".." + separator; + } + for (var i = index; len2 - 1 > i; ++i) + { + path += path2Segments[i] + separator; + } + // if path2 doesn't end with an empty string it means it ended with a non-directory name, so we add it back + if (!string.IsNullOrEmpty(path2Segments[len2 - 1])) + { + path += path2Segments[len2 - 1]; + } + + return path; + } + + public static string GetAbsolutePath(string basePath, string relativePath) + { + if (basePath == null) + { + throw new ArgumentNullException(nameof(basePath)); + } + + if (relativePath == null) + { + throw new ArgumentNullException(nameof(relativePath)); + } + + Uri resultUri = new Uri(new Uri(basePath), new Uri(relativePath, UriKind.Relative)); + return resultUri.LocalPath; + } + + public static string GetDirectoryName(string path) + { + path = path.TrimEnd(Path.DirectorySeparatorChar); + return path.Substring(Path.GetDirectoryName(path).Length).Trim(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); + } + + public static string GetPathWithForwardSlashes(string path) + { + return path.Replace('\\', '/'); + } + + public static string GetPathWithBackSlashes(string path) + { + return path.Replace('/', '\\'); + } + + public static string GetPathWithDirectorySeparator(string path) + { + if (Path.DirectorySeparatorChar == '/') + { + return GetPathWithForwardSlashes(path); + } + else + { + return GetPathWithBackSlashes(path); + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel/Utilities/VersionUtility.cs b/src/Microsoft.Extensions.ProjectModel/Utilities/VersionUtility.cs new file mode 100644 index 000000000..087c625f7 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Utilities/VersionUtility.cs @@ -0,0 +1,18 @@ +using System; +using System.Runtime.Loader; +using NuGet.Versioning; + +namespace Microsoft.Extensions.ProjectModel.Utilities +{ + internal static class VersionUtility + { + public static NuGetVersion GetAssemblyVersion(string path) + { +//#if NET451 +// return new NuGetVersion(AssemblyName.GetAssemblyName(path).Version); +//#else + return new NuGetVersion(AssemblyLoadContext.GetAssemblyName(path).Version); +//#endif + } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/Utilities/VersioningExtensions.cs b/src/Microsoft.Extensions.ProjectModel/Utilities/VersioningExtensions.cs new file mode 100644 index 000000000..7b91bcffd --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/Utilities/VersioningExtensions.cs @@ -0,0 +1,45 @@ +using System; + +namespace NuGet.Versioning +{ + public static class VersioningExtensions + { + public static bool EqualsFloating(this VersionRange self, NuGetVersion version) + { + if(!self.IsFloating) + { + return Equals(self.MinVersion, version); + } + + switch (self.Float.FloatBehavior) + { + case NuGetVersionFloatBehavior.Prerelease: + return self.MinVersion.Version == version.Version && + version.Release.StartsWith(self.MinVersion.Release, StringComparison.OrdinalIgnoreCase); + + case NuGetVersionFloatBehavior.Revision: + return self.MinVersion.Major == version.Major && + self.MinVersion.Minor == version.Minor && + self.MinVersion.Patch == version.Patch && + self.MinVersion.Revision == version.Revision; + + case NuGetVersionFloatBehavior.Patch: + return self.MinVersion.Major == version.Major && + self.MinVersion.Minor == version.Minor && + self.MinVersion.Patch == version.Patch; + + case NuGetVersionFloatBehavior.Minor: + return self.MinVersion.Major == version.Major && + self.MinVersion.Minor == version.Minor; + + case NuGetVersionFloatBehavior.Major: + return self.MinVersion.Major == version.Major; + + case NuGetVersionFloatBehavior.None: + return self.MinVersion == version; + default: + return false; + } + } + } +} diff --git a/src/Microsoft.Extensions.ProjectModel/project.json b/src/Microsoft.Extensions.ProjectModel/project.json new file mode 100644 index 000000000..63fdc5cc8 --- /dev/null +++ b/src/Microsoft.Extensions.ProjectModel/project.json @@ -0,0 +1,25 @@ +{ + "version": "1.0.0-*", + "description": "Types to model a .NET Project", + + "dependencies": { + "Microsoft.CSharp": "4.0.1-*", + "System.Collections": "4.0.11-*", + "System.Linq": "4.0.1-*", + "System.Threading.Thread": "4.0.0-*", + "System.Runtime.Loader": "4.0.0-*", + "System.Dynamic.Runtime": "4.0.11-*", + "System.Runtime.InteropServices.RuntimeInformation": "4.0.0-*", + + "NuGet.Packaging": "3.2.0", + + "Newtonsoft.Json": "7.0.1", + + "Microsoft.Extensions.FileSystemGlobbing": "1.0.0-*", + "Microsoft.Extensions.HashCodeCombiner.Sources": { "type": "build", "version": "1.0.0-*" } + }, + + "frameworks": { + "dnxcore50": { } + } +}