<Output TaskParameter="TargetOutputs" ItemName="SharedFrameworkRuntimeFiles" />
</MSBuild>
+ <!--
+ Workaround: zero-versioned Microsoft.VisualBasic.dll in non-Windows CoreFX transport package.
+ See https://github.com/dotnet/corefx/issues/36630
+ -->
+ <PropertyGroup Condition="'$(OSGroup)' != 'Windows_NT'">
+ <PermitDllAndExeFilesLackingFileVersion>true</PermitDllAndExeFilesLackingFileVersion>
+ </PropertyGroup>
+
<GenerateFileVersionProps Files="@(SharedFrameworkRuntimeFiles)"
PackageId="$(Id)"
PackageVersion="$(Version)"
PlatformManifestFile="$(PlatformManifestFile)"
PropsFile="$(PropsFile)"
- PreferredPackages="$(Id);@(RuntimeDependency)" />
+ PreferredPackages="$(Id);@(RuntimeDependency)"
+ PermitDllAndExeFilesLackingFileVersion="$(PermitDllAndExeFilesLackingFileVersion)" />
</Target>
<Target Name="IncludeFileVersionPropsFile"
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
+using Microsoft.Build.Construction;
using Microsoft.Build.Framework;
-using System.IO;
+using System;
using System.Collections.Generic;
-using Microsoft.Build.Construction;
+using System.IO;
+using System.Linq;
namespace Microsoft.DotNet.Build.Tasks
{
public partial class GenerateFileVersionProps : BuildTask
{
- const string PlatformManifestsItem = "PackageConflictPlatformManifests";
- const string PreferredPackagesProperty = "PackageConflictPreferredPackages";
+ private const string PlatformManifestsItem = "PackageConflictPlatformManifests";
+ private const string PreferredPackagesProperty = "PackageConflictPreferredPackages";
+ private static readonly Version ZeroVersion = new Version(0, 0, 0, 0);
+
[Required]
public ITaskItem[] Files { get; set; }
[Required]
public string PreferredPackages { get; set; }
+ /// <summary>
+ /// The task normally enforces that all DLL and EXE files have a non-0.0.0.0 FileVersion.
+ /// This flag disables the check.
+ /// </summary>
+ public bool PermitDllAndExeFilesLackingFileVersion { get; set; }
+
public override bool Execute()
{
var fileVersions = new Dictionary<string, FileVersionData>(StringComparer.OrdinalIgnoreCase);
}
}
+ // Check for versionless files after all duplicate filenames are resolved, rather than
+ // logging errors immediately upon encountering a versionless file. There may be
+ // duplicate filenames where only one has a version, and this is ok. The highest version
+ // is used.
+ if (!PermitDllAndExeFilesLackingFileVersion)
+ {
+ var versionlessFiles = fileVersions
+ .Where(p =>
+ p.Key.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) ||
+ p.Key.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
+ .Where(p => (p.Value.FileVersion ?? ZeroVersion) == ZeroVersion)
+ .Select(p => p.Value.File.ItemSpec)
+ .ToArray();
+
+ if (versionlessFiles.Any())
+ {
+ Log.LogError(
+ $"Missing FileVersion in {versionlessFiles.Length} shared framework files:" +
+ string.Concat(versionlessFiles.Select(f => Environment.NewLine + f)));
+ }
+ }
+
var props = ProjectRootElement.Create();
var itemGroup = props.AddItemGroup();
// set the platform manifest when the platform is not being published as part of the app
return new FileVersionData()
{
AssemblyVersion = FileUtilities.GetAssemblyName(filePath)?.Version,
- FileVersion = FileUtilities.GetFileVersion(filePath)
+ FileVersion = FileUtilities.GetFileVersion(filePath),
+ File = file
};
}
else
{
// FileVersionInfo will return 0.0.0.0 if a file doesn't have a version.
// match that behavior
- fileVersion = new Version(0, 0, 0, 0);
+ fileVersion = ZeroVersion;
}
return new FileVersionData()
{
AssemblyVersion = assemblyVersion,
- FileVersion = fileVersion
+ FileVersion = fileVersion,
+ File = file
};
}
}
{
public Version AssemblyVersion { get; set; }
public Version FileVersion { get; set; }
+ public ITaskItem File { get; set; }
}
}
}