// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. namespace WixToolset.Harvesters { using System; using System.IO; using WixToolset.Data; using WixToolset.Harvesters.Data; using WixToolset.Harvesters.Extensibility; using Wix = WixToolset.Harvesters.Serialize; /// <summary> /// Harvest WiX authoring for a file from the file system. /// </summary> public sealed class FileHarvester : BaseHarvesterExtension { private string rootedDirectoryRef; private bool setUniqueIdentifiers; private bool suppressRootDirectory; private static readonly string ComponentPrefix = "cmp"; private static readonly string DirectoryPrefix = "dir"; private static readonly string FilePrefix = "fil"; /// <summary> /// Instantiate a new FileHarvester. /// </summary> public FileHarvester() { this.setUniqueIdentifiers = true; this.suppressRootDirectory = false; } /// <summary> /// Gets or sets the rooted DirectoryRef Id if the user has supplied it. /// </summary> /// <value>The DirectoryRef Id to use as the root.</value> public string RootedDirectoryRef { get { return this.rootedDirectoryRef; } set { this.rootedDirectoryRef = value; } } /// <summary> /// Gets of sets the option to set unique identifiers. /// </summary> /// <value>The option to set unique identifiers.</value> public bool SetUniqueIdentifiers { get { return this.setUniqueIdentifiers; } set { this.setUniqueIdentifiers = value; } } /// <summary> /// Gets or sets the option to suppress including the root directory as an element. /// </summary> /// <value>The option to suppress including the root directory as an element.</value> public bool SuppressRootDirectory { get { return this.suppressRootDirectory; } set { this.suppressRootDirectory = value; } } /// <summary> /// Harvest a file. /// </summary> /// <param name="argument">The path of the file.</param> /// <returns>A harvested file.</returns> public override Wix.Fragment[] Harvest(string argument) { if (null == argument) { throw new ArgumentNullException("argument"); } if (null == this.rootedDirectoryRef) { this.rootedDirectoryRef = "TARGETDIR"; } string fullPath = Path.GetFullPath(argument); var directoryRef = DirectoryHelper.CreateDirectoryReference(this.rootedDirectoryRef); Wix.File file = this.HarvestFile(fullPath); if (!this.suppressRootDirectory) { file.Source = String.Concat("SourceDir\\", Path.GetFileName(Path.GetDirectoryName(fullPath)), "\\", Path.GetFileName(fullPath)); } Wix.Component component = new Wix.Component(); component.AddChild(file); Wix.Directory directory = new Wix.Directory(); if (this.suppressRootDirectory) { directoryRef.AddChild(component); } else { string directoryPath = Path.GetDirectoryName(Path.GetFullPath(argument)); directory.Name = Path.GetFileName(directoryPath); if (this.setUniqueIdentifiers) { directory.Id = this.Core.GenerateIdentifier(DirectoryPrefix, directoryRef.Id, directory.Name); } directory.AddChild(component); directoryRef.AddChild(directory); } if (this.setUniqueIdentifiers) { file.Id = this.Core.GenerateIdentifier(FilePrefix, (this.suppressRootDirectory) ? directoryRef.Id : directory.Id, Path.GetFileName(file.Source)); component.Id = this.Core.GenerateIdentifier(ComponentPrefix, (this.suppressRootDirectory) ? directoryRef.Id : directory.Id, file.Id); } Wix.Fragment fragment = new Wix.Fragment(); fragment.AddChild(directoryRef); return new Wix.Fragment[] { fragment }; } /// <summary> /// Harvest a file. /// </summary> /// <param name="path">The path of the file.</param> /// <returns>A harvested file.</returns> public Wix.File HarvestFile(string path) { if (null == path) { throw new ArgumentNullException("path"); } if (!File.Exists(path)) { throw new WixException(HarvesterErrors.FileNotFound(path)); } Wix.File file = new Wix.File(); // use absolute paths path = Path.GetFullPath(path); file.KeyPath = Wix.YesNoType.yes; file.Source = String.Concat("SourceDir\\", Path.GetFileName(path)); return file; } } }