//===================================================================== // Methods, etc. /// <summary> /// Constructor /// </summary> /// <param name="provider">The base path provider</param> public BindingRedirectSettings(IBasePathProvider provider) { configFile = new FilePath(provider); assemblyName = "assemblyName"; oldVersionFrom = new Version(1, 0, 0, 0); newVersion = new Version(1, 0, 0, 1); }
//===================================================================== /// <summary> /// Internal Constructor /// </summary> /// <param name="element">The project element</param> internal ProjectReferenceItem(ProjectElement element) : base(element) { projectPath = new FilePath(base.ProjectElement.Include, base.ProjectElement.Project); projectPath.PersistablePathChanging += new EventHandler( projectPath_PersistablePathChanging); this.GetProjectMetadata(false); base.ProjectElement.Include = projectPath.PersistablePath; }
//===================================================================== /// <summary> /// Internal Constructor /// </summary> /// <param name="element">The project element</param> internal ReferenceItem(ProjectElement element) : base(element) { if(base.ProjectElement.HasMetadata(ProjectElement.HintPath)) { hintPath = new FilePath(base.ProjectElement.GetMetadata( ProjectElement.HintPath), base.ProjectElement.Project); hintPath.PersistablePathChanging += new EventHandler( hintPath_PersistablePathChanging); } }
private void addButton_Click(object sender, EventArgs e) { if (_openFileDialog.ShowDialog(this) != DialogResult.OK) return; foreach (var fileName in _openFileDialog.FileNames) { var filePath = new FilePath(fileName, BasePathProvider); _filesListBox.Items.Add(filePath); } }
//===================================================================== /// <summary> /// Internal Constructor /// </summary> /// <param name="element">The project element</param> internal FileItem(ProjectElement element) : base(element) { buildAction = (BuildAction)Enum.Parse(typeof(BuildAction), base.ProjectElement.ItemName, true); includePath = new FilePath(base.ProjectElement.Include, base.ProjectElement.Project); includePath.PersistablePathChanging += new EventHandler( includePath_PersistablePathChanging); base.ProjectElement.Include = includePath.PersistablePath; if(base.ProjectElement.HasMetadata(ProjectElement.LinkPath)) { linkPath = new FilePath(base.ProjectElement.GetMetadata( ProjectElement.LinkPath), base.ProjectElement.Project); linkPath.PersistablePathChanging += new EventHandler( linkPath_PersistablePathChanging); } if(base.ProjectElement.HasMetadata(ProjectElement.ImageId)) imageId = base.ProjectElement.GetMetadata( ProjectElement.ImageId); if(base.ProjectElement.HasMetadata(ProjectElement.AlternateText)) altText = base.ProjectElement.GetMetadata( ProjectElement.AlternateText); if(base.ProjectElement.HasMetadata(ProjectElement.CopyToMedia)) if(!Boolean.TryParse(ProjectElement.GetMetadata( ProjectElement.CopyToMedia), out copyToMedia)) copyToMedia = false; if(base.ProjectElement.HasMetadata(ProjectElement.ExcludeFromToc)) if(!Boolean.TryParse(ProjectElement.GetMetadata( ProjectElement.ExcludeFromToc), out excludeFromToc)) excludeFromToc = false; if(base.ProjectElement.HasMetadata(ProjectElement.SortOrder)) if(!Int32.TryParse(ProjectElement.GetMetadata( ProjectElement.SortOrder), out sortOrder)) sortOrder = 0; }
//===================================================================== /// <summary> /// This constructor is used to wrap an existing reference /// </summary> /// <param name="project">The project that owns the reference</param> /// <param name="existingItem">The existing reference</param> /// <overloads>There are two overloads for the constructor</overloads> internal ProjectReferenceItem(SandcastleProject project, ProjectItem existingItem) : base(project, existingItem) { projectPath = new FilePath(this.Include, this.Project); projectPath.PersistablePathChanging += projectPath_PersistablePathChanging; this.GetProjectMetadata(false); this.Include = projectPath.PersistablePath; }
/// <summary> /// This constructor is used to create a new item and add it to the project /// </summary> /// <param name="project">The project that will own the item</param> /// <param name="itemType">The type of item to create</param> /// <param name="itemPath">The path to the item</param> internal FileItem(SandcastleProject project, string itemType, string itemPath) : base(project, itemType, itemPath) { buildAction = (BuildAction)Enum.Parse(typeof(BuildAction), this.ItemType, true); includePath = new FilePath(this.Include, this.Project); includePath.PersistablePathChanging += includePath_PersistablePathChanging; this.Include = includePath.PersistablePath; }
//===================================================================== /// <summary> /// Refresh the paths due to a parent path being renamed /// </summary> public void RefreshPaths() { includePath = new FilePath(this.Include, this.Project); if(this.HasMetadata(BuildItemMetadata.LinkPath)) this.LinkPath = new FilePath(this.GetMetadata(BuildItemMetadata.LinkPath), this.Project); }
/// <summary> /// This is used to locate a file by name in the project /// </summary> /// <param name="fileToFind">The fully qualified file path to find</param> /// <returns>The file item if found or null if not found</returns> public FileItem FindFile(string fileToFind) { FilePath filePath; FileItem fileItem = null; string itemPath, rootPath = Path.GetDirectoryName( msBuildProject.FullFileName); if(String.IsNullOrEmpty(fileToFind) || !fileToFind.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase)) return null; filePath = new FilePath(fileToFind, this); foreach(BuildItem item in msBuildProject.EvaluatedItems) { if(item.HasMetadata(ProjectElement.LinkPath)) itemPath = item.GetMetadata(ProjectElement.LinkPath); else itemPath = item.Include; if(itemPath == filePath.PersistablePath) { fileItem = new FileItem(new ProjectElement(this, item)); break; } } return fileItem; }
//===================================================================== /// <summary> /// This constructor is used to wrap an existing project item /// </summary> /// <param name="project">The project that owns the item</param> /// <param name="existingItem">The existing project item</param> /// <overloads>There are two overloads for the constructor</overloads> internal FileItem(SandcastleProject project, ProjectItem existingItem) : base(project, existingItem) { buildAction = (BuildAction)Enum.Parse(typeof(BuildAction), this.ItemType, true); includePath = new FilePath(this.Include, this.Project); includePath.PersistablePathChanging += includePath_PersistablePathChanging; this.Include = includePath.PersistablePath; if(this.HasMetadata(BuildItemMetadata.LinkPath)) { linkPath = new FilePath(this.GetMetadata(BuildItemMetadata.LinkPath), this.Project); linkPath.PersistablePathChanging += linkPath_PersistablePathChanging; } if(this.HasMetadata(BuildItemMetadata.ImageId)) imageId = this.GetMetadata(BuildItemMetadata.ImageId); if(this.HasMetadata(BuildItemMetadata.AlternateText)) altText = this.GetMetadata(BuildItemMetadata.AlternateText); if(this.HasMetadata(BuildItemMetadata.CopyToMedia)) if(!Boolean.TryParse(this.GetMetadata(BuildItemMetadata.CopyToMedia), out copyToMedia)) copyToMedia = false; if(this.HasMetadata(BuildItemMetadata.SortOrder)) if(!Int32.TryParse(this.GetMetadata(BuildItemMetadata.SortOrder), out sortOrder)) sortOrder = 0; }
/// <summary> /// Add a new file build item to the project /// </summary> /// <param name="sourceFile">The source filename</param> /// <param name="destFile">The optional destination path. If empty, null, or it does not start with the /// project folder, the file is copied to the root folder of the project.</param> /// <returns>The new <see cref="FileItem" /></returns> /// <remarks>If the file does not exist in the project, it is copied to the destination path or project /// folder if not already there. The default build action is determined based on the filename's /// extension. If the file is already part of the project, the existing item is returned.</remarks> public FileItem AddFileToProject(string sourceFile, string destFile) { BuildAction buildAction; FilePath filePath; FileItem newFileItem = null; string[] folders; string itemPath, rootPath = Path.GetDirectoryName(msBuildProject.FullPath); if(String.IsNullOrEmpty(destFile) || !destFile.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase)) destFile = Path.Combine(rootPath, Path.GetFileName(sourceFile)); filePath = new FilePath(destFile, this); buildAction = DefaultBuildAction(destFile); foreach(ProjectItem item in msBuildProject.AllEvaluatedItems) { if(item.HasMetadata(BuildItemMetadata.LinkPath)) itemPath = item.GetMetadataValue(BuildItemMetadata.LinkPath); else itemPath = item.EvaluatedInclude; // Files don't always have a relative path in the item when first added. As such, check both // the relative and full paths for a match. if(itemPath == filePath.PersistablePath || itemPath == filePath.Path) { newFileItem = new FileItem(this, item); break; } } if(!File.Exists(destFile)) { if(!Directory.Exists(Path.GetDirectoryName(destFile))) Directory.CreateDirectory(Path.GetDirectoryName(destFile)); // Make sure folder items exists for all parts of the path folders = Path.GetDirectoryName(filePath.PersistablePath).Split('\\'); itemPath = String.Empty; foreach(string path in folders) if(path.Length != 0) { itemPath += path + "\\"; this.AddFolderToProject(itemPath); } if(File.Exists(sourceFile)) { File.Copy(sourceFile, destFile); File.SetAttributes(destFile, FileAttributes.Normal); } } if(newFileItem == null) { newFileItem = new FileItem(this, buildAction.ToString(), destFile); // For images, assign the build action again so that it sets the default alternate text and ID if(buildAction == BuildAction.Image) newFileItem.BuildAction = buildAction; } return newFileItem; }
//===================================================================== /// <summary> /// Refresh the paths due to a parent path being renamed /// </summary> public void RefreshPaths() { this.includePath = new FilePath(base.ProjectElement.Include, base.ProjectElement.Project); if(base.ProjectElement.HasMetadata(ProjectElement.LinkPath)) this.Link = new FilePath(base.ProjectElement.GetMetadata( ProjectElement.LinkPath), base.ProjectElement.Project); }
//===================================================================== /// <summary> /// Constructor /// </summary> /// <param name="node">The node that contains the properties to expose /// via the Property Browser.</param> public DocumentationSourceNodeProperties(DocumentationSourceNode node) : base(node) { buildVarMatchEval = new MatchEvaluator(this.OnBuildVarMatch); documentationSource = node.DocumentationSource; sourceFile = new FilePath(documentationSource.Attribute("sourceFile").Value, this); sourceFile.PersistablePathChanging += sourceFile_PersistablePathChanging; sourceFile.PersistablePathChanged += sourceFile_PersistablePathChanged; if(documentationSource.Attribute("configuration") != null) configuration = documentationSource.Attribute("configuration").Value; if(documentationSource.Attribute("platform") != null) platform = documentationSource.Attribute("platform").Value; if(documentationSource.Attribute("subFolders") != null) includeSubFolders = documentationSource.Attribute("subFolders").Value.Equals( "true", StringComparison.OrdinalIgnoreCase); }
/// <summary> /// This constructor is used to create a new reference and add it to the project /// </summary> /// <param name="project">The project that will own the reference</param> /// <param name="itemType">The type of reference to create</param> /// <param name="itemPath">The path to the reference</param> internal ProjectReferenceItem(SandcastleProject project, string itemType, string itemPath) : base(project, itemType, itemPath) { projectPath = new FilePath(this.Include, this.Project); projectPath.PersistablePathChanging += projectPath_PersistablePathChanging; this.GetProjectMetadata(false); this.Include = projectPath.PersistablePath; }
/// <summary> /// This is used to set the named property to the specified value /// using Reflection. /// </summary> /// <param name="name">The name of the property to set</param> /// <param name="value">The value to which it is set</param> /// <returns>The parsed object value to which the property was set.</returns> /// <remarks>Property name matching is case insensitive as are the /// values. This is used to allow setting of simple project properties /// (non-collection) from the MSBuild project file. Unknown properties /// are ignored.</remarks> /// <exception cref="ArgumentNullException">This is thrown if the /// name parameter is null or an empty string.</exception> /// <exception cref="BuilderException">This is thrown if an error /// occurs while trying to set the named property.</exception> private void SetLocalProperty(string name, string value) { TypeConverter tc; EscapeValueAttribute escAttr; PropertyInfo property; FilePath filePath; object parsedValue; if(String.IsNullOrEmpty(name)) throw new ArgumentNullException("name"); // Ignore unknown properties if(!propertyCache.TryGetValue(name, out property)) { property = null; // Could be mismatched by case, so try again the long way foreach(string key in propertyCache.Keys) if(String.Compare(key, name, StringComparison.OrdinalIgnoreCase) == 0) { name = key; property = propertyCache[name]; break; } if(property == null) return; } if(!property.CanWrite || property.IsDefined( typeof(XmlIgnoreAttribute), true)) throw new BuilderException("PRJ0004", String.Format( CultureInfo.InvariantCulture, "An attempt was " + "made to set a read-only or ignored property: {0}" + " Value: {1}", name, value)); // If escaped, unescape it escAttr = pdcCache[name].Attributes[typeof(EscapeValueAttribute)] as EscapeValueAttribute; if(escAttr != null) value = EscapeValueAttribute.Unescape(value); try { if(property.PropertyType.IsEnum) parsedValue = Enum.Parse(property.PropertyType, value, true); else if(property.PropertyType == typeof(Version)) parsedValue = new Version(value); else { if(property.PropertyType == typeof(FilePath)) parsedValue = new FilePath(value, this); else if(property.PropertyType == typeof(FolderPath)) parsedValue = new FolderPath(value, this); else { tc = TypeDescriptor.GetConverter( property.PropertyType); parsedValue = tc.ConvertFromString(value); } // If it's a file or folder path, set the IsFixedPath // property based on whether or not it is rooted. filePath = parsedValue as FilePath; if(filePath != null && Path.IsPathRooted(value)) filePath.IsFixedPath = true; } } catch(Exception ex) { throw new BuilderException("PRJ0005", "Unable to parse value '" + value + "' for property '" + name + "'", ex); } property.SetValue(this, parsedValue, null); }
//===================================================================== /// <summary> /// Constructor /// </summary> /// <param name="source">The source image file</param> public ImageReference(string source) { id = Path.GetFileNameWithoutExtension(source); sourceFile = new FilePath(source, HtmlToMaml.PathProvider); }
/// <summary> /// Launch the ASP.NET Development Web Server to view the website /// output (Index.aspx). /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void miViewAspNetWebsite_Click(object sender, EventArgs e) { ProcessStartInfo psi; FilePath webServerPath = new FilePath(null); string[] files = null; string path; // Make sure we start out in the project's output folder // in case the output folder is relative to it. Directory.SetCurrentDirectory(Path.GetDirectoryName( Path.GetFullPath(project.Filename))); string outputPath = project.OutputPath; if(String.IsNullOrEmpty(outputPath)) outputPath = Directory.GetCurrentDirectory(); else outputPath = Path.GetFullPath(outputPath); outputPath += "Index.aspx"; if(!File.Exists(outputPath)) { MessageBox.Show("A copy of the website does not appear to " + "exist yet. It may need to be built.", Constants.AppName, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } try { // See if the web server needs to be started if(webServer == null || webServer.HasExited) { if(webServer != null) webServer.Dispose(); outputPath = Path.GetDirectoryName(outputPath); // Visual Studio conveniently provides a development web // server that doesn't require IIS. webServerPath.Path = String.Format( CultureInfo.InvariantCulture, "%SystemRoot%" + @"\Microsoft.NET\Framework\v{0}\WebDev.WebServer.exe", FrameworkVersionTypeConverter.LatestMatching("2")); // Visual Studio 2008 and later put it in a different location if(!File.Exists(webServerPath)) { path = Environment.ExpandEnvironmentVariables( @"%ProgramFiles%\Common Files\Microsoft Shared\" + "DevServer"); if(Directory.Exists(path)) files = Directory.GetFiles(path, "WebDev.WebServer.exe", SearchOption.AllDirectories); if(files != null && files.Length != 0) webServerPath.Path = files[0]; else { path = Environment.ExpandEnvironmentVariables( @"%ProgramFiles(x86)%\Common Files\Microsoft " + @"Shared\DevServer"); if(Directory.Exists(path)) files = Directory.GetFiles(path, "WebDev.WebServer.exe", SearchOption.AllDirectories); if(files != null && files.Length != 0) webServerPath.Path = files[0]; } } if(!File.Exists(webServerPath)) { MessageBox.Show("Unable to locate ASP.NET Development " + "Web Server. View the HTML website instead.", Constants.AppName, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } webServer = new Process(); psi = webServer.StartInfo; psi.FileName = webServerPath; psi.Arguments = String.Format(CultureInfo.InvariantCulture, "/port:{0} /path:\"{1}\" /vpath:\"/SHFBOutput_{2}\"", Settings.Default.ASPNETDevServerPort, outputPath, this.Handle); psi.WorkingDirectory = outputPath; psi.UseShellExecute = false; webServer.Start(); webServer.WaitForInputIdle(30000); } // This form's handle is used to keep the URL unique in case // multiple copies of SHFB are running so that each can view // website output. outputPath = String.Format(CultureInfo.InvariantCulture, "http://localhost:{0}/SHFBOutput_{1}/Index.aspx", Settings.Default.ASPNETDevServerPort, this.Handle); System.Diagnostics.Process.Start(outputPath); } catch(Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); MessageBox.Show(String.Format(CultureInfo.CurrentCulture, "Unable to open ASP.NET website '{0}'\r\nReason: {1}", outputPath, ex.Message), Constants.AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } }
/// <summary> /// Launch the ASP.NET Development Web Server to view the website output (Index.aspx/Index.html) /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void miViewAspNetWebsite_Click(object sender, EventArgs e) { ProcessStartInfo psi; FilePath webServerPath = new FilePath(null); string path, defaultPage = "Index.aspx"; // Make sure we start out in the project's output folder in case the output folder is relative to it Directory.SetCurrentDirectory(Path.GetDirectoryName(Path.GetFullPath(project.Filename))); string outputPath = project.OutputPath; if(String.IsNullOrEmpty(outputPath)) outputPath = Directory.GetCurrentDirectory(); else outputPath = Path.GetFullPath(outputPath); outputPath += defaultPage; if(!File.Exists(outputPath)) { outputPath = Path.ChangeExtension(outputPath, ".html"); defaultPage = "Index.html"; } if(!File.Exists(outputPath)) { MessageBox.Show("A copy of the website does not appear to exist yet. It may need to be built.", Constants.AppName, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } try { // See if the web server needs to be started if(webServer == null || webServer.HasExited) { if(webServer != null) webServer.Dispose(); outputPath = Path.GetDirectoryName(outputPath); // Visual Studio conveniently provides a development web server that doesn't require IIS path = Path.Combine(Environment.GetFolderPath(Environment.Is64BitProcess ? Environment.SpecialFolder.ProgramFilesX86 : Environment.SpecialFolder.ProgramFiles), @"Common Files\Microsoft Shared\DevServer"); if(Directory.Exists(path)) { webServerPath.Path = Directory.EnumerateFiles(path, "WebDev.WebServer40.exe", SearchOption.AllDirectories).FirstOrDefault(); // Fall back to the .NET 2.0/3.5 version? if(!File.Exists(webServerPath)) webServerPath.Path = Directory.EnumerateFiles(path, "WebDev.WebServer20.exe", SearchOption.AllDirectories).FirstOrDefault(); } if(!File.Exists(webServerPath)) { MessageBox.Show("Unable to locate ASP.NET Development Web Server. View the HTML " + "website instead.", Constants.AppName, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } webServer = new Process(); psi = webServer.StartInfo; psi.FileName = webServerPath; psi.Arguments = String.Format(CultureInfo.InvariantCulture, "/port:{0} /path:\"{1}\" /vpath:\"/SHFBOutput_{2}\"", Settings.Default.ASPNETDevServerPort, outputPath, this.Handle); psi.WorkingDirectory = outputPath; psi.UseShellExecute = false; webServer.Start(); webServer.WaitForInputIdle(30000); } // This form's handle is used to keep the URL unique in case multiple copies of SHFB are running // so that each can view website output. outputPath = String.Format(CultureInfo.InvariantCulture, "http://localhost:{0}/SHFBOutput_{1}/{2}", Settings.Default.ASPNETDevServerPort, this.Handle, defaultPage); System.Diagnostics.Process.Start(outputPath); } catch(Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); MessageBox.Show(String.Format(CultureInfo.CurrentCulture, "Unable to open ASP.NET website '{0}'\r\nReason: {1}", outputPath, ex.Message), Constants.AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } }
//===================================================================== /// <summary> /// Internal constructor /// </summary> /// <param name="filename">The filename of the documentation source</param> /// <param name="projConfig">The configuration to use for projects</param> /// <param name="projPlatform">The platform to use for projects</param> /// <param name="subFolders">True to include subfolders, false to /// only search the top-level folder.</param> /// <param name="project">The owning project</param> internal DocumentationSource(string filename, string projConfig, string projPlatform, bool subFolders, SandcastleProject project) : base(project) { sourceFile = new FilePath(filename, project); sourceFile.PersistablePathChanging += sourceFile_PersistablePathChanging; configuration = projConfig; platform = projPlatform; includeSubFolders = subFolders; }
/// <summary> /// This is used to set the named property to the specified value using Reflection /// </summary> /// <param name="name">The name of the property to set</param> /// <param name="value">The value to which it is set</param> /// <remarks>Property name matching is case insensitive as are the values. This is used to allow setting /// of simple project properties (non-collection) from the MSBuild project file. Unknown properties are /// ignored.</remarks> /// <exception cref="ArgumentNullException">This is thrown if the name parameter is null or an empty /// string.</exception> /// <exception cref="BuilderException">This is thrown if an error occurs while trying to set the named /// property.</exception> private void SetLocalProperty(string name, string value) { TypeConverter tc; EscapeValueAttribute escAttr; PropertyInfo property; FilePath filePath; object parsedValue; if(String.IsNullOrEmpty(name)) throw new ArgumentNullException("name"); // Ignore unknown properties if(!propertyCache.TryGetValue(name, out property)) return; if(!property.CanWrite || property.IsDefined(typeof(XmlIgnoreAttribute), true)) throw new BuilderException("PRJ0004", String.Format(CultureInfo.CurrentCulture, "An attempt was made to set a read-only or ignored property: {0} Value: {1}", name, value)); // If escaped, unescape it escAttr = pdcCache[name].Attributes[typeof(EscapeValueAttribute)] as EscapeValueAttribute; if(escAttr != null) value = EscapeValueAttribute.Unescape(value); try { if(property.PropertyType.IsEnum) parsedValue = Enum.Parse(property.PropertyType, value, true); else if(property.PropertyType == typeof(Version)) parsedValue = new Version(value); else { if(property.PropertyType == typeof(FilePath)) parsedValue = new FilePath(value, this); else if(property.PropertyType == typeof(FolderPath)) parsedValue = new FolderPath(value, this); else { tc = TypeDescriptor.GetConverter(property.PropertyType); parsedValue = tc.ConvertFromString(value); } // If it's a file or folder path, set the IsFixedPath property based on whether or not // it is rooted. filePath = parsedValue as FilePath; if(filePath != null && Path.IsPathRooted(value)) filePath.IsFixedPath = true; } } catch(Exception ex) { // Ignore exceptions for the Language property. A few people have had an environment variable // with that name that gets picked up as a default and the value isn't typically valid for a // culture name. if(!name.Equals("Language", StringComparison.OrdinalIgnoreCase)) throw new BuilderException("PRJ0005", "Unable to parse value '" + value + "' for property '" + name + "'", ex); parsedValue = null; } property.SetValue(this, parsedValue, null); }
//===================================================================== /// <summary> /// Constructor /// </summary> /// <param name="source">The source file or null to create an empty container node with no /// associated topic</param> public Topic(string source) { id = Guid.NewGuid(); revisionNumber = "1"; sortOrder = Int32.MaxValue; if(source != null) sourceFile = new FilePath(source, HtmlToMaml.PathProvider); subtopics = new TopicCollection(); }
/// <summary> /// This is used to locate a file by name in the project /// </summary> /// <param name="fileToFind">The fully qualified file path to find</param> /// <returns>The file item if found or null if not found</returns> public FileItem FindFile(string fileToFind) { FilePath filePath; FileItem fileItem = null; string itemPath, rootPath = Path.GetDirectoryName(msBuildProject.FullPath); if(String.IsNullOrEmpty(fileToFind) || !fileToFind.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase)) return null; filePath = new FilePath(fileToFind, this); foreach(ProjectItem item in msBuildProject.AllEvaluatedItems) { if(item.HasMetadata(BuildItemMetadata.LinkPath)) itemPath = item.GetMetadataValue(BuildItemMetadata.LinkPath); else itemPath = item.EvaluatedInclude; // Files don't always have a relative path in the item when first added. As such, check both // the relative and full paths for a match. if(itemPath == filePath.PersistablePath || itemPath == filePath.Path) { fileItem = new FileItem(this, item); break; } } return fileItem; }
//===================================================================== /// <summary> /// This returns a clone of the object /// </summary> /// <returns>A clone of the object</returns> public object Clone() { FilePath newFilePath = new FilePath(filePath, isFixedPath, basePathProvider); return newFilePath; }
//===================================================================== /// <summary> /// This constructor is used to wrap an existing reference /// </summary> /// <param name="project">The project that owns the reference</param> /// <param name="existingItem">The existing reference</param> /// <overloads>There are two overloads for the constructor</overloads> internal ReferenceItem(SandcastleProject project, ProjectItem existingItem) : base(project, existingItem) { if(this.HasMetadata(BuildItemMetadata.HintPath)) { hintPath = new FilePath(this.GetMetadata(BuildItemMetadata.HintPath), this.Project); hintPath.PersistablePathChanging += hintPath_PersistablePathChanging; } }
/// <summary> /// Add a new file build item to the project /// </summary> /// <param name="sourceFile">The source filename</param> /// <param name="destFile">The optional destination path. If empty, /// null, or it does not start with the project folder, the file is /// copied to the root folder of the project.</param> /// <returns>The new <see cref="FileItem" />.</returns> /// <remarks>If the file does not exist in the project, it is copied to /// the destination path or project folder if not already there. The /// default build action is determined based on the filename's /// extension. If the file is already part of the project, the /// existing item is returned.</remarks> public FileItem AddFileToProject(string sourceFile, string destFile) { BuildAction buildAction; FilePath filePath; FileItem newFileItem = null; string[] folders; string itemPath, rootPath = Path.GetDirectoryName( msBuildProject.FullFileName); if(String.IsNullOrEmpty(destFile) || !destFile.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase)) destFile = Path.Combine(rootPath, Path.GetFileName(sourceFile)); filePath = new FilePath(destFile, this); buildAction = DefaultBuildAction(destFile); foreach(BuildItem item in msBuildProject.EvaluatedItems) { if(item.HasMetadata(ProjectElement.LinkPath)) itemPath = item.GetMetadata(ProjectElement.LinkPath); else itemPath = item.Include; if(itemPath == filePath.PersistablePath) { newFileItem = new FileItem(new ProjectElement(this, item)); break; } } if(!File.Exists(destFile)) { if(!Directory.Exists(Path.GetDirectoryName(destFile))) Directory.CreateDirectory(Path.GetDirectoryName(destFile)); // Make sure folder items exists for all parts of the path folders = Path.GetDirectoryName(filePath.PersistablePath).Split('\\'); itemPath = String.Empty; foreach(string path in folders) if(path.Length != 0) { itemPath += path + "\\"; this.AddFolderToProject(itemPath); } if(File.Exists(sourceFile)) { File.Copy(sourceFile, destFile); File.SetAttributes(destFile, FileAttributes.Normal); } } if(newFileItem == null) newFileItem = new FileItem(new ProjectElement(this, buildAction.ToString(), destFile)); return newFileItem; }