| File: CreateAppHost.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.NET.HostModel; using Microsoft.NET.HostModel.AppHost; namespace Microsoft.NET.Build.Tasks { /// <summary> /// Creates the runtime host to be used for an application. /// This embeds the application DLL path into the apphost and performs additional customizations as requested. /// </summary> [MSBuildMultiThreadableTask] public class CreateAppHost : TaskBase, IMultiThreadableTask { /// <summary> /// The number of additional retries to attempt for creating the apphost. /// <summary> /// <remarks> /// The default is no retries because internally the `HostWriter` attempts to retry /// on different I/O operations. Users can optionally retry at the task level if desired. /// </remarks> public const int DefaultRetries = 0; /// The default delay, in milliseconds, for each retry attempt for creating the apphost. /// </summary> public const int DefaultRetryDelayMilliseconds = 1000; [Required] public string AppHostSourcePath { get; set; } [Required] public string AppHostDestinationPath { get; set; } [Required] public string AppBinaryName { get; set; } [Required] public string IntermediateAssembly { get; set; } public bool WindowsGraphicalUserInterface { get; set; } public int Retries { get; set; } = DefaultRetries; public int RetryDelayMilliseconds { get; set; } = DefaultRetryDelayMilliseconds; public bool EnableMacOSCodeSign { get; set; } = false; public bool DisableCetCompat { get; set; } = false; public ITaskItem[] DotNetSearchLocations { get; set; } public string AppRelativeDotNet { get; set; } = null; public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback; protected override void ExecuteCore() { try { var isGUI = WindowsGraphicalUserInterface; AbsolutePath appHostSource = TaskEnvironment.GetAbsolutePath(AppHostSourcePath); AbsolutePath appHostDest = TaskEnvironment.GetAbsolutePath(AppHostDestinationPath); AbsolutePath resourcesAssembly = TaskEnvironment.GetAbsolutePath(IntermediateAssembly); int attempts = 0; while (true) { try { HostWriter.DotNetSearchOptions options = null; if (DotNetSearchLocations?.Length > 0) { HostWriter.DotNetSearchOptions.SearchLocation searchLocation = default; foreach (var locationItem in DotNetSearchLocations) { if (Enum.TryParse(locationItem.ItemSpec, out HostWriter.DotNetSearchOptions.SearchLocation location) && Enum.IsDefined(typeof(HostWriter.DotNetSearchOptions.SearchLocation), location)) { searchLocation |= location; } else { throw new BuildErrorException(Strings.InvalidAppHostDotNetSearch, locationItem.ItemSpec); } } options = new HostWriter.DotNetSearchOptions() { Location = searchLocation, AppRelativeDotNet = AppRelativeDotNet }; } HostWriter.CreateAppHost(appHostSourceFilePath: appHostSource, appHostDestinationFilePath: appHostDest, appBinaryFilePath: AppBinaryName, // Not absolutized — HostWriter embeds this as a relative path, never resolves it on disk windowsGraphicalUserInterface: isGUI, assemblyToCopyResourcesFrom: resourcesAssembly, enableMacOSCodeSign: EnableMacOSCodeSign, disableCetCompat: DisableCetCompat, dotNetSearchOptions: options); return; } catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException || (ex is AggregateException && (ex.InnerException is IOException || ex.InnerException is UnauthorizedAccessException))) { if (Retries < 0 || attempts == Retries) { throw; } ++attempts; string message = ex.Message; if (ex is AggregateException) { message = ex.InnerException.Message; } Log.LogWarning( string.Format(Strings.AppHostCreationFailedWithRetry, attempts, Retries + 1, message)); if (RetryDelayMilliseconds > 0) { Thread.Sleep(RetryDelayMilliseconds); } } } } catch (AppNameTooLongException ex) { throw new BuildErrorException(Strings.FileNameIsTooLong, ex.LongName); } catch (AppHostSigningException ex) { throw new BuildErrorException(Strings.AppHostSigningFailed, ex.Message, ex.ExitCode.ToString()); } catch (PlaceHolderNotFoundInAppHostException ex) { throw new BuildErrorException(Strings.AppHostHasBeenModified, AppHostSourcePath, BitConverter.ToString(ex.MissingPattern)); } } } }