| File: GenerateShims.cs | Web Access |
| Project: src\sdk\src\Tasks\Microsoft.NET.Build.Tasks\Microsoft.NET.Build.Tasks.csproj (Microsoft.NET.Build.Tasks) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #nullable disable using Microsoft.Build.Framework; using Microsoft.Build.Utilities; using Microsoft.NET.HostModel.AppHost; using NuGet.Versioning; namespace Microsoft.NET.Build.Tasks { public sealed class GenerateShims : TaskBase { /// <summary> /// Relative paths for Apphost for different ShimRuntimeIdentifiers with RuntimeIdentifier as meta data /// </summary> [Required] public ITaskItem[] ApphostsForShimRuntimeIdentifiers { get; private set; } [Required] public string IntermediateAssembly { get; set; } public string OutputType { get; set; } /// <summary> /// PackageId of the dotnet tool NuGet Package. /// </summary> [Required] public string PackageId { get; set; } /// <summary> /// Package Version of the dotnet tool NuGet Package. /// </summary> [Required] public string PackageVersion { get; set; } /// <summary> /// TFM to use for compile-time assets. /// </summary> [Required] public string TargetFrameworkMoniker { get; set; } /// <summary> /// The command name of the dotnet tool. /// </summary> [Required] public string ToolCommandName { get; set; } /// <summary> /// The entry point of the dotnet tool which will be run by Apphost /// </summary> [Required] public string ToolEntryPoint { get; set; } /// <summary> /// The output directory path of generated shims. /// </summary> [Required] public string PackagedShimOutputDirectory { get; set; } /// <summary> /// The RuntimeIdentifiers that shims will be generated for. /// </summary> [Required] public ITaskItem[] ShimRuntimeIdentifiers { get; set; } /// <summary> /// Path of generated shims. metadata "ShimRuntimeIdentifier" is used to map back to input ShimRuntimeIdentifiers. /// </summary> [Output] public ITaskItem[] EmbeddedApphostPaths { get; private set; } private const ushort WindowsGUISubsystem = 0x2; protected override void ExecuteCore() { var embeddedApphostPaths = new List<ITaskItem>(); foreach (var runtimeIdentifier in ShimRuntimeIdentifiers.Select(r => r.ItemSpec)) { var resolvedApphostAssetPath = GetApphostAsset(ApphostsForShimRuntimeIdentifiers, runtimeIdentifier); var packagedShimOutputDirectoryAndRid = Path.Combine( PackagedShimOutputDirectory, runtimeIdentifier); var appHostDestinationFilePath = Path.Combine( packagedShimOutputDirectoryAndRid, ToolCommandName + ExecutableExtension.ForRuntimeIdentifier(runtimeIdentifier)); Directory.CreateDirectory(packagedShimOutputDirectoryAndRid); // per https://github.com/dotnet/cli/issues/9870 nuget layout (as in {packageid}/{packageversion}/tools/)is normalized version var normalizedPackageVersion = NuGetVersion.Parse(PackageVersion).ToNormalizedString(); // This is the embedded string. We should normalize it on forward slash, so the file won't be different according to // build machine. var appBinaryFilePath = string.Join("/", new[] { ".store", PackageId.ToLowerInvariant(), normalizedPackageVersion, PackageId.ToLowerInvariant(), normalizedPackageVersion, "tools", NuGetUtils.ParseFrameworkName(TargetFrameworkMoniker).GetShortFolderName(), "any", ToolEntryPoint}); try { var windowsGraphicalUserInterface = runtimeIdentifier.StartsWith("win") && "WinExe".Equals(OutputType, StringComparison.OrdinalIgnoreCase); if (runtimeIdentifier.StartsWith("win")) { HostWriter.CreateAppHost(appHostSourceFilePath: resolvedApphostAssetPath, appHostDestinationFilePath: appHostDestinationFilePath, appBinaryFilePath: appBinaryFilePath, windowsGraphicalUserInterface: windowsGraphicalUserInterface, assemblyToCopyResourcesFrom: IntermediateAssembly); } else { // by passing null to assemblyToCopyResourcesFrom, it will skip copying resources, // which is only supported on Windows if (windowsGraphicalUserInterface) { Log.LogWarning(Strings.AppHostCustomizationRequiresWindowsHostWarning); } HostWriter.CreateAppHost(appHostSourceFilePath: resolvedApphostAssetPath, appHostDestinationFilePath: appHostDestinationFilePath, appBinaryFilePath: appBinaryFilePath, windowsGraphicalUserInterface: false, assemblyToCopyResourcesFrom: null); } } catch (AppNameTooLongException ex) { throw new BuildErrorException(Strings.FileNameIsTooLong, ex.LongName); } catch (PlaceHolderNotFoundInAppHostException ex) { throw new BuildErrorException(Strings.AppHostHasBeenModified, resolvedApphostAssetPath, BitConverter.ToString(ex.MissingPattern)); } var item = new TaskItem(appHostDestinationFilePath); item.SetMetadata(MetadataKeys.ShimRuntimeIdentifier, runtimeIdentifier); embeddedApphostPaths.Add(item); } EmbeddedApphostPaths = embeddedApphostPaths.ToArray(); } private string GetApphostAsset(ITaskItem[] apphostsForShimRuntimeIdentifiers, string runtimeIdentifier) { return apphostsForShimRuntimeIdentifiers.Single(i => i.GetMetadata(MetadataKeys.RuntimeIdentifier) == runtimeIdentifier).ItemSpec; } } }