/// <summary> /// Create an ComHost with an embedded CLSIDMap file to map CLSIDs to .NET Classes. /// </summary> /// <param name="comHostSourceFilePath">The path of Apphost template, which has the place holder</param> /// <param name="comHostDestinationFilePath">The destination path for desired location to place, including the file name</param> /// <param name="intermediateAssembly">Path to the intermediate assembly, used for copying resources to PE apphosts.</param> /// <param name="clsidmap">The path to the *.clsidmap file.</param> /// <param name="log">Specify the logger used to log warnings and messages. If null, no logging is done.</param> public static void Create( string comHostSourceFilePath, string comHostDestinationFilePath, string clsidmapFilePath) { var destinationDirectory = new FileInfo(comHostDestinationFilePath).Directory.FullName; if (!Directory.Exists(destinationDirectory)) { Directory.CreateDirectory(destinationDirectory); } // Copy apphost to destination path so it inherits the same attributes/permissions. File.Copy(comHostSourceFilePath, comHostDestinationFilePath, overwrite: true); if (ResourceUpdater.IsSupportedOS()) { string clsidMap = File.ReadAllText(clsidmapFilePath); byte[] clsidMapBytes = Encoding.UTF8.GetBytes(clsidMap); ResourceUpdater updater = new ResourceUpdater(comHostDestinationFilePath); updater.AddResource(clsidMapBytes, (IntPtr)ClsidmapResourceType, (IntPtr)ClsidmapResourceId); updater.Update(); } else { throw new BuildErrorException(Strings.CannotEmbedClsidMapIntoComhost); } }
protected override void ExecuteCore() { try { if (ResourceUpdater.IsSupportedOS()) { HostWriter.CreateAppHost(appHostSourceFilePath: AppHostSourcePath, appHostDestinationFilePath: AppHostDestinationPath, appBinaryFilePath: AppBinaryName, windowsGraphicalUserInterface: WindowsGraphicalUserInterface, assemblyToCopyResorcesFrom: IntermediateAssembly); } else { // by passing null to assemblyToCopyResorcesFrom, it will skip copying resorces, // which is only supported on Windows if (WindowsGraphicalUserInterface) { Log.LogWarning(Strings.AppHostCustomizationRequiresWindowsHostWarning); } HostWriter.CreateAppHost(appHostSourceFilePath: AppHostSourcePath, appHostDestinationFilePath: AppHostDestinationPath, appBinaryFilePath: AppBinaryName, windowsGraphicalUserInterface: false, assemblyToCopyResorcesFrom: null); } } catch (AppNameTooLongException ex) { throw new BuildErrorException(Strings.FileNameIsTooLong, ex.LongName); } catch (PlaceHolderNotFoundInAppHostException ex) { throw new BuildErrorException(Strings.AppHostHasBeenModified, AppHostSourcePath, BitConverter.ToString(ex.MissingPattern)); } }
protected override void ExecuteCore() { try { var isGUI = WindowsGraphicalUserInterface; var resourcesAssembly = IntermediateAssembly; if (!ResourceUpdater.IsSupportedOS()) { if (isGUI) { Log.LogWarning(Strings.AppHostCustomizationRequiresWindowsHostWarning); } isGUI = false; resourcesAssembly = null; } int attempts = 0; while (true) { try { HostWriter.CreateAppHost(appHostSourceFilePath: AppHostSourcePath, appHostDestinationFilePath: AppHostDestinationPath, appBinaryFilePath: AppBinaryName, windowsGraphicalUserInterface: isGUI, assemblyToCopyResorcesFrom: resourcesAssembly); return; } catch (Exception ex) when(ex is IOException || ex is UnauthorizedAccessException || ex is HResultException || (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 (PlaceHolderNotFoundInAppHostException ex) { throw new BuildErrorException(Strings.AppHostHasBeenModified, AppHostSourcePath, BitConverter.ToString(ex.MissingPattern)); } }
/// <summary> /// Create an AppHost with embedded configuration of app binary location /// </summary> /// <param name="appHostSourceFilePath">The path of Apphost template, which has the place holder</param> /// <param name="appHostDestinationFilePath">The destination path for desired location to place, including the file name</param> /// <param name="appBinaryFilePath">Full path to app binary or relative path to the result apphost file</param> /// <param name="windowsGraphicalUserInterface">Specify whether to set the subsystem to GUI. Only valid for PE apphosts.</param> /// <param name="intermediateAssembly">Path to the intermediate assembly, used for copying resources to PE apphosts.</param> /// <param name="log">Specify the logger used to log warnings and messages. If null, no logging is done.</param> public static void Create( string appHostSourceFilePath, string appHostDestinationFilePath, string appBinaryFilePath, bool windowsGraphicalUserInterface = false, string intermediateAssembly = null, Logger log = null) { var bytesToWrite = Encoding.UTF8.GetBytes(appBinaryFilePath); if (bytesToWrite.Length > 1024) { throw new BuildErrorException(Strings.FileNameIsTooLong, appBinaryFilePath); } var destinationDirectory = new FileInfo(appHostDestinationFilePath).Directory.FullName; if (!Directory.Exists(destinationDirectory)) { Directory.CreateDirectory(destinationDirectory); } // Copy apphost to destination path so it inherits the same attributes/permissions. File.Copy(appHostSourceFilePath, appHostDestinationFilePath, overwrite: true); // Re-write the destination apphost with the proper contents. bool appHostIsPEImage = false; using (var memoryMappedFile = MemoryMappedFile.CreateFromFile(appHostDestinationFilePath)) { using (MemoryMappedViewAccessor accessor = memoryMappedFile.CreateViewAccessor()) { SearchAndReplace(accessor, AppBinaryPathPlaceholderSearchValue, bytesToWrite, appHostSourceFilePath); appHostIsPEImage = IsPEImage(accessor); if (windowsGraphicalUserInterface) { if (!appHostIsPEImage) { throw new BuildErrorException(Strings.AppHostNotWindows, appHostSourceFilePath); } SetWindowsGraphicalUserInterfaceBit(accessor, appHostSourceFilePath); } } } if (intermediateAssembly != null && appHostIsPEImage) { if (ResourceUpdater.IsSupportedOS()) { // Copy resources from managed dll to the apphost new ResourceUpdater(appHostDestinationFilePath) .AddResourcesFromPEImage(intermediateAssembly) .Update(); } else if (log != null) { log.LogWarning(Strings.AppHostCustomizationRequiresWindowsHostWarning); } } // Memory-mapped write does not updating last write time File.SetLastWriteTimeUtc(appHostDestinationFilePath, DateTime.UtcNow); }
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 (ResourceUpdater.IsSupportedOS() && runtimeIdentifier.StartsWith("win")) { HostWriter.CreateAppHost(appHostSourceFilePath: resolvedApphostAssetPath, appHostDestinationFilePath: appHostDestinationFilePath, appBinaryFilePath: appBinaryFilePath, windowsGraphicalUserInterface: windowsGraphicalUserInterface, assemblyToCopyResorcesFrom: IntermediateAssembly); } else { // by passing null to assemblyToCopyResorcesFrom, 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, assemblyToCopyResorcesFrom: 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(); }