public virtual CabinetBuildOption ResolveCabinet(FileRowCollection fileRows, ref string cabinetPath) { if (fileRows == null) { throw new ArgumentNullException("fileRows"); } // no special behavior specified, use the default if (null == this.cabCachePath && !this.reuseCabinets) { return(CabinetBuildOption.BuildAndMove); } // if a cabinet cache path was provided, change the location for the cabinet // to be built to if (null != this.cabCachePath) { string cabinetName = Path.GetFileName(cabinetPath); cabinetPath = Path.Combine(this.cabCachePath, cabinetName); } // if we still think we're going to reuse the cabinet check to see if the cabinet exists first if (this.reuseCabinets) { bool cabinetValid = false; if (BinderFileManager.CheckFileExists(cabinetPath)) { // check to see if // 1. any files are added or removed // 2. order of files changed or names changed // 3. modified time changed cabinetValid = true; // Need to force garbage collection of WixEnumerateCab to ensure the handle // associated with it is closed before it is reused. using (Cab.WixEnumerateCab wixEnumerateCab = new Cab.WixEnumerateCab()) { ArrayList fileList = wixEnumerateCab.Enumerate(cabinetPath); if (fileRows.Count != fileList.Count) { cabinetValid = false; } else { int i = 0; foreach (FileRow fileRow in fileRows) { // First check that the file identifiers match because that is quick and easy. CabinetFileInfo cabFileInfo = fileList[i] as CabinetFileInfo; cabinetValid = (cabFileInfo.FileId == fileRow.File); if (cabinetValid) { // Still valid so ensure the source time stamp hasn't changed. Thus we need // to convert the source file time stamp into a cabinet compatible data/time. DateTime sourceFileTime = File.GetLastWriteTime(fileRow.Source); ushort sourceCabDate; ushort sourceCabTime; Cab.Interop.CabInterop.DateTimeToCabDateAndTime(sourceFileTime, out sourceCabDate, out sourceCabTime); cabinetValid = (cabFileInfo.Date == sourceCabDate && cabFileInfo.Time == sourceCabTime); } if (!cabinetValid) { break; } i++; } } } } return(cabinetValid ? CabinetBuildOption.Copy : CabinetBuildOption.BuildAndCopy); } else // by default move the built cabinet { return(CabinetBuildOption.BuildAndMove); } }
/// <summary> /// Resolves the source path of a cabinet file. /// </summary> /// <param name="fileRows">Collection of files in this cabinet.</param> /// <param name="cabinetPath">Path to cabinet to generate. Path may be modified by delegate.</param> /// <returns>The CabinetBuildOption. By default the cabinet is built and moved to its target location.</returns> public virtual CabinetBuildOption ResolveCabinet(FileRowCollection fileRows, ref string cabinetPath) { // no special behavior specified, use the default if (null == this.cabCachePath && !this.reuseCabinets) { return(CabinetBuildOption.BuildAndMove); } // if a cabinet cache path was provided, change the location for the cabinet // to be built to if (null != this.cabCachePath) { string cabinetName = Path.GetFileName(cabinetPath); cabinetPath = Path.Combine(this.cabCachePath, cabinetName); } // if we still think we're going to reuse the cabinet check to see if the cabinet exists first if (this.reuseCabinets) { bool cabinetExists = false; if (File.Exists(cabinetPath)) { // check to see if // 1. any files are added or removed // 2. order of files changed or names changed // 3. modified time changed cabinetExists = true; Cab.WixEnumerateCab wixEnumerateCab = new Cab.WixEnumerateCab(); ArrayList fileList = wixEnumerateCab.Enumerate(cabinetPath); if (fileRows.Count != fileList.Count) { cabinetExists = false; } else { int i = 0; foreach (FileRow fileRow in fileRows) { CabinetFileInfo fileInfo = fileList[i] as CabinetFileInfo; DateTime fileTime = File.GetLastWriteTime(fileRow.Source); ushort cabDate; ushort cabTime; Cab.Interop.CabInterop.DateTimeToCabDateAndTime(fileTime, out cabDate, out cabTime); if (fileRow.File != fileInfo.FileId || fileInfo.Date != cabDate || fileInfo.Time != cabTime) { cabinetExists = false; break; } i++; } } } return(cabinetExists ? CabinetBuildOption.Copy : CabinetBuildOption.BuildAndCopy); } else // by default move the built cabinet { return(CabinetBuildOption.BuildAndMove); } }