private string SetEntryPointAndConfig(ApplicationManifest manifest, string fileName, AssemblyReference asmRef) { string entryPointFileName = Path.GetFileName(fileName); manifest.EntryPoint = asmRef; manifest.AssemblyIdentity = AssemblyIdentity.FromFile(fileName); if (UseConfigName) { manifest.AssemblyIdentity.Name = entryPointFileName + "_" + this.ConfigName; } else { manifest.AssemblyIdentity.Name = entryPointFileName; } if (ConfigFile != null) { string configFilePath = Path.GetFullPath(ConfigFile.ItemSpec); FileReference configRef = new FileReference(configFilePath); string configFileName = entryPointFileName + ".config"; configRef.TargetPath = configFileName; manifest.FileReferences.Add(configRef); return(configFileName); } else { return(null); } }
/// <summary> /// Adds an individual file to the manifest /// </summary> /// <param name="fileName">Full file path of file to add</param> /// <param name="appfiles">The application files collection to add to</param> /// <param name="appManifest">The app manifest the file is associated with</param> public static void AddFile(string fileName, IList <ApplicationFile> appfiles, ApplicationManifest appManifest) { BaseReference fileRef; // Check to see if it is an assembly AssemblyIdentity assemId = AssemblyIdentity.FromFile(fileName); if (assemId != null) // valid assembly { // Add as assembly fileRef = appManifest.AssemblyReferences.Add(fileName); } else { // Add as a file fileRef = appManifest.FileReferences.Add(fileName); } // Add it to bound list of file information ApplicationFile appFile = new ApplicationFile(); appFile.FileName = Path.GetFileName(fileRef.TargetPath); string appManifestFolder = Path.GetDirectoryName(appManifest.SourcePath); appFile.RelativePath = ManifestHelper.GetRelativeFolderPath(fileName, appManifestFolder); appfiles.Add(appFile); }
private static bool Add(this Manifest application, Project project, string source, string target, GlobKind kind, string group = null) { if (source is null || target is null) { return(false); } if (kind == GlobKind.Assemblies && application.AssemblyReferences.FindTargetPath(target) is null && application.FileReferences.FindTargetPath(target) is null) { var identity = AssemblyIdentity.FromManagedAssembly(source); if (identity is null) { Logger.Verbose(Messages.Build_Process_Glob_Skipped, 1, 1, source); return(false); } application.AssemblyReferences.Add(new AssemblyReference { SourcePath = source, TargetPath = target, AssemblyIdentity = AssemblyIdentity.FromFile(source), IsOptional = group != null, Group = group }); }
/// <summary> /// Saves manifest values into the respective manifest /// </summary> /// <param name="name">Application deployment name</param> /// <param name="version">Version number</param> /// <param name="deploymentProvider">Deployment provider URL</param> /// <param name="deployManifest">Deployment manifest reference</param> /// <param name="appManifest">Application manifest reference</param> /// <param name="appFiles">List of files to populate app manifest</param> /// <param name="preReqs">List of prerequisites to add</param> public static void SaveManifestValues(string name, string version, string deploymentProvider, DeployManifest deployManifest, ApplicationManifest appManifest, IList <ApplicationFile> appFiles, IList <AssemblyReference> preReqs) { // Populate discrete values deployManifest.AssemblyIdentity.Name = name; deployManifest.AssemblyIdentity.Version = version; deployManifest.DeploymentUrl = deploymentProvider; appManifest.AssemblyIdentity.Version = version; // Refresh app manifest file lists appManifest.AssemblyReferences.Clear(); appManifest.FileReferences.Clear(); // Populate prerequisites foreach (AssemblyReference assemRef in preReqs) { appManifest.AssemblyReferences.Add(assemRef); } // Populate assembly and file references foreach (ApplicationFile appFile in appFiles) { string appFilePath = Path.Combine(appFile.RelativePath, appFile.FileName); string appManifestFolder = Path.GetDirectoryName(appManifest.SourcePath); string appFileFullPath = Path.Combine(appManifestFolder, appFilePath) + ".deploy"; AssemblyIdentity assemId = AssemblyIdentity.FromFile(appFileFullPath); if (assemId != null) // valid assembly { AssemblyReference assemRef = appManifest.AssemblyReferences.Add(appFileFullPath); assemRef.TargetPath = appFilePath; if (appFile.EntryPoint) { appManifest.EntryPoint = assemRef; } } else { FileReference fref = appManifest.FileReferences.Add(appFileFullPath); fref.TargetPath = appFilePath; if (appFile.DataFile) { fref.IsDataFile = true; } } } }
private static void InternalAddAssemblyReferences(ApplicationManifest application, string currentDirectory, string root) { foreach (var file in Directory.GetFiles(currentDirectory)) { var filePath = file; if (Path.GetExtension(filePath) == Constants.DeployDotExtension) { File.Move(filePath, filePath = GetNormalFilePath(filePath)); } var fileExtension = Path.GetExtension(filePath); if (fileExtension != null && Constants.IgnoreReferences.Any( item => string.Equals(item, fileExtension, StringComparison.InvariantCultureIgnoreCase))) { continue; } BaseReference fileReference; try { AssemblyName.GetAssemblyName(filePath); AssemblyReference assemblyReference; fileReference = assemblyReference = application.AssemblyReferences.Add(filePath); assemblyReference.AssemblyIdentity = AssemblyIdentity.FromFile(filePath); } catch (BadImageFormatException) { fileReference = application.FileReferences.Add(filePath); } fileReference.TargetPath = PathUtils.GetRelativePath(filePath, root); } foreach (var directory in Directory.GetDirectories(currentDirectory)) { InternalAddAssemblyReferences(application, directory, root); } }
private static IEnumerable <InfoData> GetGeneralInfoData(Container container) { var entryPoint = container.EntrypointPath; entryPoint = File.Exists(entryPoint) ? entryPoint : File.Exists(entryPoint = $"{entryPoint}{Constants.DeployDotExtension}") ? entryPoint : null; if (!string.IsNullOrEmpty(entryPoint)) { var entryPointIdentity = AssemblyIdentity.FromFile(entryPoint); if (entryPointIdentity != null && entryPointIdentity.IsStrongName) { // https://msdn.microsoft.com/en-us/library/aa730868(v=vs.80).aspx yield return (new InfoData( "EntryPoint [.exe]", $"You have a strong named entry point .exe file ({Path.GetFileName(entryPoint)}). Its means you should make a singing after ClickOnce application build done. Otherwise your try to deploy will have an error result \"Manifest XML signature is not valid\"", true)); } } }
private ApplicationManifest CreateApplicationManifest(string entryPoint, out string configFileName, out string entryPointFilePath) { entryPointFilePath = null; string frameworkVersion; if (string.IsNullOrEmpty(TargetFramework)) { frameworkVersion = "3.5"; } else { FrameworkName fn = new FrameworkName(TargetFramework); frameworkVersion = fn.Version.ToString(); } ApplicationManifest manifest = new ApplicationManifest(frameworkVersion); manifest.IsClickOnceManifest = true; manifest.IconFile = IconFile; configFileName = null; Dictionary <string, AssemblyIdentity> addedIdentities = new Dictionary <string, AssemblyIdentity>(); string basePath = Path.GetFullPath(BasePath); foreach (var taskItem in Files.Where(MatchFilter)) { string filePath = taskItem.GetMetadata("FullPath"); string targetPath = null; string dir = Path.GetDirectoryName(filePath); string fileName = Path.GetFileName(filePath); BaseReference reference = null; if (!dir.Equals(basePath, StringComparison.InvariantCultureIgnoreCase) && dir.StartsWith(basePath, StringComparison.InvariantCultureIgnoreCase)) { int index = basePath.Length; if (dir[index] == Path.DirectorySeparatorChar) { index++; } targetPath = Path.Combine(dir.Substring(index), fileName); } AssemblyIdentity identity = null; try { identity = AssemblyIdentity.FromFile(filePath); if (LinkAssembliesWithManifestAsFile && HasEmbeddedManifest(filePath)) { identity = null; } } catch (BadImageFormatException) { } if (identity != null) { string identityFullName = identity.GetFullName(AssemblyIdentity.FullNameFlags.All); if (addedIdentities.ContainsKey(identityFullName)) { throw new DuplicateAssemblyReferenceException(identityFullName); } else { addedIdentities.Add(identityFullName, identity); } AssemblyReference asmRef = new AssemblyReference(fileName); reference = asmRef; asmRef.AssemblyIdentity = identity; manifest.AssemblyReferences.Add(asmRef); if (manifest.EntryPoint == null && (string.IsNullOrEmpty(entryPoint) || string.Equals(entryPoint, fileName, StringComparison.InvariantCultureIgnoreCase)) && Path.GetExtension(fileName).Equals(".exe", StringComparison.InvariantCultureIgnoreCase)) { configFileName = SetEntryPointAndConfig(manifest, filePath, asmRef); entryPointFilePath = filePath; } } else { FileReference fileRef = new FileReference(fileName); reference = fileRef; manifest.FileReferences.Add(fileRef); } Log.LogMessage(MessageImportance.Low, "TargetPath for {0}: {1}", fileName, targetPath); reference.TargetPath = targetPath; } List <string> searchPaths = new List <string>(); searchPaths.Add(BasePath); if (ConfigFile != null) { searchPaths.Add(Path.GetDirectoryName(ConfigFile.ItemSpec)); } manifest.ResolveFiles(searchPaths.ToArray()); manifest.UpdateFileInfo(); TrustInfo trust = new TrustInfo(); trust.IsFullTrust = true; manifest.TrustInfo = trust; if (manifest.EntryPoint == null) { Log.LogError("Cannot determine EntryPoint. EntryPoint property = '{0}'", entryPoint ?? string.Empty); } return(manifest); }
/// <summary> /// Adds/updates references, using a breadth-first recursive descent model. /// </summary> /// <param name="manifest">Manifest whose references are to be updated</param> /// <param name="addDeploy">Specifies if '.deploy' should be appended</param> /// <param name="root">Directory where search began (does not change during descent)</param> /// <param name="searchDirectory">Directory to examine for references and subdirectories</param> /// <param name="relativePath">Path from origin directory (codeBase) to current directory</param> /// <param name="filesToIgnore">Files that should not be included in the manifest</param> /// <param name="lockedFileReporter">Delegate via which locked files will be reported</param> /// <param name="sender">Sender</param> /// <param name="updateProgress">UpdateProgress event handler</param> /// <param name="overwrite">Overwrite event handler</param> /// <param name="errors">List of errors</param> private static void AddReferences(ApplicationManifest manifest, bool addDeploy, string root, string searchDirectory, string relativePath, List <string> filesToIgnore, LockedFileReporter lockedFileReporter, object sender, UpdateProgressEventHandler updateProgress, OverwriteEventHandler overwrite, ArrayList errors) { if ((manifest == null) || (searchDirectory == null)) { return; } // Process files in current directory string[] files; try { files = Directory.GetFiles(searchDirectory); } catch (System.UnauthorizedAccessException) { return; } if (addDeploy) { files = AppendDeploy(filesToIgnore, files, overwrite, errors); } bool launcherBasedDeployment = false; string launcherPath = addDeploy ? Path.Combine(root, LauncherUtil.LauncherFilename + ".deploy") : Path.Combine(root, LauncherUtil.LauncherFilename); if (File.Exists(launcherPath)) { launcherBasedDeployment = true; } List <BaseReference> assembliesToRemove = new List <BaseReference>(); List <BaseReference> filesToRemove = new List <BaseReference>(); foreach (string filePath in files) { bool bRelativePath = false; // Generate codebase from filePath string codebase = filePath; if (codebase == null) { // This could be true if we renamed a file continue; } string extension = Path.GetExtension(codebase).ToLower(); // Strip a leading .\ from the path, if present if ((codebase.Length >= 2) && codebase.Substring(0, 2) == ".\\") { bRelativePath = true; codebase = codebase.Substring(2); } // See if this file is in the ignore list. // Ignorelist of the .manifest file is using the fullpath at // the very beggining so if a -fd . is used it does not find it. if (filesToIgnore.Contains(codebase.ToLower()) || (bRelativePath && extension == ".manifest" && filesToIgnore.Contains(Path.GetFullPath(codebase).ToLower()))) { continue; } // Strip the root path from the filename, if present if (codebase.StartsWith(root)) { codebase = codebase.Substring(root.Length); } // See if this file is in the ignore list if (filesToIgnore.Contains(codebase.ToLower()) || Path.GetExtension(codebase).ToLower() == ".netmodule" || (Path.GetExtension(codebase).ToLower() == ".deploy") && Path.GetExtension(codebase.Substring(0, codebase.Length - 7)).ToLower() == ".netmodule") { continue; } // Use the presence/absence of metadata to indicate whether // the file is an assembly or just a regular sort of file. AssemblyIdentity assembly = null; // If this is a Launcher-based deployment, all files except Launcher should be added as simple files // Launcher-based deployments are used for .NET (Core) apps - assembly identity cannot be positively // obtained from all types of .NET (Core) assemblies, requiring us to use simple file references. if (string.Equals(filePath, launcherPath, StringComparison.OrdinalIgnoreCase) || !launcherBasedDeployment) { try { assembly = AssemblyIdentity.FromFile(filePath); } catch (BadImageFormatException) { // The file does not have a manifest in it } catch (System.Net.WebException) { // Internet connection might not be available } } bool isAssembly = (assembly != null); // Make sure the file isn't locked, print an error message if // it is. Without this test, ManifestUtil will throw an // exception later when it tries to compute the file's hash. try { FileInfo f = new FileInfo(filePath); Stream s = f.OpenRead(); s.Close(); } catch (System.Exception) { lockedFileReporter?.Invoke(filePath); continue; } // Create a reference and add it to the appropriate collection. Action action = Action.AlreadyPresent; if (isAssembly) { if (!CollectionContains(manifest.AssemblyReferences, codebase, assembliesToRemove)) { AssemblyReference newref = new AssemblyReference { TargetPath = codebase }; manifest.AssemblyReferences.Add(newref); action = Action.Added; // Determine if this is the EntryPoint string strippedPath = codebase; if (strippedPath.ToLower().EndsWith(".deploy")) { strippedPath = strippedPath.Substring(0, codebase.Length - 7).ToLower(); } if (manifest.EntryPoint != null && (String.Compare(manifest.EntryPoint.TargetPath, strippedPath, true, CultureInfo.InvariantCulture) == 0)) { manifest.EntryPoint = newref; } } } else { if (!CollectionContains(manifest.FileReferences, codebase, filesToRemove)) { FileReference newref = new FileReference { TargetPath = codebase }; manifest.FileReferences.Add(newref); action = Action.Added; } } if (updateProgress != null) { updateProgress(sender, new UpdateProgressEventArgs(action, codebase)); } } // Remove files that were replaced because of renames. foreach (BaseReference reference in assembliesToRemove) { manifest.AssemblyReferences.Remove(reference as AssemblyReference); } foreach (BaseReference reference in filesToRemove) { manifest.FileReferences.Remove(reference as FileReference); } // Descend to subfolders string[] subdirs = Directory.GetDirectories(searchDirectory); foreach (string eachSubdir in subdirs) { string subdir = Path.GetFileName(eachSubdir); string newRelativePath; if ((relativePath.Length == 0) || (relativePath == ".")) { newRelativePath = subdir; } else { newRelativePath = relativePath + "\\" + subdir; } AddReferences(manifest, addDeploy, root, eachSubdir, newRelativePath, filesToIgnore, lockedFileReporter, sender, updateProgress, overwrite, errors); } }