public static void Extract(CabinetOpenCabHandler openCabHandler, CabinetCloseCabHandler closeCabHandler, object openCabContext, bool autoChain, CabinetExtractOpenFileHandler openFileHandler, CabinetExtractCloseFileHandler closeFileHandler, object openFileContext, CabinetFilterFileHandler filterFileHandler, object filterContext, CabinetStatusCallback statusCallback, object statusContext) #endif // !CABMINIMAL { using (CabExtractor cabInstance = new CabExtractor()) { cabInstance.openCabHandler = openCabHandler; cabInstance.closeCabHandler = closeCabHandler; cabInstance.openCabContext = openCabContext; cabInstance.openFileHandler = openFileHandler; cabInstance.closeFileHandler = closeFileHandler; cabInstance.openFileContext = openFileContext; cabInstance.filterFileHandler = filterFileHandler; cabInstance.filterFileContext = filterContext; cabInstance.fdiNotifyHandler = new FDI.PFNNOTIFY(cabInstance.CabExtractNotify); cabInstance.nextCabinetName = ""; #if !CABMINIMAL cabInstance.statusCallback = statusCallback; cabInstance.statusContext = statusContext; if (statusCallback != null) { CabinetFileInfo[] files = Cabinet.GetFiles(openCabHandler, closeCabHandler, openCabContext, autoChain, filterFileHandler, filterContext); cabInstance.status.totalFiles = files.Length; cabInstance.status.totalFileBytes = 0; int prevFolder = -1, prevCabinet = -1; for (int i = 0; i < files.Length; i++) { cabInstance.status.totalFileBytes += files[i].Length; if (files[i].CabinetFolderNumber != prevFolder) // Assumes the results of GetFiles are grouped by folders { prevFolder = files[i].CabinetFolderNumber; cabInstance.status.totalFolders++; } if (files[i].CabinetNumber != prevCabinet) { prevCabinet = files[i].CabinetNumber; cabInstance.status.totalCabinets++; } } } #endif // !CABMINIMAL for (short iCab = 0; (autoChain || iCab == 0) && cabInstance.nextCabinetName != null; iCab++) { cabInstance.cabNumbers[""] = iCab; cabInstance.Process(); } } }
/// <summary> /// Extracts all files from a cabinet to a destination directory, optionally extracting only newer files. /// </summary> /// <param name="destDirectory">Directory where the files are to be extracted.</param> /// <param name="update">Specify true to only extract files when the timestamp in the cabinet is newer than /// the timestamp of the file on disk, when the file already exists.</param> /// <param name="callback">Handler for receiving progress information; this may be null if progress is not desired.</param> /// <param name="context">User context object passed to the <paramref name="callback"/>, may be null.</param> internal virtual void ExtractAll(string destDirectory, bool update, CabinetStatusCallback callback, object context) { using (Stream stream = this.GetCabinetReadStream()) { object[] fileContext = new Object[] { destDirectory, null, update }; Cabinet.Extract(stream, new CabinetExtractOpenFileHandler(CabinetInfo.ExtractOpenFileHandler), new CabinetExtractCloseFileHandler(CabinetInfo.ExtractCloseFileHandler), fileContext, null, null, callback, context); } }
/// <summary> /// Creates a cabinet and writes it to a stream. /// </summary> /// <param name="stream">The stream for writing the cabinet.</param> /// <param name="files">The names of the files in the cabinet (not external file paths).</param> /// <param name="compLevel">The cabinet compression level.</param> /// <param name="openFileHandler">Callback for opening streams for reading included files.</param> /// <param name="closeFileHandler">Callback for closing included file streams. This may be null, in which /// case the stream's <see cref="Stream.Close"/> method will be called.</param> /// <param name="openFileContext">User context object that will be passed to the /// <paramref name="openFileHandler"/> and <paramref name="closeFileHandler"/>.</param> /// <param name="statusCallback">Callback for reporting creation progress. This may be null /// if status is not desired.</param> /// <param name="statusContext">User context object passed to the <paramref name="statusCallback"/>.</param> /// <exception cref="CabinetCreateException">The cabinet could not be created.</exception> public static void Create(Stream stream, string[] files, CabinetCompressionLevel compLevel, CabinetCreateOpenFileHandler openFileHandler, CabinetCreateCloseFileHandler closeFileHandler, object openFileContext, CabinetStatusCallback statusCallback, object statusContext) #endif // !CABMINIMAL { if (stream == null) { throw new ArgumentNullException("stream"); } Cabinet.Create(null, null, 0, 0, new CabinetOpenCabHandler(Cabinet.DefaultOpenCabHandler), new CabinetCloseCabHandler(Cabinet.DefaultCloseCabHandler), stream, new string[][] { files }, compLevel, openFileHandler, closeFileHandler, openFileContext #if !CABMINIMAL , statusCallback, statusContext #endif // !CABMINIMAL ); }
/// <summary> /// Extracts files from a cabinet stream. /// </summary> /// <param name="stream">Stream for reading the cabinet file.</param> /// <param name="openFileHandler">Callback for opening streams for writing extracted files.</param> /// <param name="closeFileHandler">Callback for closing extracted file streams. This may be null, in which /// case the stream's <see cref="Stream.Close"/> method will be called.</param> /// <param name="openFileContext">User context object that will be passed to the /// <paramref name="openFileHandler"/> and <paramref name="closeFileHandler"/>.</param> /// <param name="filterFileHandler">Callback for filtering the list of extracted files. If null, /// all files will be extracted.</param> /// <param name="filterContext">User context object that will be passed to the /// <paramref name="filterFileHandler"/>.</param> /// <param name="statusCallback">Callback for reporting extraction status. This may be null /// if status is not desired.</param> /// <param name="statusContext">User context object passed to the <paramref name="statusCallback"/>.</param> /// <exception cref="CabinetExtractException">The stream is not a cabinet file or the cabinet file is corrupt.</exception> public static void Extract(Stream stream, CabinetExtractOpenFileHandler openFileHandler, CabinetExtractCloseFileHandler closeFileHandler, object openFileContext, CabinetFilterFileHandler filterFileHandler, object filterContext, CabinetStatusCallback statusCallback, object statusContext) #endif { if (stream == null) { throw new ArgumentNullException("stream"); } Cabinet.Extract(new CabinetOpenCabHandler(Cabinet.DefaultOpenCabHandler), new CabinetCloseCabHandler(Cabinet.DefaultCloseCabHandler), stream, false, openFileHandler, closeFileHandler, openFileContext, filterFileHandler, filterContext #if !CABMINIMAL , statusCallback, statusContext #endif // !CABMINIMAL ); }
/// <summary> /// Compresses files into the cabinet file, specifying the names used to store the files in the cabinet. /// </summary> /// <param name="sourceDirectory">This parameter may be null, but if specified it is the root directory /// for any relative paths in <paramref name="filenameMap"/>.</param> /// <param name="filenameMap">A mapping from internal file paths to external file paths.</param> /// <param name="compLevel">The compression level used when creating the cabinet.</param> /// <param name="callback">Handler for receiving progress information; this may be null if progress is not desired.</param> /// <param name="context">User context object passed to the <paramref name="callback"/>, may be null.</param> internal virtual void CompressFileSet(string sourceDirectory, IDictionary filenameMap, CabinetCompressionLevel compLevel, CabinetStatusCallback callback, object context) { if (filenameMap == null) { throw new ArgumentNullException("filenameMap"); } string[] fileNames = new string[filenameMap.Count]; filenameMap.Keys.CopyTo(fileNames, 0); using (Stream stream = this.GetCabinetWriteStream()) { Cabinet.Create(stream, fileNames, compLevel, new CabinetCreateOpenFileHandler(CabinetInfo.CreateOpenFileHandler), new CabinetCreateCloseFileHandler(CabinetInfo.CreateCloseFileHandler), new object[] { sourceDirectory, filenameMap }, callback, context); } }
/// <summary> /// Compresses files into the cabinet file, specifying the names used to store the files in the cabinet. /// </summary> /// <param name="sourceDirectory">This parameter may be null, but if specified it is the root directory /// for any relative paths in <paramref name="sourceFileNames"/>.</param> /// <param name="sourceFileNames">The list of files to be included in the cabinet.</param> /// <param name="fileNames">The names of the files as they are stored in the cabinet. Each name /// includes the internal path of the file, if any. This parameter may be null, in which case the /// files are stored in the cabinet with their source file names and no path information.</param> /// <param name="compLevel">The compression level used when creating the cabinet.</param> /// <param name="callback">Handler for receiving progress information; this may be null if progress is not desired.</param> /// <param name="context">User context object passed to the <paramref name="callback"/>, may be null.</param> /// <remarks> /// Duplicate items in the <paramref name="fileNames"/> array will cause a <see cref="CabinetCreateException"/>. /// </remarks> internal virtual void CompressFiles(string sourceDirectory, string[] sourceFileNames, string[] fileNames, CabinetCompressionLevel compLevel, CabinetStatusCallback callback, object context) { if (sourceFileNames == null) { if (sourceDirectory == null) { throw new ArgumentNullException("sourceDirectory", "Either sourceDirectory or sourceFileNames must be non-null."); } sourceFileNames = System.IO.Directory.GetFiles(sourceDirectory); } if (fileNames == null) { fileNames = new string[sourceFileNames.Length]; for (int i = 0; i < sourceFileNames.Length; i++) { fileNames[i] = Path.GetFileName(sourceFileNames[i]); } } using (Stream stream = this.GetCabinetWriteStream()) { Cabinet.Create(stream, fileNames, compLevel, new CabinetCreateOpenFileHandler(CabinetInfo.CreateOpenFileHandler), new CabinetCreateCloseFileHandler(CabinetInfo.CreateCloseFileHandler), new object[] { sourceDirectory, CreateStringDictionary(fileNames, sourceFileNames) }, callback, context); } }
/// <summary> /// Compresses all files in a directory into the cabinet file, optionally including subdirectories. /// The files are stored in the cabinet using their relative file paths in the directory tree. /// Note, while this library fully supports an internal directory structure in cabinets, /// some extraction tools do not. /// </summary> /// <param name="sourceDirectory">This parameter may be null, but if specified it is the root directory /// for any relative paths in source file.</param> /// <param name="includeSubdirectories">If true, recursively include files in subdirectories.</param> /// <param name="compLevel">The compression level used when creating the cabinet.</param> /// <param name="callback">Handler for receiving progress information; this may be null if progress is not desired.</param> /// <param name="context">User context object passed to the callback, may be null.</param> internal void CompressDirectory(string sourceDirectory, bool includeSubdirectories, CabinetCompressionLevel compLevel, CabinetStatusCallback callback, object context) { string[] files = GetRelativeFilePathsInDirectoryTree(sourceDirectory, includeSubdirectories); this.CompressFiles(sourceDirectory, files, files, compLevel, callback, context); }
/// <summary> /// Extracts multiple files from the cabinet. If any extracted files already exist on disk, they will be overwritten. /// </summary> /// <param name="filenameMap">A mapping from internal file paths to external file paths. /// Case-senstivity when matching internal paths depends on the IDictionary implementation.</param> /// <param name="destDirectory">This parameter may be null, but if specified it is the root directory /// for any relative external paths in <paramref name="filenameMap"/>.</param> /// <param name="update">Specify true to only extract files when the timestamp in the cabinet is newer than /// the timestamp of the file on disk, when the file already exists.</param> /// <param name="callback">Handler for receiving progress information; this may be null if progress is not desired.</param> /// <param name="context">User context object passed to the <paramref name="callback"/>, may be null.</param> internal virtual void ExtractFileSet(IDictionary filenameMap, string destDirectory, bool update, CabinetStatusCallback callback, Object context) { if (filenameMap == null) { throw new ArgumentNullException("filenameMap"); } using (Stream stream = this.GetCabinetReadStream()) { object[] fileContext = new Object[] { destDirectory, filenameMap, update }; Cabinet.Extract(stream, new CabinetExtractOpenFileHandler(CabinetInfo.ExtractOpenFileHandler), new CabinetExtractCloseFileHandler(CabinetInfo.ExtractCloseFileHandler), fileContext, new CabinetFilterFileHandler(this.FilterFileHandler), filenameMap, callback, context); } }
/// <summary> /// Extracts multiple files from the cabinet, optionally extracting only newer files. /// </summary> /// <param name="fileNames">The names of the files in the cabinet. Each name includes the internal /// path of the file, if any. File name matching is case-insensitive.</param> /// <param name="destDirectory">This parameter may be null, but if specified it is the root directory /// for any relative paths in <paramref name="destFileNames"/>.</param> /// <param name="destFileNames">The paths where the files are to be extracted on disk. If this parameter is null, /// the files will be extracted with the names from the cabinet.</param> /// <param name="update">Specify true to only extract files when the timestamp in the cabinet is newer than /// the timestamp of the file on disk, when the file already exists.</param> /// <param name="callback">Handler for receiving progress information; this may be null if progress is not desired.</param> /// <param name="context">User context object passed to the <paramref name="callback"/>, may be null.</param> /// <remarks> /// If any extracted files already exist on disk, they will be overwritten. /// <p>The <paramref name="destDirectory"/> and <paramref name="destFileNames"/> parameters cannot both be null.</p> /// </remarks> internal void ExtractFiles(string[] fileNames, string destDirectory, string[] destFileNames, bool update, CabinetStatusCallback callback, object context) { if (fileNames == null) { throw new ArgumentNullException("fileNames"); } if (destFileNames == null) { if (destDirectory == null) { throw new ArgumentNullException("destFileNames"); } destFileNames = fileNames; } this.ExtractFileSet(CreateStringDictionary(fileNames, destFileNames), destDirectory, update, callback, context); }
public static void Create(CabinetNameHandler nameHandler, object nameContext, long maxCabSize, long maxFolderSize, CabinetOpenCabHandler openCabHandler, CabinetCloseCabHandler closeCabHandler, object openCabContext, string[][] foldersAndFiles, CabinetCompressionLevel compLevel, CabinetCreateOpenFileHandler openFileHandler, CabinetCreateCloseFileHandler closeFileHandler, object openFileContext, CabinetStatusCallback statusCallback, object statusContext) #endif // !CABMINIMAL { using (CabCreator cabInstance = new CabCreator(maxCabSize, maxFolderSize)) { cabInstance.nameHandler = nameHandler; cabInstance.nameContext = nameContext; cabInstance.openCabHandler = openCabHandler; cabInstance.closeCabHandler = closeCabHandler; cabInstance.openCabContext = openCabContext; cabInstance.openFileHandler = openFileHandler; cabInstance.closeFileHandler = closeFileHandler; cabInstance.openFileContext = openFileContext; #if !CABMINIMAL cabInstance.statusCallback = statusCallback; cabInstance.statusContext = statusContext; if (cabInstance.statusCallback != null) { cabInstance.status.totalFolders = (short)foldersAndFiles.Length; for (int iFolder = 0; iFolder < foldersAndFiles.Length; iFolder++) { string[] files = foldersAndFiles[iFolder]; for (int iFile = 0; iFile < files.Length; iFile++) { FileAttributes attributes; DateTime lastWriteTime; Stream fileStream = openFileHandler(files[iFile], out attributes, out lastWriteTime, openFileContext); if (fileStream != null) { cabInstance.status.totalFileBytes += fileStream.Length; cabInstance.status.totalFiles++; } closeFileHandler(files[iFile], fileStream, openFileContext); } } } #endif // !CABMINIMAL for (int iFolder = 0; iFolder < foldersAndFiles.Length; iFolder++) { string[] files = foldersAndFiles[iFolder]; for (int iFile = 0; iFile < files.Length; iFile++) { FileAttributes attributes; DateTime lastWriteTime; Stream fileStream = openFileHandler(files[iFile], out attributes, out lastWriteTime, openFileContext); if (fileStream != null) { #if !CABMINIMAL if (cabInstance.statusCallback != null) { if (cabInstance.status.currentFolderTotalBytes > 0) { cabInstance.status.currentFolderBytesProcessed = cabInstance.status.currentFolderTotalBytes; cabInstance.status.statusType = CabinetStatusType.FinishFolder; cabInstance.statusCallback(cabInstance.status, cabInstance.statusContext); cabInstance.status.currentFolderBytesProcessed = cabInstance.status.currentFolderTotalBytes = 0; if (!(iFolder == 0 && iFile == 0)) { cabInstance.status.currentFolderNumber++; if (cabInstance.status.totalFolders <= cabInstance.status.currentFolderNumber) { cabInstance.status.totalFolders = (short)(cabInstance.status.currentFolderNumber + 1); } } } } #endif // !CABMINIMAL cabInstance.status.currentFileName = files[iFile]; if (!(iFolder == 0 && iFile == 0)) { cabInstance.status.currentFileNumber++; } #if !CABMINIMAL if (cabInstance.statusCallback != null) { cabInstance.status.currentFileTotalBytes = fileStream.Length; cabInstance.status.currentFileBytesProcessed = 0; cabInstance.status.statusType = CabinetStatusType.StartFile; cabInstance.statusCallback(cabInstance.status, cabInstance.statusContext); } #endif // !CABMINIMAL cabInstance.AddFile(files[iFile], fileStream, attributes, lastWriteTime, false, compLevel); } } cabInstance.FlushFolder(); } cabInstance.FlushCabinet(); } }