Skip to content
This repository was archived by the owner on Apr 20, 2023. It is now read-only.

Commit e70f071

Browse files
author
William Li
authored
Apphost shim (#8893)
* Publish app host to folder under SDK * Use carried apphost as shim * Remove full framework launcher * Fix test run command issue * Use latest release/2.1 build * Test with 32 bit env * Add missing return * Update to latest prodcon build * Add xlfs
1 parent 113f008 commit e70f071

28 files changed

+532
-284
lines changed

Microsoft.DotNet.Cli.sln

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestPackages", "TestPackage
2222
EndProject
2323
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{89905EC4-BC0F-443B-8ADF-691321F10108}"
2424
ProjectSection(SolutionItems) = preProject
25+
build\AppHostTemplate.proj = build\AppHostTemplate.proj
2526
build\AzureInfo.props = build\AzureInfo.props
2627
build\BackwardsCompatibilityRuntimes.props = build\BackwardsCompatibilityRuntimes.props
2728
build\BranchInfo.props = build\BranchInfo.props
2829
build\Branding.props = build\Branding.props
2930
build\BuildDefaults.props = build\BuildDefaults.props
3031
build\BuildInfo.targets = build\BuildInfo.targets
32+
build\BundledDotnetTools.proj = build\BundledDotnetTools.proj
33+
build\BundledDotnetTools.props = build\BundledDotnetTools.props
3134
build\BundledRuntimes.props = build\BundledRuntimes.props
3235
build\BundledSdks.props = build\BundledSdks.props
3336
build\BundledTemplates.proj = build\BundledTemplates.proj

build/AppHostTemplate.proj

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<Project ToolsVersion="15.0" DefaultTargets="ExtractAppHostToOutput">
2+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
3+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.tasks))\dir.tasks" />
4+
5+
<PropertyGroup>
6+
<NativeExecutableExtension Condition=" $(Rid.StartsWith('win'))">.exe</NativeExecutableExtension>
7+
<AppHostExecutableName>AppHost$(NativeExecutableExtension)</AppHostExecutableName>
8+
</PropertyGroup>
9+
10+
<Target Name="ExtractAppHostToOutput"
11+
Condition="!Exists('$(AppHostTemplatePath)/$(AppHostExecutableName)')"
12+
DependsOnTargets="EnsureAppHostPackageRestored">
13+
14+
<Message Text="Restore $(TemplateFillInPackageName) from $(AppHostTemplatePath) to $(AppHostTemplateRestoreAdditionalParameters)."
15+
Importance="High" />
16+
17+
<ItemGroup>
18+
<AllFileOfRestoredAppHostPackage Include="$(AppHostIntermediateDirectory)\**\*.*" />
19+
<NativeRestoredAppHostNETCore
20+
Include="@(AllFileOfRestoredAppHostPackage)"
21+
Condition="'%(FileName)%(Extension)' == '$(AppHostExecutableName)'"/>
22+
</ItemGroup>
23+
24+
<Error Condition="@(NativeRestoredAppHostNETCore->Distinct()->Count()) != 1"
25+
Text="Failed to determine the $(_NETCoreDotNetAppHostPackageName) executable in $(AllFileOfRestoredAppHostPackage)" />
26+
27+
<Copy
28+
SourceFiles="@(NativeRestoredAppHostNETCore)"
29+
DestinationFolder="$(AppHostTemplatePath)" />
30+
31+
<Message Text="Copy from @(NativeRestoredAppHostNETCore) to $(AppHostTemplatePath)."
32+
Importance="High" />
33+
34+
</Target>
35+
36+
<Target Name="EnsureAppHostPackageRestored">
37+
<PropertyGroup>
38+
<AppHostTemplateRestoreAdditionalParameters>--runtime $(Rid)</AppHostTemplateRestoreAdditionalParameters>
39+
<AppHostTemplateRestoreAdditionalParameters>$(AppHostTemplateRestoreAdditionalParameters) /p:TargetFramework=$(CliTargetFramework)</AppHostTemplateRestoreAdditionalParameters>
40+
<AppHostTemplateRestoreAdditionalParameters>$(AppHostTemplateRestoreAdditionalParameters) /p:TemplateFillInPackageName=$(TemplateFillInPackageName)</AppHostTemplateRestoreAdditionalParameters>
41+
<AppHostTemplateRestoreAdditionalParameters>$(AppHostTemplateRestoreAdditionalParameters) /p:TemplateFillInPackageVersion=$(TemplateFillInPackageVersion)</AppHostTemplateRestoreAdditionalParameters>
42+
<AppHostTemplateRestoreAdditionalParameters>$(AppHostTemplateRestoreAdditionalParameters) /p:RestorePackagesPath=$(AppHostIntermediateDirectory)</AppHostTemplateRestoreAdditionalParameters>
43+
</PropertyGroup>
44+
45+
<DotNetRestore ToolPath="$(PreviousStageDirectory)"
46+
ProjectPath="$(MSBuildThisFileDirectory)/templates/templates.csproj"
47+
AdditionalParameters="$(AppHostTemplateRestoreAdditionalParameters)" />
48+
</Target>
49+
</Project>

build/DependencyVersions.props

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
33
<PropertyGroup>
44
<MicrosoftAspNetCoreAppPackageVersion>2.1.0-preview2-30475</MicrosoftAspNetCoreAppPackageVersion>
5-
<MicrosoftNETCoreAppPackageVersion>2.1.0-preview2-26314-02</MicrosoftNETCoreAppPackageVersion>
5+
<MicrosoftNETCoreAppPackageVersion>2.1.0-preview2-26330-03</MicrosoftNETCoreAppPackageVersion>
66
<MicrosoftNETCoreDotNetHostResolverPackageVersion>$(MicrosoftNETCoreAppPackageVersion)</MicrosoftNETCoreDotNetHostResolverPackageVersion>
77
<MicrosoftBuildPackageVersion>15.7.0-preview-000127</MicrosoftBuildPackageVersion>
88
<MicrosoftBuildFrameworkPackageVersion>$(MicrosoftBuildPackageVersion)</MicrosoftBuildFrameworkPackageVersion>
@@ -28,8 +28,8 @@
2828
<MicrosoftTemplateEngineCliLocalizationPackageVersion>$(MicrosoftTemplateEngineCliPackageVersion)</MicrosoftTemplateEngineCliLocalizationPackageVersion>
2929
<MicrosoftTemplateEngineOrchestratorRunnableProjectsPackageVersion>$(MicrosoftTemplateEngineCliPackageVersion)</MicrosoftTemplateEngineOrchestratorRunnableProjectsPackageVersion>
3030
<MicrosoftTemplateEngineUtilsPackageVersion>$(MicrosoftTemplateEngineCliPackageVersion)</MicrosoftTemplateEngineUtilsPackageVersion>
31-
<MicrosoftDotNetPlatformAbstractionsPackageVersion>2.1.0-preview2-26314-02</MicrosoftDotNetPlatformAbstractionsPackageVersion>
32-
<MicrosoftExtensionsDependencyModelPackageVersion>2.1.0-preview2-26314-02</MicrosoftExtensionsDependencyModelPackageVersion>
31+
<MicrosoftDotNetPlatformAbstractionsPackageVersion>2.1.0-preview2-26330-03</MicrosoftDotNetPlatformAbstractionsPackageVersion>
32+
<MicrosoftExtensionsDependencyModelPackageVersion>2.1.0-preview2-26330-03</MicrosoftExtensionsDependencyModelPackageVersion>
3333
<MicrosoftDotNetCliCommandLinePackageVersion>0.1.1-alpha-174</MicrosoftDotNetCliCommandLinePackageVersion>
3434
<MicrosoftDotNetProjectJsonMigrationPackageVersion>1.2.1-alpha-002133</MicrosoftDotNetProjectJsonMigrationPackageVersion>
3535
<MicrosoftDotNetToolsMigrateCommandPackageVersion>$(MicrosoftDotNetProjectJsonMigrationPackageVersion)</MicrosoftDotNetToolsMigrateCommandPackageVersion>
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// Copyright (c) .NET Foundation and contributors. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System.IO;
5+
using System.Text;
6+
7+
namespace Microsoft.DotNet.Cli.Utils
8+
{
9+
/// <summary>
10+
/// Embeds the App Name into the AppHost.exe
11+
/// </summary>
12+
public static class EmbedAppNameInHost
13+
{
14+
private static string _placeHolder = "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2"; //hash value embedded in default apphost executable
15+
private static byte[] _bytesToSearch = Encoding.UTF8.GetBytes(_placeHolder);
16+
public static void EmbedAndReturnModifiedAppHostPath(
17+
string appHostSourceFilePath,
18+
string appHostDestinationFilePath,
19+
string appBinaryName)
20+
{
21+
var hostExtension = Path.GetExtension(appHostSourceFilePath);
22+
var appbaseName = Path.GetFileNameWithoutExtension(appBinaryName);
23+
var bytesToWrite = Encoding.UTF8.GetBytes(appBinaryName);
24+
var destinationDirectory = new FileInfo(appHostDestinationFilePath).Directory.FullName;
25+
26+
if (File.Exists(appHostDestinationFilePath))
27+
{
28+
//We have already done the required modification to apphost.exe
29+
return;
30+
}
31+
32+
if (bytesToWrite.Length > 1024)
33+
{
34+
throw new EmbedAppNameInHostException(string.Format(LocalizableStrings.EmbedAppNameInHostFileNameIsTooLong, appBinaryName));
35+
}
36+
37+
var array = File.ReadAllBytes(appHostSourceFilePath);
38+
39+
SearchAndReplace(array, _bytesToSearch, bytesToWrite, appHostSourceFilePath);
40+
41+
if (!Directory.Exists(destinationDirectory))
42+
{
43+
Directory.CreateDirectory(destinationDirectory);
44+
}
45+
46+
// Copy AppHostSourcePath to ModifiedAppHostPath so it inherits the same attributes\permissions.
47+
File.Copy(appHostSourceFilePath, appHostDestinationFilePath);
48+
49+
// Re-write ModifiedAppHostPath with the proper contents.
50+
using (FileStream fs = new FileStream(appHostDestinationFilePath, FileMode.Truncate, FileAccess.ReadWrite, FileShare.Read))
51+
{
52+
fs.Write(array, 0, array.Length);
53+
}
54+
}
55+
56+
// See: https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
57+
private static int[] ComputeKMPFailureFunction(byte[] pattern)
58+
{
59+
int[] table = new int[pattern.Length];
60+
if (pattern.Length >= 1)
61+
{
62+
table[0] = -1;
63+
}
64+
if (pattern.Length >= 2)
65+
{
66+
table[1] = 0;
67+
}
68+
69+
int pos = 2;
70+
int cnd = 0;
71+
while (pos < pattern.Length)
72+
{
73+
if (pattern[pos - 1] == pattern[cnd])
74+
{
75+
table[pos] = cnd + 1;
76+
cnd++;
77+
pos++;
78+
}
79+
else if (cnd > 0)
80+
{
81+
cnd = table[cnd];
82+
}
83+
else
84+
{
85+
table[pos] = 0;
86+
pos++;
87+
}
88+
}
89+
return table;
90+
}
91+
92+
// See: https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
93+
private static int KMPSearch(byte[] pattern, byte[] bytes)
94+
{
95+
int m = 0;
96+
int i = 0;
97+
int[] table = ComputeKMPFailureFunction(pattern);
98+
99+
while (m + i < bytes.Length)
100+
{
101+
if (pattern[i] == bytes[m + i])
102+
{
103+
if (i == pattern.Length - 1)
104+
{
105+
return m;
106+
}
107+
i++;
108+
}
109+
else
110+
{
111+
if (table[i] > -1)
112+
{
113+
m = m + i - table[i];
114+
i = table[i];
115+
}
116+
else
117+
{
118+
m++;
119+
i = 0;
120+
}
121+
}
122+
}
123+
return -1;
124+
}
125+
126+
private static void SearchAndReplace(byte[] array, byte[] searchPattern, byte[] patternToReplace, string appHostSourcePath)
127+
{
128+
int offset = KMPSearch(searchPattern, array);
129+
if (offset < 0)
130+
{
131+
throw new EmbedAppNameInHostException(string.Format(LocalizableStrings.EmbedAppNameInHostAppHostHasBeenModified, appHostSourcePath, _placeHolder));
132+
}
133+
134+
patternToReplace.CopyTo(array, offset);
135+
136+
if (patternToReplace.Length < searchPattern.Length)
137+
{
138+
for (int i = patternToReplace.Length; i < searchPattern.Length; i++)
139+
{
140+
array[i + offset] = 0x0;
141+
}
142+
}
143+
}
144+
}
145+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) .NET Foundation and contributors. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System;
5+
6+
namespace Microsoft.DotNet.Cli.Utils
7+
{
8+
public class EmbedAppNameInHostException : Exception
9+
{
10+
public EmbedAppNameInHostException()
11+
{
12+
}
13+
14+
public EmbedAppNameInHostException(string message) : base(message)
15+
{
16+
}
17+
18+
public EmbedAppNameInHostException(string message, Exception innerException) : base(message, innerException)
19+
{
20+
}
21+
}
22+
}

src/Microsoft.DotNet.Cli.Utils/LocalizableStrings.resx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,4 +265,10 @@
265265
<data name="MSBuildArgs" xml:space="preserve">
266266
<value>MSBuild arguments: {0}</value>
267267
</data>
268-
</root>
268+
<data name="EmbedAppNameInHostAppHostHasBeenModified" xml:space="preserve">
269+
<value>Unable to use '{0}' as application host executable as it does not contain the expected placeholder byte sequence '{1}' that would mark where the application name would be written.</value>
270+
</data>
271+
<data name="EmbedAppNameInHostFileNameIsTooLong" xml:space="preserve">
272+
<value>Given file name '{0}' is longer than 1024 bytes</value>
273+
</data>
274+
</root>

src/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.cs.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,16 @@
249249
<target state="new">MSBuild arguments: {0}</target>
250250
<note />
251251
</trans-unit>
252+
<trans-unit id="EmbedAppNameInHostAppHostHasBeenModified">
253+
<source>Unable to use '{0}' as application host executable as it does not contain the expected placeholder byte sequence '{1}' that would mark where the application name would be written.</source>
254+
<target state="new">Unable to use '{0}' as application host executable as it does not contain the expected placeholder byte sequence '{1}' that would mark where the application name would be written.</target>
255+
<note />
256+
</trans-unit>
257+
<trans-unit id="EmbedAppNameInHostFileNameIsTooLong">
258+
<source>Given file name '{0}' is longer than 1024 bytes</source>
259+
<target state="new">Given file name '{0}' is longer than 1024 bytes</target>
260+
<note />
261+
</trans-unit>
252262
</body>
253263
</file>
254264
</xliff>

src/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.de.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,16 @@
249249
<target state="new">MSBuild arguments: {0}</target>
250250
<note />
251251
</trans-unit>
252+
<trans-unit id="EmbedAppNameInHostAppHostHasBeenModified">
253+
<source>Unable to use '{0}' as application host executable as it does not contain the expected placeholder byte sequence '{1}' that would mark where the application name would be written.</source>
254+
<target state="new">Unable to use '{0}' as application host executable as it does not contain the expected placeholder byte sequence '{1}' that would mark where the application name would be written.</target>
255+
<note />
256+
</trans-unit>
257+
<trans-unit id="EmbedAppNameInHostFileNameIsTooLong">
258+
<source>Given file name '{0}' is longer than 1024 bytes</source>
259+
<target state="new">Given file name '{0}' is longer than 1024 bytes</target>
260+
<note />
261+
</trans-unit>
252262
</body>
253263
</file>
254264
</xliff>

src/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.es.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,16 @@
249249
<target state="new">MSBuild arguments: {0}</target>
250250
<note />
251251
</trans-unit>
252+
<trans-unit id="EmbedAppNameInHostAppHostHasBeenModified">
253+
<source>Unable to use '{0}' as application host executable as it does not contain the expected placeholder byte sequence '{1}' that would mark where the application name would be written.</source>
254+
<target state="new">Unable to use '{0}' as application host executable as it does not contain the expected placeholder byte sequence '{1}' that would mark where the application name would be written.</target>
255+
<note />
256+
</trans-unit>
257+
<trans-unit id="EmbedAppNameInHostFileNameIsTooLong">
258+
<source>Given file name '{0}' is longer than 1024 bytes</source>
259+
<target state="new">Given file name '{0}' is longer than 1024 bytes</target>
260+
<note />
261+
</trans-unit>
252262
</body>
253263
</file>
254264
</xliff>

src/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.fr.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,16 @@
249249
<target state="new">MSBuild arguments: {0}</target>
250250
<note />
251251
</trans-unit>
252+
<trans-unit id="EmbedAppNameInHostAppHostHasBeenModified">
253+
<source>Unable to use '{0}' as application host executable as it does not contain the expected placeholder byte sequence '{1}' that would mark where the application name would be written.</source>
254+
<target state="new">Unable to use '{0}' as application host executable as it does not contain the expected placeholder byte sequence '{1}' that would mark where the application name would be written.</target>
255+
<note />
256+
</trans-unit>
257+
<trans-unit id="EmbedAppNameInHostFileNameIsTooLong">
258+
<source>Given file name '{0}' is longer than 1024 bytes</source>
259+
<target state="new">Given file name '{0}' is longer than 1024 bytes</target>
260+
<note />
261+
</trans-unit>
252262
</body>
253263
</file>
254264
</xliff>

0 commit comments

Comments
 (0)