Add application model detection package (#119)
This commit is contained in:
parent
5b0cf49d0d
commit
db6c04818e
|
|
@ -1,4 +1,4 @@
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 15.0.27004.2002
|
VisualStudioVersion = 15.0.27004.2002
|
||||||
MinimumVisualStudioVersion = 15.0.26730.03
|
MinimumVisualStudioVersion = 15.0.26730.03
|
||||||
|
|
@ -50,6 +50,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Web.Xdt.Extension
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.AzureAppServices.SiteExtension.Tests", "test\Microsoft.AspNetCore.AzureAppServices.SiteExtension.Tests\Microsoft.AspNetCore.AzureAppServices.SiteExtension.Tests.csproj", "{491A857A-3529-4375-985D-D748F9F01476}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.AzureAppServices.SiteExtension.Tests", "test\Microsoft.AspNetCore.AzureAppServices.SiteExtension.Tests\Microsoft.AspNetCore.AzureAppServices.SiteExtension.Tests.csproj", "{491A857A-3529-4375-985D-D748F9F01476}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Extensions.ApplicationModelDetection", "src\Microsoft.Extensions.ApplicationModelDetection\Microsoft.Extensions.ApplicationModelDetection.csproj", "{F0CABFE8-A5B1-487B-A451-A486D26742D3}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Extensions.ApplicationModelDetection.Tests", "test\Microsoft.Extensions.ApplicationModelDetection.Tests\Microsoft.Extensions.ApplicationModelDetection.Tests.csproj", "{15664836-2B94-4D2D-AC18-6DED01FCCCBD}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|
@ -112,6 +116,14 @@ Global
|
||||||
{491A857A-3529-4375-985D-D748F9F01476}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{491A857A-3529-4375-985D-D748F9F01476}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{491A857A-3529-4375-985D-D748F9F01476}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{491A857A-3529-4375-985D-D748F9F01476}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{491A857A-3529-4375-985D-D748F9F01476}.Release|Any CPU.Build.0 = Release|Any CPU
|
{491A857A-3529-4375-985D-D748F9F01476}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{F0CABFE8-A5B1-487B-A451-A486D26742D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{F0CABFE8-A5B1-487B-A451-A486D26742D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{F0CABFE8-A5B1-487B-A451-A486D26742D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{F0CABFE8-A5B1-487B-A451-A486D26742D3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{15664836-2B94-4D2D-AC18-6DED01FCCCBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{15664836-2B94-4D2D-AC18-6DED01FCCCBD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{15664836-2B94-4D2D-AC18-6DED01FCCCBD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{15664836-2B94-4D2D-AC18-6DED01FCCCBD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
@ -131,6 +143,8 @@ Global
|
||||||
{1EC31DA1-131D-4257-B001-BE8391E6077E} = {FF9B744E-6C59-40CC-9E41-9D2EBD292435}
|
{1EC31DA1-131D-4257-B001-BE8391E6077E} = {FF9B744E-6C59-40CC-9E41-9D2EBD292435}
|
||||||
{809AEE05-1B28-4E31-8959-776B249BD725} = {CD650B4B-81C2-4A44-AEF2-A251A877C1F0}
|
{809AEE05-1B28-4E31-8959-776B249BD725} = {CD650B4B-81C2-4A44-AEF2-A251A877C1F0}
|
||||||
{491A857A-3529-4375-985D-D748F9F01476} = {CD650B4B-81C2-4A44-AEF2-A251A877C1F0}
|
{491A857A-3529-4375-985D-D748F9F01476} = {CD650B4B-81C2-4A44-AEF2-A251A877C1F0}
|
||||||
|
{F0CABFE8-A5B1-487B-A451-A486D26742D3} = {FF9B744E-6C59-40CC-9E41-9D2EBD292435}
|
||||||
|
{15664836-2B94-4D2D-AC18-6DED01FCCCBD} = {CD650B4B-81C2-4A44-AEF2-A251A877C1F0}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {5743DFE7-1AA5-439D-84AE-A480EA389927}
|
SolutionGuid = {5743DFE7-1AA5-439D-84AE-A480EA389927}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@
|
||||||
"AdxVerificationCompositeRule"
|
"AdxVerificationCompositeRule"
|
||||||
],
|
],
|
||||||
"packages": {
|
"packages": {
|
||||||
"Microsoft.AspNetCore.AzureAppServicesIntegration": { }
|
"Microsoft.AspNetCore.AzureAppServicesIntegration": { },
|
||||||
|
"Microsoft.Extensions.ApplicationModelDetection": { }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Default": { // Rules to run for packages not listed in any other set.
|
"Default": { // Rules to run for packages not listed in any other set.
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@
|
||||||
<MicrosoftNETTestSdkPackageVersion>15.3.0</MicrosoftNETTestSdkPackageVersion>
|
<MicrosoftNETTestSdkPackageVersion>15.3.0</MicrosoftNETTestSdkPackageVersion>
|
||||||
<MicrosoftWebXdtPackageVersion>1.4.0</MicrosoftWebXdtPackageVersion>
|
<MicrosoftWebXdtPackageVersion>1.4.0</MicrosoftWebXdtPackageVersion>
|
||||||
<MoqPackageVersion>4.7.49</MoqPackageVersion>
|
<MoqPackageVersion>4.7.49</MoqPackageVersion>
|
||||||
|
<NewtonsoftJsonPackageVersion>10.0.1</NewtonsoftJsonPackageVersion>
|
||||||
|
<SystemReflectionMetadataPackageVersion>1.5.0</SystemReflectionMetadataPackageVersion>
|
||||||
<WindowsAzureStoragePackageVersion>8.1.4</WindowsAzureStoragePackageVersion>
|
<WindowsAzureStoragePackageVersion>8.1.4</WindowsAzureStoragePackageVersion>
|
||||||
<XunitPackageVersion>2.3.0</XunitPackageVersion>
|
<XunitPackageVersion>2.3.0</XunitPackageVersion>
|
||||||
<XunitRunnerVisualStudioPackageVersion>2.3.0</XunitRunnerVisualStudioPackageVersion>
|
<XunitRunnerVisualStudioPackageVersion>2.3.0</XunitRunnerVisualStudioPackageVersion>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
// 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.ApplicationModelDetection
|
||||||
|
{
|
||||||
|
public class AppModelDetectionResult
|
||||||
|
{
|
||||||
|
public RuntimeFramework? Framework { get; set; }
|
||||||
|
public string FrameworkVersion { get; set; }
|
||||||
|
public string AspNetCoreVersion { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,250 @@
|
||||||
|
// 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.Linq;
|
||||||
|
using System.Reflection.Metadata;
|
||||||
|
using System.Reflection.PortableExecutable;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace Microsoft.Extensions.ApplicationModelDetection
|
||||||
|
{
|
||||||
|
public class AppModelDetector
|
||||||
|
{
|
||||||
|
// We use Hosting package to detect AspNetCore version
|
||||||
|
// it contains light-up implemenation that we care about and
|
||||||
|
// would have to be used by aspnet core web apps
|
||||||
|
private const string AspNetCoreAssembly = "Microsoft.AspNetCore.Hosting";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads the following sources
|
||||||
|
/// - web.config to detect dotnet framework kind
|
||||||
|
/// - *.runtimeconfig.json to detect target framework version
|
||||||
|
/// - *.deps.json to detect Asp.Net Core version
|
||||||
|
/// - Microsoft.AspNetCore.Hosting.dll to detect Asp.Net Core version
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="directory">The application directory</param>
|
||||||
|
/// <returns>The <see cref="AppModelDetectionResult"/> instance containing information about application</returns>
|
||||||
|
public AppModelDetectionResult Detect(DirectoryInfo directory)
|
||||||
|
{
|
||||||
|
string entryPoint = null;
|
||||||
|
|
||||||
|
// Try reading web.config and resolving framework and app path
|
||||||
|
var webConfig = directory.GetFiles("web.config").FirstOrDefault();
|
||||||
|
|
||||||
|
bool webConfigExists = webConfig != null;
|
||||||
|
bool? usesDotnetExe = null;
|
||||||
|
|
||||||
|
if (webConfigExists &&
|
||||||
|
TryParseWebConfig(webConfig, out var dotnetExe, out entryPoint))
|
||||||
|
{
|
||||||
|
usesDotnetExe = dotnetExe;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we found entry point let's look for .deps.json
|
||||||
|
// in some cases it exists in desktop too
|
||||||
|
FileInfo depsJson = null;
|
||||||
|
FileInfo runtimeConfig = null;
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(entryPoint))
|
||||||
|
{
|
||||||
|
depsJson = new FileInfo(Path.ChangeExtension(entryPoint, ".deps.json"));
|
||||||
|
runtimeConfig = new FileInfo(Path.ChangeExtension(entryPoint, ".runtimeconfig.json"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depsJson == null || !depsJson.Exists)
|
||||||
|
{
|
||||||
|
depsJson = directory.GetFiles("*.deps.json").FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runtimeConfig == null || !runtimeConfig.Exists)
|
||||||
|
{
|
||||||
|
runtimeConfig = directory.GetFiles("*.runtimeconfig.json").FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
string aspNetCoreVersionFromDeps = null;
|
||||||
|
string aspNetCoreVersionFromDll = null;
|
||||||
|
|
||||||
|
|
||||||
|
// Try to detect ASP.NET Core version from .deps.json
|
||||||
|
if (depsJson != null &&
|
||||||
|
depsJson.Exists &&
|
||||||
|
TryParseDependencies(depsJson, out var aspNetCoreVersion))
|
||||||
|
{
|
||||||
|
aspNetCoreVersionFromDeps = aspNetCoreVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to detect ASP.NET Core version from .deps.json
|
||||||
|
var aspNetCoreDll = directory.GetFiles(AspNetCoreAssembly + ".dll").FirstOrDefault();
|
||||||
|
if (aspNetCoreDll != null &&
|
||||||
|
TryParseAssembly(aspNetCoreDll, out aspNetCoreVersion))
|
||||||
|
{
|
||||||
|
aspNetCoreVersionFromDll = aspNetCoreVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to detect dotnet core runtime version from runtimeconfig.json
|
||||||
|
string runtimeVersionFromRuntimeConfig = null;
|
||||||
|
if (runtimeConfig != null &&
|
||||||
|
runtimeConfig.Exists)
|
||||||
|
{
|
||||||
|
TryParseRuntimeConfig(runtimeConfig, out runtimeVersionFromRuntimeConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = new AppModelDetectionResult();
|
||||||
|
if (usesDotnetExe == true)
|
||||||
|
{
|
||||||
|
result.Framework = RuntimeFramework.DotNetCore;
|
||||||
|
result.FrameworkVersion = runtimeVersionFromRuntimeConfig;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (depsJson?.Exists == true &&
|
||||||
|
runtimeConfig?.Exists == true)
|
||||||
|
{
|
||||||
|
result.Framework = RuntimeFramework.DotNetCoreStandalone;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.Framework = RuntimeFramework.DotNetFramework;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.AspNetCoreVersion = aspNetCoreVersionFromDeps ?? aspNetCoreVersionFromDll;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TryParseAssembly(FileInfo aspNetCoreDll, out string aspNetCoreVersion)
|
||||||
|
{
|
||||||
|
aspNetCoreVersion = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var stream = aspNetCoreDll.OpenRead())
|
||||||
|
using (var peReader = new PEReader(stream))
|
||||||
|
{
|
||||||
|
var metadataReader = peReader.GetMetadataReader();
|
||||||
|
var assemblyDefinition = metadataReader.GetAssemblyDefinition();
|
||||||
|
aspNetCoreVersion = assemblyDefinition.Version.ToString();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Search for Microsoft.AspNetCore.Hosting entry in deps.json and get it's version number
|
||||||
|
/// </summary>
|
||||||
|
private bool TryParseDependencies(FileInfo depsJson, out string aspnetCoreVersion)
|
||||||
|
{
|
||||||
|
aspnetCoreVersion = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var streamReader = depsJson.OpenText())
|
||||||
|
using (var jsonReader = new JsonTextReader(streamReader))
|
||||||
|
{
|
||||||
|
var json = JObject.Load(jsonReader);
|
||||||
|
|
||||||
|
var libraryPrefix = AspNetCoreAssembly+ "/";
|
||||||
|
|
||||||
|
var library = json.Descendants().OfType<JProperty>().FirstOrDefault(property => property.Name.StartsWith(libraryPrefix));
|
||||||
|
if (library != null)
|
||||||
|
{
|
||||||
|
aspnetCoreVersion = library.Name.Substring(libraryPrefix.Length);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TryParseRuntimeConfig(FileInfo runtimeConfig, out string frameworkVersion)
|
||||||
|
{
|
||||||
|
frameworkVersion = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var streamReader = runtimeConfig.OpenText())
|
||||||
|
using (var jsonReader = new JsonTextReader(streamReader))
|
||||||
|
{
|
||||||
|
var json = JObject.Load(jsonReader);
|
||||||
|
frameworkVersion = (string)json?["runtimeOptions"]
|
||||||
|
?["framework"]
|
||||||
|
?["version"];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TryParseWebConfig(FileInfo webConfig, out bool usesDotnetExe, out string entryPoint)
|
||||||
|
{
|
||||||
|
usesDotnetExe = false;
|
||||||
|
entryPoint = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var xdocument = XDocument.Load(webConfig.FullName);
|
||||||
|
var aspNetCoreHandler = xdocument.Root?
|
||||||
|
.Element("system.webServer")
|
||||||
|
.Element("aspNetCore");
|
||||||
|
|
||||||
|
if (aspNetCoreHandler == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var processPath = (string) aspNetCoreHandler.Attribute("processPath");
|
||||||
|
var arguments = (string) aspNetCoreHandler.Attribute("arguments");
|
||||||
|
|
||||||
|
if (processPath.EndsWith("dotnet", StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
processPath.EndsWith("dotnet.exe", StringComparison.OrdinalIgnoreCase) &&
|
||||||
|
!string.IsNullOrWhiteSpace(arguments))
|
||||||
|
{
|
||||||
|
usesDotnetExe = true;
|
||||||
|
var entryPointPart = arguments.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(entryPointPart))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
entryPoint = Path.GetFullPath(Path.Combine(webConfig.DirectoryName, entryPointPart));
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usesDotnetExe = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
entryPoint = Path.GetFullPath(Path.Combine(webConfig.DirectoryName, processPath));
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Description>ASP.NET Core integration with Azure AppServices.</Description>
|
||||||
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
|
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
|
<PackageTags>aspnetcore;azure;appservices</PackageTags>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
|
||||||
|
<PackageReference Include="System.Reflection.Metadata" Version="$(SystemReflectionMetadataPackageVersion)" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
// 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.ApplicationModelDetection
|
||||||
|
{
|
||||||
|
public enum RuntimeFramework
|
||||||
|
{
|
||||||
|
DotNetCore,
|
||||||
|
DotNetCoreStandalone,
|
||||||
|
DotNetFramework
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,229 @@
|
||||||
|
// // 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 Microsoft.AspNetCore.Hosting;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.Extensions.ApplicationModelDetection.Tests
|
||||||
|
{
|
||||||
|
public class AppModelTests
|
||||||
|
{
|
||||||
|
private const string EmptyWebConfig = @"<?xml version=""1.0"" encoding=""utf-8""?><configuration></configuration>";
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("dotnet")]
|
||||||
|
[InlineData("dotnet.exe")]
|
||||||
|
[InlineData("%HOME%/dotnet")]
|
||||||
|
[InlineData("%HOME%/dotnet.exe")]
|
||||||
|
[InlineData("DoTNeT.ExE")]
|
||||||
|
public void DetectsCoreFrameworkFromWebConfig(string processPath)
|
||||||
|
{
|
||||||
|
using (var temp = new TemporaryDirectory()
|
||||||
|
.WithFile("web.config",GenerateWebConfig(processPath, ".\\app.dll")))
|
||||||
|
{
|
||||||
|
var result = new AppModelDetector().Detect(temp.Directory);
|
||||||
|
Assert.Equal(RuntimeFramework.DotNetCore, result.Framework);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("app")]
|
||||||
|
[InlineData("app.exe")]
|
||||||
|
[InlineData("%HOME%/app")]
|
||||||
|
[InlineData("%HOME%/app.exe")]
|
||||||
|
public void DetectsFullFrameworkFromWebConfig(string processPath)
|
||||||
|
{
|
||||||
|
using (var temp = new TemporaryDirectory()
|
||||||
|
.WithFile("web.config", GenerateWebConfig(processPath, ".\\app.dll")))
|
||||||
|
{
|
||||||
|
var result = new AppModelDetector().Detect(temp.Directory);
|
||||||
|
Assert.Equal(RuntimeFramework.DotNetFramework, result.Framework);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("2.0.0")]
|
||||||
|
[InlineData("2.0.0-preview1")]
|
||||||
|
[InlineData("1.1.3")]
|
||||||
|
public void DetectsRuntimeVersionFromRuntimeConfig(string runtimeVersion)
|
||||||
|
{
|
||||||
|
using (var temp = new TemporaryDirectory()
|
||||||
|
.WithFile("web.config", GenerateWebConfig("dotnet", ".\\app.dll"))
|
||||||
|
.WithFile("app.runtimeconfig.json", @"{
|
||||||
|
""runtimeOptions"": {
|
||||||
|
""tfm"": ""netcoreapp2.0"",
|
||||||
|
""framework"": {
|
||||||
|
""name"": ""Microsoft.NETCore.App"",
|
||||||
|
""version"": """+ runtimeVersion + @"""
|
||||||
|
},
|
||||||
|
""configProperties"": {
|
||||||
|
""System.GC.Server"": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}"))
|
||||||
|
{
|
||||||
|
var result = new AppModelDetector().Detect(temp.Directory);
|
||||||
|
Assert.Equal(RuntimeFramework.DotNetCore, result.Framework);
|
||||||
|
Assert.Equal(runtimeVersion, result.FrameworkVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("2.0.0")]
|
||||||
|
[InlineData("2.0.0-preview1")]
|
||||||
|
[InlineData("1.1.3")]
|
||||||
|
public void DetectsRuntimeVersionFromRuntimeConfigWitoutEntryPoint(string runtimeVersion)
|
||||||
|
{
|
||||||
|
using (var temp = new TemporaryDirectory()
|
||||||
|
.WithFile("web.config", GenerateWebConfig("dotnet", "%HOME%\\app.dll"))
|
||||||
|
.WithFile("app.runtimeconfig.json", @"{
|
||||||
|
""runtimeOptions"": {
|
||||||
|
""tfm"": ""netcoreapp2.0"",
|
||||||
|
""framework"": {
|
||||||
|
""name"": ""Microsoft.NETCore.App"",
|
||||||
|
""version"": """+ runtimeVersion + @"""
|
||||||
|
},
|
||||||
|
""configProperties"": {
|
||||||
|
""System.GC.Server"": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}"))
|
||||||
|
{
|
||||||
|
var result = new AppModelDetector().Detect(temp.Directory);
|
||||||
|
Assert.Equal(RuntimeFramework.DotNetCore, result.Framework);
|
||||||
|
Assert.Equal(runtimeVersion, result.FrameworkVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("2.0.0")]
|
||||||
|
[InlineData("2.0.0-preview1")]
|
||||||
|
[InlineData("1.1.3")]
|
||||||
|
public void DetectsAspNetCoreVersionFromDepsFile(string runtimeVersion)
|
||||||
|
{
|
||||||
|
using (var temp = new TemporaryDirectory()
|
||||||
|
.WithFile("web.config", GenerateWebConfig("dotnet", "app.dll"))
|
||||||
|
.WithFile("app.deps.json", @"{
|
||||||
|
""targets"": {
|
||||||
|
"".NETCoreApp,Version=v2.7"": {
|
||||||
|
""Microsoft.AspNetCore.Hosting/" + runtimeVersion + @""": { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}"))
|
||||||
|
{
|
||||||
|
var result = new AppModelDetector().Detect(temp.Directory);
|
||||||
|
Assert.Equal(RuntimeFramework.DotNetCore, result.Framework);
|
||||||
|
Assert.Equal(runtimeVersion, result.AspNetCoreVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("2.0.0")]
|
||||||
|
[InlineData("2.0.0-preview1")]
|
||||||
|
[InlineData("1.1.3")]
|
||||||
|
public void DetectsAspNetCoreVersionFromDepsFileWithoutEntryPoint(string runtimeVersion)
|
||||||
|
{
|
||||||
|
using (var temp = new TemporaryDirectory()
|
||||||
|
.WithFile("web.config", GenerateWebConfig("dotnet", "%HOME%\\app.dll"))
|
||||||
|
.WithFile("app.deps.json", @"{
|
||||||
|
""targets"": {
|
||||||
|
"".NETCoreApp,Version=v2.7"": {
|
||||||
|
""Microsoft.AspNetCore.Hosting/" + runtimeVersion + @""": { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}"))
|
||||||
|
{
|
||||||
|
var result = new AppModelDetector().Detect(temp.Directory);
|
||||||
|
Assert.Equal(RuntimeFramework.DotNetCore, result.Framework);
|
||||||
|
Assert.Equal(runtimeVersion, result.AspNetCoreVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DetectsFullFrameworkWhenWebConfigExists()
|
||||||
|
{
|
||||||
|
using (var temp = new TemporaryDirectory()
|
||||||
|
.WithFile("web.config", EmptyWebConfig))
|
||||||
|
{
|
||||||
|
var result = new AppModelDetector().Detect(temp.Directory);
|
||||||
|
Assert.Equal(RuntimeFramework.DotNetFramework, result.Framework);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DetectsStandalone_WhenBothDepsAndRuntimeConfigExist()
|
||||||
|
{
|
||||||
|
using (var temp = new TemporaryDirectory()
|
||||||
|
.WithFile("web.config", GenerateWebConfig("app.exe", ""))
|
||||||
|
.WithFile("app.runtimeconfig.json", "{}")
|
||||||
|
.WithFile("app.deps.json", "{}"))
|
||||||
|
{
|
||||||
|
var result = new AppModelDetector().Detect(temp.Directory);
|
||||||
|
Assert.Equal(RuntimeFramework.DotNetCoreStandalone, result.Framework);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DetectsAspNetCoreVersionFromHostingDll()
|
||||||
|
{
|
||||||
|
using (var temp = new TemporaryDirectory()
|
||||||
|
.WithFile(typeof(WebHostBuilder).Assembly.Location))
|
||||||
|
{
|
||||||
|
var result = new AppModelDetector().Detect(temp.Directory);
|
||||||
|
Assert.Equal(typeof(WebHostBuilder).Assembly.GetName().Version.ToString(), result.AspNetCoreVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GenerateWebConfig(string processPath, string arguments)
|
||||||
|
{
|
||||||
|
return $@"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||||
|
<configuration>
|
||||||
|
<system.webServer>
|
||||||
|
<handlers>
|
||||||
|
<add name=""aspNetCore"" path=""*"" verb=""*"" modules=""AspNetCoreModule"" resourceType=""Unspecified"" />
|
||||||
|
</handlers>
|
||||||
|
<aspNetCore processPath=""{processPath}"" arguments=""{arguments}"" stdoutLogEnabled=""false"" stdoutLogFile="".\logs\stdout"" />
|
||||||
|
</system.webServer>
|
||||||
|
</configuration>
|
||||||
|
";
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TemporaryDirectory: IDisposable
|
||||||
|
{
|
||||||
|
public TemporaryDirectory()
|
||||||
|
{
|
||||||
|
Directory = new DirectoryInfo(Path.GetTempPath())
|
||||||
|
.CreateSubdirectory(Guid.NewGuid().ToString("N"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public DirectoryInfo Directory { get; }
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.Delete(true);
|
||||||
|
}
|
||||||
|
catch (IOException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TemporaryDirectory WithFile(string name, string value)
|
||||||
|
{
|
||||||
|
File.WriteAllText(Path.Combine(Directory.FullName, name), value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public TemporaryDirectory WithFile(string name)
|
||||||
|
{
|
||||||
|
File.Copy(name, Path.Combine(Directory.FullName, Path.GetFileName(name)));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
|
||||||
|
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Microsoft.Extensions.ApplicationModelDetection\Microsoft.Extensions.ApplicationModelDetection.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
Loading…
Reference in New Issue