diff --git a/eng/Versions.props b/eng/Versions.props
index c50c3a78819f39..80936c71feea63 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -97,6 +97,7 @@
7.0.0
8.0.0
+ 6.0.1
4.5.1
8.0.0
4.5.5
diff --git a/src/installer/managed/Microsoft.NET.HostModel/AppHost/HostWriter.cs b/src/installer/managed/Microsoft.NET.HostModel/AppHost/HostWriter.cs
index 47f64f4669c60c..777fab812578b0 100644
--- a/src/installer/managed/Microsoft.NET.HostModel/AppHost/HostWriter.cs
+++ b/src/installer/managed/Microsoft.NET.HostModel/AppHost/HostWriter.cs
@@ -124,7 +124,7 @@ void RewriteAppHost(MemoryMappedFile mappedFile, MemoryMappedViewAccessor access
if (File.Exists(appHostDestinationFilePath))
File.Delete(appHostDestinationFilePath);
- long appHostSourceLength = new FileInfo(appHostSourceFilePath).Length;
+ long appHostSourceLength = HostModelUtils.GetFileLength(appHostSourceFilePath);
string destinationFileName = Path.GetFileName(appHostDestinationFilePath);
// Memory-mapped files cannot be resized, so calculate
// the maximum length of the destination file upfront.
diff --git a/src/installer/managed/Microsoft.NET.HostModel/Bundle/Bundler.cs b/src/installer/managed/Microsoft.NET.HostModel/Bundle/Bundler.cs
index a5e8b593484198..c0ab083017a8d2 100644
--- a/src/installer/managed/Microsoft.NET.HostModel/Bundle/Bundler.cs
+++ b/src/installer/managed/Microsoft.NET.HostModel/Bundle/Bundler.cs
@@ -293,7 +293,7 @@ public string GenerateBundle(IReadOnlyList fileSpecs)
// We will memory map a larger file than needed, but we'll take that trade-off.
foreach (var (spec, type) in relativePathToSpec)
{
- bundledFilesSize += new FileInfo(spec.SourcePath).Length;
+ bundledFilesSize += HostModelUtils.GetFileLength(spec.SourcePath);
if (type == FileType.Assembly)
{
// Alignment could be as much as AssemblyAlignment - 1 bytes.
@@ -314,7 +314,7 @@ public string GenerateBundle(IReadOnlyList fileSpecs)
{
Directory.CreateDirectory(destinationDirectory);
}
- var hostLength = new FileInfo(hostSource).Length;
+ var hostLength = HostModelUtils.GetFileLength(hostSource);
var bundleManifestLength = Manifest.GetManifestLength(BundleManifest.BundleMajorVersion, relativePathToSpec.Select(x => x.Spec.BundleRelativePath));
long bundleTotalSize = hostLength + bundledFilesSize + bundleManifestLength;
if (_target.IsOSX && _macosCodesign)
diff --git a/src/installer/managed/Microsoft.NET.HostModel/HostModelUtils.cs b/src/installer/managed/Microsoft.NET.HostModel/HostModelUtils.cs
index 85724bef64c026..8fcb58da9b899a 100644
--- a/src/installer/managed/Microsoft.NET.HostModel/HostModelUtils.cs
+++ b/src/installer/managed/Microsoft.NET.HostModel/HostModelUtils.cs
@@ -2,9 +2,14 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
+#if NETFRAMEWORK
+using Microsoft.IO;
+#else
using System.IO;
+#endif
using System.Runtime.InteropServices;
+
namespace Microsoft.NET.HostModel
{
internal static class HostModelUtils
@@ -32,5 +37,11 @@ public static (int ExitCode, string StdErr) RunCodesign(string args, string appH
return (p.ExitCode, p.StandardError.ReadToEnd());
}
}
+
+ public static long GetFileLength(string path)
+ {
+ var info = new FileInfo(path);
+ return ((FileInfo)info.ResolveLinkTarget(true) ?? info).Length;
+ }
}
}
diff --git a/src/installer/managed/Microsoft.NET.HostModel/Microsoft.NET.HostModel.csproj b/src/installer/managed/Microsoft.NET.HostModel/Microsoft.NET.HostModel.csproj
index 92a763f7032414..af27dd32dcc9a8 100644
--- a/src/installer/managed/Microsoft.NET.HostModel/Microsoft.NET.HostModel.csproj
+++ b/src/installer/managed/Microsoft.NET.HostModel/Microsoft.NET.HostModel.csproj
@@ -24,6 +24,7 @@
+
diff --git a/src/installer/tests/Microsoft.NET.HostModel.Tests/Bundle/BundlerConsistencyTests.cs b/src/installer/tests/Microsoft.NET.HostModel.Tests/Bundle/BundlerConsistencyTests.cs
index 44cfdfd95358cf..fe6e122d46b68c 100644
--- a/src/installer/tests/Microsoft.NET.HostModel.Tests/Bundle/BundlerConsistencyTests.cs
+++ b/src/installer/tests/Microsoft.NET.HostModel.Tests/Bundle/BundlerConsistencyTests.cs
@@ -98,6 +98,24 @@ public void ExactDuplicateEntries()
bundler.BundleManifest.Files.Where(entry => entry.RelativePath.Equals("rel/system.repeat.dll")).Single().Type.Should().Be(FileType.Assembly);
}
+ [Fact]
+ public void ResolveLinkTargets()
+ {
+ string appPath = Path.Combine(
+ Path.GetDirectoryName(sharedTestState.App.AppDll),
+ Path.GetFileNameWithoutExtension(sharedTestState.App.AppDll)
+ + ".link" + Path.GetExtension(sharedTestState.App.AppDll));
+ File.CreateSymbolicLink(appPath, sharedTestState.App.AppDll);
+ // File specification with duplicate entries with matching source paths
+ var fileSpecs = new FileSpec[]
+ {
+ new FileSpec(Binaries.AppHost.FilePath, BundlerHostName),
+ new FileSpec(appPath, "rel/app.repeat.dll")
+ };
+ Bundler bundler = CreateBundlerInstance();
+ bundler.GenerateBundle(fileSpecs);
+ }
+
[Fact]
public void DuplicateBundleRelativePath_Fails()
{