main
cs 129 lines 4.54 KB
Raw
1 // 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.
2
3 namespace WixToolset.Core.Native
4 {
5 using System;
6 using System.Collections.Generic;
7 using System.Linq;
8 using WixToolset.Data;
9
10 /// <summary>
11 /// Cabinet create, enumerate and extract mechanism.
12 /// </summary>
13 public sealed class Cabinet
14 {
15 private const string CompressionLevelVariable = "WIX_COMPRESSION_LEVEL";
16 private static readonly char[] TextLineSplitter = new[] { '\t' };
17
18 /// <summary>
19 /// Creates a cabinet creation, enumeration, extraction mechanism.
20 /// </summary>
21 /// <param name="path">Path of cabinet</param>
22 public Cabinet(string path)
23 {
24 this.Path = path;
25 }
26
27 /// <summary>
28 /// Cabinet path.
29 /// </summary>
30 public string Path { get; }
31
32 /// <summary>
33 /// Creates a cabinet.
34 /// </summary>
35 /// <param name="files">Files to compress.</param>
36 /// <param name="compressionLevel">Level of compression to apply.</param>
37 /// <param name="maxSize">Maximum size of cabinet.</param>
38 /// <param name="maxThresh">Maximum threshold for each cabinet.</param>
39 /// <returns>>List of CabinetCreated.</returns>
40 public IReadOnlyCollection<CabinetCreated> Compress(IEnumerable<CabinetCompressFile> files, CompressionLevel compressionLevel, int maxSize = 0, int maxThresh = 0)
41 {
42 var compressionLevelVariable = Environment.GetEnvironmentVariable(CompressionLevelVariable);
43
44 // Override authored compression level if environment variable is present.
45 if (!String.IsNullOrEmpty(compressionLevelVariable))
46 {
47 if (!Enum.TryParse(compressionLevelVariable, true, out compressionLevel))
48 {
49 throw new WixException(ErrorMessages.IllegalEnvironmentVariable(CompressionLevelVariable, compressionLevelVariable));
50 }
51 }
52
53 var wixnative = new WixNativeExe("smartcab", this.Path, Convert.ToInt32(compressionLevel), files.Count(), maxSize, maxThresh);
54
55 foreach (var file in files)
56 {
57 wixnative.AddStdinLine(file.ToWixNativeStdinLine());
58 }
59
60 var cabinetsCreated = wixnative.Run();
61
62 return ParseCreatedCabinets(cabinetsCreated);
63 }
64
65 /// <summary>
66 /// Enumerates all files in a cabinet.
67 /// </summary>
68 /// <returns>>List of CabinetFileInfo</returns>
69 public List<CabinetFileInfo> Enumerate()
70 {
71 var wixnative = new WixNativeExe("enumcab", this.Path);
72 var lines = wixnative.Run();
73
74 var fileInfoList = new List<CabinetFileInfo>();
75
76 foreach (var line in lines)
77 {
78 if (String.IsNullOrEmpty(line))
79 {
80 continue;
81 }
82
83 var data = line.Split(TextLineSplitter, StringSplitOptions.None);
84
85 var size = Convert.ToInt32(data[1]);
86 var date = Convert.ToInt32(data[2]);
87 var time = Convert.ToInt32(data[3]);
88
89 fileInfoList.Add(new CabinetFileInfo(data[0], size, date, time));
90 }
91
92 return fileInfoList;
93 }
94
95 /// <summary>
96 /// Extracts all the files from a cabinet to a directory.
97 /// </summary>
98 /// <param name="outputFolder">Directory to extract files to.</param>
99 public IEnumerable<string> Extract(string outputFolder)
100 {
101 if (!outputFolder.EndsWith("\\", StringComparison.Ordinal))
102 {
103 outputFolder += "\\";
104 }
105
106 var wixnative = new WixNativeExe("extractcab", this.Path, outputFolder);
107 return wixnative.Run().Where(output => !String.IsNullOrWhiteSpace(output));
108 }
109
110 private static IReadOnlyCollection<CabinetCreated> ParseCreatedCabinets(IReadOnlyCollection<string> cabinetsCreated)
111 {
112 var created = new List<CabinetCreated>();
113
114 foreach (var cabinetCreated in cabinetsCreated)
115 {
116 var data = cabinetCreated.Split(TextLineSplitter, StringSplitOptions.None);
117
118 if (data.Length != 3)
119 {
120 continue;
121 }
122
123 created.Add(new CabinetCreated(data[1], data[2]));
124 }
125
126 return created;
127 }
128 }
129 }