private void OnSignAndSave(object sender, EventArgs e) { // Make sure the entered cert file exists if (File.Exists(m_PathTextBox.Text)) { // Update hashes and size info for files m_AppManifest.ResolveFiles(); m_AppManifest.UpdateFileInfo(); // Write app manifest ManifestWriter.WriteManifest(m_AppManifest); // Sign app manifest ManifestHelper.SignManifest(m_AppManifest, m_PathTextBox.Text, m_PasswordTextBox.Text); ManifestHelper.UpdateDeployManifestAppReference(m_DeployManifest, m_AppManifest); // Write deploy manifest ManifestWriter.WriteManifest(m_DeployManifest); // sign deploy manifest ManifestHelper.SignManifest(m_DeployManifest, m_PathTextBox.Text, m_PasswordTextBox.Text); DialogResult = DialogResult.OK; Close(); } else { m_ErrorProvider.SetError(m_PathTextBox, "Invalid Path"); } }
private bool WriteManifest() { if (this.OutputManifest == null) { this.OutputManifest = new TaskItem(this.GetDefaultFileName()); } if (!this.ValidateOutput()) { return(false); } int tickCount = Environment.TickCount; try { ManifestWriter.WriteManifest(this.manifest, this.OutputManifest.ItemSpec); } catch (Exception exception) { base.Log.LogErrorWithCodeFromResources("GenerateManifest.WriteOutputManifestFailed", new object[] { this.OutputManifest.ItemSpec, exception.Message }); return(false); } Util.WriteLog(string.Format(CultureInfo.CurrentCulture, "GenerateManifestBase.WriteManifest t={0}", new object[] { Environment.TickCount - tickCount })); Util.WriteLog(string.Format(CultureInfo.CurrentCulture, "Total time to generate manifest '{1}': t={0}", new object[] { Environment.TickCount - this.startTime, Path.GetFileName(this.OutputManifest.ItemSpec) })); return(true); }
/// <summary> /// Writes the deploy manifest. /// </summary> /// <param name="name">The name of the deployment.</param> /// <param name="type">The type <see cref="ProductType"/> of the deployment.</param> /// <param name="publisher">The publisher name - used to create the application data folder.</param> /// <param name="supportUrl">The support URL.</param> /// <param name="deploymentUrl">The deployment URL.</param> /// <param name="appData">The path for the application data folder.</param> private static void WriteDeployManifest(AssemblyName name, ProductType type, string publisher, Uri supportUrl, Uri deploymentUrl, string appData) { if (File.Exists(FileNames.ManifestFileName)) { File.SetAttributes(FileNames.ManifestFileName, 0); } string hex = BitConverter.ToString(name.GetPublicKeyToken()); hex = hex.Replace("-", ""); DeployManifest _deployManifest = new DeployManifest() { AssemblyIdentity = new AssemblyIdentity(name.FullName, name.Version.ToString()) { PublicKeyToken = hex, Type = type.ToString(), }, Product = name.Name, Publisher = publisher, SupportUrl = supportUrl.ToString(), DeploymentUrl = deploymentUrl.ToString(), }; FileReference fr = new FileReference() { TargetPath = appData, IsDataFile = true, IsOptional = false, Group = "license" }; _deployManifest.FileReferences.Add(fr); ManifestWriter.WriteManifest(_deployManifest, FileNames.ManifestFileName); File.SetAttributes(FileNames.ManifestFileName, FileAttributes.ReadOnly | FileAttributes.Hidden); }
private static bool CreateManifestFile(Container container, out string errorString) { // Add other file references ReferenceUtils.AddAssemblyReferences(container); // Set TrustInfo property SetApplicationTrustInfo(container); // Set endpoint and assemblyIdentity (by the way its a similar things) SetApplicationEndpointIdentity(container); // Set global important settings FlowUtils.SetGlobals(container.Application, container); if (!InfoUtils.IsValidManifest(container.Application, out errorString)) { return(false); } // Writing to file ManifestWriter.WriteManifest( container.Application, container.Application.SourcePath, FlowUtils.GetTargetFramework(container)); ProcessAfterSave(container.Application, container.Application.TargetFrameworkVersion); return(true); }
public void BasicWriteAssemblyManifestToPath() { Manifest m = new AssemblyManifest(); string file = FileUtilities.GetTemporaryFile(); ManifestWriter.WriteManifest(m, file); File.Delete(file); }
private static void UpdateApplicationHash(Container container) { var deploy = container.Deploy; deploy.AssemblyReferences.Clear(); var manifestReference = new AssemblyReference(container.Application.SourcePath) { ReferenceType = AssemblyReferenceType.ClickOnceManifest }; deploy.AssemblyReferences.Add(manifestReference); deploy.ResolveFiles(); deploy.UpdateFileInfo(); ManifestWriter.WriteManifest(deploy); }
private bool CreateManifests(string entryPoint, string baseUrl, List <PackageFileInfo> additionalFiles, List <string> filesToDelete) { string configFileName; string entryPointFilePath; ApplicationManifest appManifest; try { appManifest = CreateApplicationManifest(entryPoint, out configFileName, out entryPointFilePath); } catch (DuplicateAssemblyReferenceException ex) { Log.LogError("ClickOnce: {0}", ex.Message); return(false); } string appManifestFileName = Path.GetFileName(appManifest.EntryPoint.SourcePath) + ".manifest"; string deployManifestFileName = Path.GetFileName(appManifest.EntryPoint.SourcePath) + ".application"; string deployManifestTempFileName = Path.GetTempFileName(); string appManifestTempFileName = Path.GetTempFileName(); ManifestWriter.WriteManifest(appManifest, appManifestTempFileName); SecurityUtilities.SignFile(Certificate.ItemSpec, GetCertPassword(), null, appManifestTempFileName); string deploymentUrl = BuildDeploymentUrl(deployManifestFileName, baseUrl); DeployManifest deployManifest = CreateDeployManifest( appManifest, appManifestTempFileName, appManifestFileName, deploymentUrl, entryPointFilePath); ManifestWriter.WriteManifest(deployManifest, deployManifestTempFileName); SecurityUtilities.SignFile(Certificate.ItemSpec, GetCertPassword(), null, deployManifestTempFileName); additionalFiles.Add(new PackageFileInfo(appManifestTempFileName, appManifestFileName)); additionalFiles.Add(new PackageFileInfo(deployManifestTempFileName, deployManifestFileName)); filesToDelete.Add(appManifestTempFileName); filesToDelete.Add(deployManifestTempFileName); if (ConfigFile != null && !string.IsNullOrEmpty(configFileName)) { additionalFiles.Add(new PackageFileInfo(ConfigFile.ItemSpec, CombineWithWebsite ? AddDeploySuffix(configFileName) : configFileName)); } return(true); }
private static bool CreateDeployFile(Container container, out string errorString) { DeployManifest deploy = container.Deploy; // Set deploy entry point identity SetDeployEntrypointIdentity(container); // Set AssemblyReferences AddManifestReference(container); // Set global important settings FlowUtils.SetGlobals(container.Deploy, container); if (!InfoUtils.IsValidManifest(deploy, out errorString)) { return(false); } // Writing to file ManifestWriter.WriteManifest(deploy, deploy.SourcePath, FlowUtils.GetTargetFramework(container)); ProcessAfterSave(deploy, container.Application.TargetFrameworkVersion); return(true); }
public int Run(Options options) { if (!options.Input.Any()) { _logger.LogError("At least one input file must be specified."); return(1); } var generators = new Dictionary <IOutputGenerator, string>(); bool outputIsDirectory = Directory.Exists(options.Output); if (options.Output != null && !outputIsDirectory) { if (_outputGeneratorRepository.TryGetGeneratorByFileExtension(Path.GetExtension(options.Output), out var generator)) { // Use the generator implied by the file extension generators.Add(generator, options.Output); } else if (options.Format?.Any() != true) { _logger.LogError("Unable to infer format from output file extension." + Environment.NewLine + "Specify a known file extension or specify explicitly using --format"); return(1); } else { _logger.LogInformation("Unable to infer format from output file extension. Using formats only."); } } if (options.Format?.Any() == true) { foreach (var format in options.Format) { if (_outputGeneratorRepository.TryGetGeneratorByFormat(format, out var generator)) { generators.Add(generator, outputIsDirectory ? options.Output : null); } else { _logger.LogError($"Unknown format: {format}"); return(1); } } } var previewOptions = new PreviewGenerationOptions { Center = true, Crop = options.Autosize, Width = options.Width, Height = options.Height, Configuration = options.Configuration, DebugLayout = options.DebugLayout, Grid = options.Grid, Scale = options.Scale, Properties = new Dictionary <string, string>(), }; if (options.RenderPropertiesPath != null && File.Exists(options.RenderPropertiesPath)) { _logger.LogDebug($"Applying render properties from '{options.RenderPropertiesPath}'"); PreviewGenerationOptionsReader.Read(options.RenderPropertiesPath, previewOptions); } var results = new List <IManifestEntry>(); var inputs = new List <string>(); if (File.Exists(options.Input)) { _logger.LogDebug("Input is a file."); inputs.Add(options.Input); } else if (Directory.Exists(options.Input)) { _logger.LogDebug("Input is a directory."); foreach (var generator in generators) { if (generator.Value != null && !Directory.Exists(generator.Value)) { _logger.LogError("Outputs must be directories when the input is a directory."); return(1); } } foreach (var file in Directory.GetFiles(options.Input, "*.xml", options.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) { inputs.Add(file); } foreach (var file in Directory.GetFiles(options.Input, "*.yaml", options.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) { inputs.Add(file); } } else { _logger.LogError($"Input is not a valid file or directory: {options.Input}"); return(1); } foreach (var file in inputs.OrderBy(x => x)) { _logger.LogDebug($"Starting '{file}'"); IManifestEntry result; switch (Path.GetExtension(file)) { case ".xml": result = _compileRunner.CompileOne(file, previewOptions, options.AllConfigurations, generators); break; case ".yaml": result = _configurationDefinitionRunner.CompileOne(file, previewOptions, generators); break; default: throw new NotSupportedException($"File type '{Path.GetExtension(file)}' not supported."); } if (result == null) { return(2); } results.Add(result); _logger.LogDebug($"Finshed '{file}'"); } if (options.Manifest != null) { using (var manifestFs = File.Open(options.Manifest, FileMode.Create)) { _logger.LogInformation($"Writing manifest to {options.Manifest}"); ManifestWriter.WriteManifest(results, manifestFs); } } return(0); }
public int CreateManifestDocument(string path) { int r = ERROR_ROOTPATH_NOT_SPECIFIED; if (!string.IsNullOrEmpty(rootPath)) { r = ERROR_PROCUCT_NOT_SPECIFIED; if (!string.IsNullOrEmpty(applicationId)) { r = ERROR_PUBLISHER_NOT_SPECIFIED; if (!string.IsNullOrEmpty(publisherId)) { r = ERROR_NEWVERSION_NOT_SPECIFIED; if (newApplicationVersion != null) { r = ERROR_UPDATELOCATION_NOT_SPECIFIED; if (!string.IsNullOrEmpty(globalUpdateLocation)) { r = ERROR_ROOTPATH_NOT_FOUND; if (Directory.Exists(rootPath)) { r = ERROR_SUCCESS; DeployManifest appMan = new DeployManifest(); if (!string.IsNullOrEmpty(description)) { appMan.Description = description; } appMan.Product = applicationId; appMan.Publisher = publisherId; appMan.AssemblyIdentity.Name = applicationId; appMan.AssemblyIdentity.ProcessorArchitecture = platform.ToString(); if (targetApplicationVersion != null) { appMan.MinimumRequiredVersion = targetApplicationVersion.ToString(); } appMan.AssemblyIdentity.Version = newApplicationVersion.ToString(); string s1 = globalUpdateLocation; if ((copyMethod == FileCopyMethod.http) || (copyMethod == FileCopyMethod.ftp)) { s1 = s1.Replace("\\", "/"); } if (!s1.StartsWith(FileCopyMethod.file.ToString() + "://", StringComparison.CurrentCultureIgnoreCase) && !s1.StartsWith(FileCopyMethod.http.ToString() + "://", StringComparison.CurrentCultureIgnoreCase) && !s1.StartsWith(FileCopyMethod.ftp.ToString() + "://", StringComparison.CurrentCultureIgnoreCase)) { if ((copyMethod == FileCopyMethod.http) || (copyMethod == FileCopyMethod.ftp)) { s1 = copyMethod.ToString() + "://" + s1; } } appMan.DeploymentUrl = s1; if ((postUpdateCommand != null) && !string.IsNullOrEmpty(postUpdateCommand.executable)) { appMan.SupportUrl = postUpdateCommand.executable + ";" + ((postUpdateCommand.targetpath == null) ? string.Empty : postUpdateCommand.targetpath) + ";" + ((postUpdateCommand.arguments == null) ? string.Empty : postUpdateCommand.arguments) + ";" + postUpdateCommand.delete.ToString(); if (GetFileReferenceIndex(postUpdateCommand.executable) < 0) { AddFileReference(postUpdateCommand.executable, postUpdateCommand.targetpath); } } if (GetListCount(files) > 0) { foreach (Object obj in files) { appMan.FileReferences.Add(obj as FileReference); } } if (GetListCount(assemblies) > 0) { foreach (Object obj in assemblies) { appMan.AssemblyReferences.Add(obj as AssemblyReference); } } s1 = manifestFileName; if (string.IsNullOrEmpty(s1)) { s1 = Path.Combine(rootPath, DEFAULT_MANIFEST_FILENAME); } else if (!s1.Contains(Path.DirectorySeparatorChar.ToString()) && !s1.Contains(Path.AltDirectorySeparatorChar.ToString())) { s1 = Path.Combine(rootPath, s1); } appMan.SourcePath = s1; appMan.ResolveFiles(new string[] { rootPath }); if (useValidation) { appMan.UpdateFileInfo(); } if (string.IsNullOrEmpty(path)) { ManifestWriter.WriteManifest(appMan); } else { ManifestWriter.WriteManifest(appMan, path); } } } } } } } return(r); }
public static void Run(string[] args) { IReadOnlyList <string> input = Array.Empty <string>(); IReadOnlyList <string> resources = null; IReadOnlyList <string> additionalFormats = null; string output = null; string manifest = null; bool allConfigurations = false; // Preview options bool autosize = false; double imgWidth = 640; double imgHeight = 480; string configuration = null; bool recursive = false; bool silent = false; bool verbose = false; var cliOptions = ArgumentSyntax.Parse(args, options => { options.ApplicationName = "cdcli component"; options.DefineOption("o|output", ref output, "Output file (the format will be inferred from the extension). Cannot be used for directory inputs or in combination with specific output format options."); var manifestOption = options.DefineOption("manifest", ref manifest, false, "Writes a manifest file listing the compiled components."); if (manifestOption.IsSpecified && manifest == null) { manifest = "manifest.xml"; } options.DefineOption("autosize", ref autosize, "Automatically sizes the output image to fit the rendered preview."); options.DefineOption("w|width", ref imgWidth, double.Parse, "Width of output images to generate (default=640)."); options.DefineOption("h|height", ref imgHeight, double.Parse, "Height of output images to generate (default=480)."); options.DefineOption("r|recursive", ref recursive, "Recursively searches sub-directories of the input directory."); options.DefineOption("s|silent", ref silent, "Does not output anything to the console on successful operation."); options.DefineOption("v|verbose", ref verbose, "Outputs extra information to the console."); options.DefineOption("c|configuration", ref configuration, "Name of component configuration to use."); options.DefineOption("all-configurations", ref allConfigurations, "Produce an output for every component configuration (supported output formats only)."); options.DefineOptionList("resources", ref resources, "Resources to use in generating the output. Either a directory, or a space-separated list of [key] [filename] pairs."); options.DefineOptionList("format", ref additionalFormats, "Output formats to write."); options.DefineParameterList("input", ref input, "Components to compile."); }); var loggerFactory = new LoggerFactory(); if (!silent) { loggerFactory.AddProvider(new BasicConsoleLogger(LogLevel.Information)); } var logger = loggerFactory.CreateLogger(typeof(ComponentApp)); if (!input.Any()) { logger.LogError("At least one input file must be specified."); Environment.Exit(1); } var generators = new Dictionary <IOutputGenerator, string>(); var outputGenerators = new OutputGeneratorRepository(); bool outputIsDirectory = Directory.Exists(output); if (output != null && !outputIsDirectory) { if (outputGenerators.TryGetGeneratorByFileExtension(Path.GetExtension(output), out var generator)) { // Use the generator implied by the file extension generators.Add(generator, output); } else if (additionalFormats?.Any() != true) { logger.LogError("Unable to infer format from output file extension." + Environment.NewLine + "Specify a known file extension or specify explicitly using --format"); Environment.Exit(1); } else { logger.LogInformation("Unable to infer format from output file extension. Using formats only."); } } if (additionalFormats?.Any() == true) { foreach (var format in additionalFormats) { if (outputGenerators.TryGetGeneratorByFormat(format, out var generator)) { generators.Add(generator, outputIsDirectory ? output : null); } else { logger.LogError($"Unknown format: {format}"); Environment.Exit(1); } } } var previewOptions = new PreviewGenerationOptions { Center = true, Crop = autosize, Width = imgWidth, Height = imgHeight, Configuration = configuration, Properties = new Dictionary <string, string>(), }; DirectoryComponentDescriptionLookup componentDescriptionLookup; if (input.Count == 1 && Directory.Exists(input.Single())) { componentDescriptionLookup = new DirectoryComponentDescriptionLookup(input.Single(), true); } else { componentDescriptionLookup = new DirectoryComponentDescriptionLookup(input.ToArray()); } var resourceProvider = ResourceProviderFactory.Create(loggerFactory.CreateLogger(typeof(ResourceProviderFactory)), resources); var outputRunner = new OutputRunner(loggerFactory.CreateLogger <OutputRunner>(), resourceProvider); var compileRunner = new ComponentDescriptionRunner(loggerFactory.CreateLogger <ComponentDescriptionRunner>(), outputRunner); var configurationDefinitionRunner = new ConfigurationDefinitionRunner(loggerFactory.CreateLogger <ConfigurationDefinitionRunner>(), componentDescriptionLookup, outputRunner); var results = new List <IManifestEntry>(); var inputs = new List <string>(); foreach (var i in input) { if (File.Exists(i)) { inputs.Add(i); } else if (Directory.Exists(i)) { foreach (var generator in generators) { if (generator.Value != null && !Directory.Exists(generator.Value)) { logger.LogError("Outputs must be directories when the input is a directory."); Environment.Exit(1); } } foreach (var file in Directory.GetFiles(i, "*.xml", recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) { inputs.Add(file); } foreach (var file in Directory.GetFiles(i, "*.yaml", recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) { inputs.Add(file); } } else { logger.LogError($"Input is not a valid file or directory: {i}"); Environment.Exit(1); } } foreach (var file in inputs.OrderBy(x => x)) { IManifestEntry result; switch (Path.GetExtension(file)) { case ".xml": result = compileRunner.CompileOne(file, previewOptions, allConfigurations, generators); break; case ".yaml": result = configurationDefinitionRunner.CompileOne(file, previewOptions, generators); break; default: throw new NotSupportedException($"File type '{Path.GetExtension(file)}' not supported."); } results.Add(result); } if (manifest != null) { using (var manifestFs = File.Open(manifest, FileMode.Create)) { logger.LogInformation($"Writing manifest to {manifest}"); ManifestWriter.WriteManifest(results, manifestFs); } } }
internal static void Build(Project project) { var application = new ApplicationManifest { IsClickOnceManifest = true, ReadOnly = false, IconFile = project.IconFile.Value, OSVersion = project.OsVersion.Value, OSDescription = project.OsDescription.Value, OSSupportUrl = project.OsSupportUrl.Value, TargetFrameworkVersion = project.TargetFramework.Version, HostInBrowser = project.LaunchMode.Value == LaunchMode.Browser, AssemblyIdentity = new AssemblyIdentity { Name = Path.GetFileName(project.EntryPoint.Value), Version = project.Version.Value, Culture = project.Culture.Value, ProcessorArchitecture = project.ProcessorArchitecture.Value.ToString().ToLowerInvariant() }, UseApplicationTrust = project.UseApplicationTrust.Value, TrustInfo = project.TrustInfo.Resolve() }; if (project.UseApplicationTrust.Value) { application.Publisher = project.Publisher.Value; application.SuiteName = project.Suite.Value; application.Product = project.Product.Value; application.SupportUrl = project.SupportUrl.Value; application.ErrorReportUrl = project.ErrorUrl.Value; application.Description = project.Description.Value; } application.AddEntryPoint(project); application.AddIconFile(project); application.AddGlob(project, project.Assemblies); application.AddGlob(project, project.DataFiles); application.AddGlob(project, project.Files); application.AddFileAssociations(project); application.ResolveFiles(); application.UpdateFileInfo(project.TargetFramework.Version); Logger.Normal(Messages.Build_Process_Application); application.Validate(); Logger.OutputMessages(application.OutputMessages, 1); if (!project.PackageMode.Value.HasFlag(PackageMode.Application)) { return; } Directory.CreateDirectory(Path.GetDirectoryName(project.ApplicationManifestFile.RootedPath)); ManifestWriter.WriteManifest(application, project.ApplicationManifestFile.RootedPath, project.TargetFramework.Version); var signed = Utilities.Sign(project.ApplicationManifestFile.RootedPath, project); Logger.Normal(Messages.Build_Process_Manifest, 1, 1, project.ApplicationManifestFile.RootedPath); if (signed) { Logger.Normal(Messages.Build_Process_Manifest_Signed, 1); } Logger.Normal(); }
/// <summary> /// Generated and returns the <code>META-INF/MANIFEST.MF</code> file based on the provided (optional) /// input <code>MANIFEST.MF</code> and digests of JAR entries covered by the manifest. /// </summary> /// <param name="jarEntryDigestAlgorithm"></param> /// <param name="jarEntryDigests"></param> /// <param name="sourceManifestBytes"></param> /// <returns></returns> public static OutputManifestFile GenerateManifestFile(DigestAlgorithm jarEntryDigestAlgorithm, IDictionary <string, byte[]> jarEntryDigests, byte[] sourceManifestBytes) { Manifest.Manifest sourceManifest = null; if (sourceManifestBytes != null) { try { sourceManifest = new Manifest.Manifest(sourceManifestBytes); } catch (IOException e) { throw new ApkFormatException("Malformed source META-INF/MANIFEST.MF", e); } } var manifestOut = new MemoryStream(); var mainAttrs = new Dictionary <string, string>(); // Copy the main section from the source manifest (if provided). Otherwise use defaults. // NOTE: We don't output our own Created-By header because this signer did not create the // JAR/APK being signed -- the signer only adds signatures to the already existing // JAR/APK. if (sourceManifest != null) { foreach (var kvp in sourceManifest.MainAttributes) { mainAttrs.Add(kvp.Key, kvp.Value); } } else { mainAttrs.Add(Manifest.Manifest.ManifestVersion, AttributeValueManifestVersion); } try { ManifestWriter.WriteMainSection(manifestOut, mainAttrs); } catch (IOException e) { throw new Exception("Failed to write in-memory MANIFEST.MF", e); } var sortedEntryNames = new List <string>(jarEntryDigests.Keys); sortedEntryNames.Sort(StringComparer.Ordinal); var invidualSectionsContents = new SortedDictionary <string, byte[]>(StringComparer.Ordinal); var entryDigestAttributeName = GetEntryDigestAttributeName(jarEntryDigestAlgorithm); foreach (var entryName in sortedEntryNames) { CheckEntryNameValid(entryName); var entryDigest = jarEntryDigests[entryName]; var entryAttrs = new Dictionary <string, string>(); entryAttrs.Add( entryDigestAttributeName, Convert.ToBase64String(entryDigest)); var sectionOut = new MemoryStream(); byte[] sectionBytes; try { ManifestWriter.WriteIndividualSection(sectionOut, entryName, entryAttrs); sectionBytes = sectionOut.ToArray(); manifestOut.Write(sectionBytes, 0, sectionBytes.Length); } catch (IOException e) { throw new Exception("Failed to write in-memory MANIFEST.MF", e); } invidualSectionsContents.Add(entryName, sectionBytes); } var result = new OutputManifestFile { Contents = manifestOut.ToArray(), MainSectionAttributes = mainAttrs, IndividualSectionsContents = invidualSectionsContents }; return(result); }
internal static void Build(Project project) { var deployment = new DeployManifest { SourcePath = project.Target.Value, ReadOnly = false, AssemblyIdentity = new AssemblyIdentity { Name = Path.GetFileName(project.DeploymentManifestFile.Value), Version = project.Version.Value, Culture = project.Culture.Value, ProcessorArchitecture = project.ProcessorArchitecture.Value.ToString().ToLowerInvariant() }, EntryPoint = new AssemblyReference { SourcePath = project.ApplicationManifestFile.RootedPath, TargetPath = Path.Combine(project.PackagePath.Value, project.ApplicationManifestFile.Value), AssemblyIdentity = AssemblyIdentity.FromManifest(project.ApplicationManifestFile.RootedPath) }, Product = project.Product.Value, SuiteName = project.Suite.Value, Publisher = project.Publisher.Value, Description = project.Description.Value, TargetFrameworkMoniker = project.TargetFramework.Moniker, DeploymentUrl = project.DeploymentUrl.Value is null ? null : $"{project.DeploymentUrl.Value}/{Path.GetFileName(project.DeploymentManifestFile.Value)}", ErrorReportUrl = project.ErrorUrl.Value, SupportUrl = project.SupportUrl.Value, Install = project.LaunchMode.Value.HasFlag(LaunchMode.Start), DisallowUrlActivation = !project.LaunchMode.Value.HasFlag(LaunchMode.Url), TrustUrlParameters = project.TrustUrlParameters.Value, MapFileExtensions = project.UseDeployExtension.Value, CreateDesktopShortcut = project.CreateDesktopShortcut.Value, UpdateEnabled = project.Update.Value.Enabled, UpdateInterval = project.Update.Value.Interval, UpdateUnit = project.Update.Value.Unit, UpdateMode = project.Update.Value.Mode, MinimumRequiredVersion = project.MinimumVersion.Value }; deployment.AssemblyReferences.Add(deployment.EntryPoint); deployment.ResolveFiles(); deployment.UpdateFileInfo(project.TargetFramework.Version); Logger.Normal(Messages.Build_Process_Deployment); deployment.Validate(); Logger.OutputMessages(deployment.OutputMessages, 1); if (!project.PackageMode.Value.HasFlag(PackageMode.Deployment)) { return; } Directory.CreateDirectory(Path.GetDirectoryName(project.DeploymentManifestFile.RootedPath)); ManifestWriter.WriteManifest(deployment, project.DeploymentManifestFile.RootedPath, project.TargetFramework.Version); var signed = Utilities.Sign(project.DeploymentManifestFile.RootedPath, project); File.Copy(project.DeploymentManifestFile.RootedPath, Path.Combine(project.PackagePath.RootedPath, Path.GetFileName(project.DeploymentManifestFile.Value)), true); Logger.Normal(Messages.Build_Process_Manifest, 1, 1, project.DeploymentManifestFile.RootedPath); if (signed) { Logger.Normal(Messages.Build_Process_Manifest_Signed, 1); } Logger.Normal(); if (project.CreateAutoRun.Value) { Logger.Normal(Messages.Build_Proces_AutoRun); using var autoRunFile = new StreamWriter(Path.Combine(project.Target.RootedPath, "autorun.inf")); autoRunFile.WriteLine("[autorun]"); autoRunFile.WriteLine($"open={Path.GetFileName(project.DeploymentManifestFile.Value)}"); Logger.Normal(Messages.Result_Done, 1, 2); } if (project.DeploymentPage.Value != null) { Logger.Normal(Messages.Build_Process_DeploymentPage); var templateFile = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "publish.template.html"); if (!File.Exists(templateFile)) { Logger.Normal(Messages.Build_Exceptions_DeploymentPage_TemplateNotFound); } else { using var reader = new StreamReader(templateFile); var deploymentPage = reader.ReadToEnd(); deploymentPage = Regex.Replace(deploymentPage, @"\$\{PublishedAt\}", $"{DateTime.UtcNow:G} (UTC)", RegexOptions.IgnoreCase); var placeholder = Regex.Match(deploymentPage, @"\$\{\w+\}", RegexOptions.IgnoreCase); while (placeholder.Success) { var option = project.FirstOrDefault(o => o.Name.Equals(placeholder.Value.Substring(2, placeholder.Length - 3), StringComparison.InvariantCultureIgnoreCase)); if (option != null) { deploymentPage = deploymentPage.Replace(placeholder.Value, option.ToString()); } placeholder = placeholder.NextMatch(); } using var writer = new StreamWriter(Path.Combine(project.Target.RootedPath, project.DeploymentPage.Value)); writer.Write(deploymentPage); Logger.Normal(Messages.Result_Done, 1, 2); } } } }