リビジョン | a540a230a748481804d78f4200d46292db3db67b (tree) |
---|---|
日時 | 2014-07-21 23:43:40 |
作者 | ttp <ttp@user...> |
コミッター | ttp |
na-get-lib, 7-Zipがインストールされているならば 7z.exe で展開するコードを追加 (cab他対策)。
@@ -13,15 +13,6 @@ namespace ArchiveInstall | ||
13 | 13 | |
14 | 14 | public const string InstalledPackageFileName = ".applistation.package.xml"; |
15 | 15 | |
16 | - private static void extract(string arcFile, string extractDestDir) | |
17 | - { | |
18 | - StringBuilder output = new StringBuilder(1024); | |
19 | - int res = NaGet.InteropServices.CommonArchiverExtracter.ExtractArchive(arcFile, extractDestDir, output, IntPtr.Zero); | |
20 | - if (res != 0) { | |
21 | - Environment.Exit(res); | |
22 | - } | |
23 | - } | |
24 | - | |
25 | 16 | private static void install(string fakeTargetDir, string targetDir) |
26 | 17 | { |
27 | 18 | // ハッシュ比較 |
@@ -316,6 +307,8 @@ namespace ArchiveInstall | ||
316 | 307 | Console.WriteLine("\t{0} -i archive.zip PackageName\tInstall", executeFileName); |
317 | 308 | Console.WriteLine("\t{0} -x PackageName\t\tUninstall", executeFileName); |
318 | 309 | Console.WriteLine(); |
310 | + | |
311 | + Environment.ExitCode = 1; | |
319 | 312 | } |
320 | 313 | |
321 | 314 | // インストールおよび展開処理 |
@@ -330,7 +323,7 @@ namespace ArchiveInstall | ||
330 | 323 | string destFile = Path.Combine(tempExtractDir, Path.GetFileName(arcFile)); |
331 | 324 | File.Copy(arcFile, destFile); |
332 | 325 | } else { |
333 | - extract(arcFile, tempExtractDir); | |
326 | + NaGet.ArchiveExtractionHelpers.ArchiveExtract.Extract(arcFile, tempExtractDir); | |
334 | 327 | } |
335 | 328 | |
336 | 329 | // インストールの元となるフォルダを決定する |
@@ -354,12 +347,18 @@ namespace ArchiveInstall | ||
354 | 347 | // STEP5. パッケージ情報をインストール先(targetDir)に置く |
355 | 348 | storePackageXml(package, targetDir); |
356 | 349 | } |
357 | - } catch (DllNotFoundException) { | |
358 | - Console.Error.WriteLine("E: Does not exist archive dll for {0}", arcFile); // TODO | |
359 | - Environment.Exit(10); | |
350 | + } catch (NaGet.InteropServices.CommonArchiverDllExtractionException e) { | |
351 | + Console.Error.WriteLine("E: Error: {0}", e.Message); | |
352 | + Environment.ExitCode = e.ReturnValue; | |
353 | + } catch (NaGet.ArchiveExtractionHelpers.SevenZipExtractException e) { | |
354 | + Console.Error.WriteLine("E: Error: {0}", e.Message); | |
355 | + Environment.ExitCode = e.ReturnValue; | |
356 | + } catch (ApplicationException e) { | |
357 | + Console.Error.WriteLine("E: Error: {0}", e.Message); | |
358 | + Environment.ExitCode = 1; | |
360 | 359 | } catch (IOException e) { |
361 | 360 | Console.Error.WriteLine("E: File I/O Error : {0}", e.Message); |
362 | - Environment.Exit(1); | |
361 | + Environment.ExitCode = 1; | |
363 | 362 | } finally { |
364 | 363 | Directory.Delete(tempExtractDir, true); |
365 | 364 | } |
@@ -0,0 +1,29 @@ | ||
1 | +using System; | |
2 | +using System.IO; | |
3 | +using System.Text; | |
4 | + | |
5 | +namespace NaGet.ArchiveExtractionHelpers | |
6 | +{ | |
7 | + public class ArchiveExtract | |
8 | + { | |
9 | + private ArchiveExtract() | |
10 | + { | |
11 | + } | |
12 | + | |
13 | + public static bool Extract(string arcFile, string extractDestDir) | |
14 | + { | |
15 | + bool ret = false; | |
16 | + | |
17 | + if (ret == false) { | |
18 | + StringBuilder output = new StringBuilder(1024); | |
19 | + ret = NaGet.InteropServices.CommonArchiverExtracter.ExtractArchive(arcFile, extractDestDir, output, IntPtr.Zero); | |
20 | + } | |
21 | + | |
22 | + if (ret == false) { | |
23 | + ret = SevenZipExtract.ExtractArchive(arcFile, extractDestDir); | |
24 | + } | |
25 | + | |
26 | + return ret; | |
27 | + } | |
28 | + } | |
29 | +} |
@@ -0,0 +1,108 @@ | ||
1 | +using System; | |
2 | +using System.IO; | |
3 | +using System.Diagnostics; | |
4 | + | |
5 | +namespace NaGet.ArchiveExtractionHelpers | |
6 | +{ | |
7 | + /// <summary> | |
8 | + /// 7zG.exe呼び出しによるアーカイブ展開のエラー | |
9 | + /// </summary> | |
10 | + public class SevenZipExtractException : ApplicationException { | |
11 | + /// <summary> | |
12 | + /// 戻り値 | |
13 | + /// </summary> | |
14 | + private int returnValue; | |
15 | + | |
16 | + /// <summary> | |
17 | + /// 7z.exe呼び出しによるアーカイブ展開のエラー | |
18 | + /// </summary> | |
19 | + /// <param name="message">メッセージ</param> | |
20 | + /// <param name="dllName">対象DLL名</param> | |
21 | + /// <param name="returnValue">戻り値</param> | |
22 | + public SevenZipExtractException(string message, int returnValue) | |
23 | + : base(message) | |
24 | + { | |
25 | + this.returnValue = returnValue; | |
26 | + } | |
27 | + | |
28 | + /// <summary> | |
29 | + /// 戻り値(非0) | |
30 | + /// </summary> | |
31 | + public int ReturnValue { | |
32 | + get { return returnValue; } | |
33 | + } | |
34 | + } | |
35 | + | |
36 | + /// <summary> | |
37 | + /// 7zG.exe呼び出しによるアーカイブ展開 | |
38 | + /// </summary> | |
39 | + public class SevenZipExtract | |
40 | + { | |
41 | + /// <summary> | |
42 | + /// 7zG.exeのパスを返す | |
43 | + /// </summary> | |
44 | + private static string SevenZipExeFilePath { | |
45 | + get { | |
46 | + string subPath = Path.Combine("7-Zip", "7zG.exe"); | |
47 | + string path = null; | |
48 | + | |
49 | + if (! string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ProgramFiles"))) { | |
50 | + string programFiles = Environment.GetEnvironmentVariable("ProgramFiles"); | |
51 | + if (File.Exists(Path.Combine(programFiles, subPath))) { | |
52 | + path = Path.Combine(programFiles, subPath); | |
53 | + } else if (programFiles.EndsWith(" (x86)")) { | |
54 | + // WOW64対策として手動で" (x86)"を抜く | |
55 | + programFiles = programFiles.Substring(0, programFiles.Length - " (x86)".Length); | |
56 | + if (File.Exists(Path.Combine(programFiles, subPath))) { | |
57 | + path = Path.Combine(programFiles, subPath); | |
58 | + } | |
59 | + } | |
60 | + } else if (! string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ProgramFiles(x86)"))) { | |
61 | + string programFiles = Environment.GetEnvironmentVariable("ProgramFiles(x86)"); | |
62 | + if (File.Exists(Path.Combine(programFiles, subPath))) { | |
63 | + path = Path.Combine(programFiles, subPath); | |
64 | + } | |
65 | + } | |
66 | + return path; | |
67 | + } | |
68 | + } | |
69 | + | |
70 | + /// <summary> | |
71 | + /// アーカイブを展開する。 | |
72 | + /// </summary> | |
73 | + /// <param name="arcFile">アーカイブのパス</param> | |
74 | + /// <param name="targetDir">展開先ディレクトリ</param> | |
75 | + /// <param name="output">アーカイバの展開時の標準出力を格納する</param> | |
76 | + /// <returns>7zG.exe が見つかって正しく処理できたらtrue、7zG.exe が見つからなかったらfalse</returns> | |
77 | + public static bool ExtractArchive(string arcFile, string targetDir) | |
78 | + { | |
79 | + bool retVal = false; | |
80 | + | |
81 | + if (! string.IsNullOrEmpty(SevenZipExeFilePath)) { | |
82 | + | |
83 | + if (Directory.Exists(targetDir)) { | |
84 | + NaGet.Utils.SetAttributeRecursive(targetDir, FileAttributes.Normal); | |
85 | + Directory.Delete(targetDir, true); | |
86 | + } | |
87 | + Directory.CreateDirectory(targetDir); | |
88 | + | |
89 | + ProcessStartInfo procInfo = new ProcessStartInfo(); | |
90 | + procInfo.FileName = SevenZipExeFilePath; | |
91 | + procInfo.Arguments = string.Format("x \"{0}\" -o\"{1}\"", arcFile, targetDir); | |
92 | + procInfo.WorkingDirectory = targetDir; | |
93 | + //procInfo.WindowStyle = ProcessWindowStyle.Hidden; | |
94 | + | |
95 | + Process hProcess = Process.Start(procInfo); | |
96 | + hProcess.WaitForExit(); | |
97 | + if (hProcess.ExitCode == 0) { | |
98 | + retVal = true; | |
99 | + } else { | |
100 | + string errorMsg = string.Format("Extraction failure: \"{0}\" returns {1}.", SevenZipExeFilePath, hProcess.ExitCode); | |
101 | + throw new SevenZipExtractException(errorMsg, hProcess.ExitCode); | |
102 | + } | |
103 | + } | |
104 | + | |
105 | + return retVal; | |
106 | + } | |
107 | + } | |
108 | +} |
@@ -36,6 +36,49 @@ namespace NaGet.InteropServices | ||
36 | 36 | } |
37 | 37 | |
38 | 38 | /// <summary> |
39 | + /// アーカイバDLLを使った書庫展開のエラー | |
40 | + /// </summary> | |
41 | + public class CommonArchiverDllExtractionException : ApplicationException | |
42 | + { | |
43 | + /// <summary> | |
44 | + /// DLLファイル名 | |
45 | + /// </summary> | |
46 | + private string dllName; | |
47 | + | |
48 | + /// <summary> | |
49 | + /// 戻り値 | |
50 | + /// </summary> | |
51 | + private int returnValue; | |
52 | + | |
53 | + /// <summary> | |
54 | + /// アーカイバDLLを使った書庫展開のエラー | |
55 | + /// </summary> | |
56 | + /// <param name="message">メッセージ</param> | |
57 | + /// <param name="dllName">対象DLL名</param> | |
58 | + /// <param name="returnValue">戻り値</param> | |
59 | + public CommonArchiverDllExtractionException(string message, string dllName, int returnValue) | |
60 | + : base(message) | |
61 | + { | |
62 | + this.dllName = dllName; | |
63 | + this.returnValue = returnValue; | |
64 | + } | |
65 | + | |
66 | + /// <summary> | |
67 | + /// DLLファイルの名称 | |
68 | + /// </summary> | |
69 | + public string DllName { | |
70 | + get { return dllName; } | |
71 | + } | |
72 | + | |
73 | + /// <summary> | |
74 | + /// 戻り値(非0) | |
75 | + /// </summary> | |
76 | + public int ReturnValue { | |
77 | + get { return returnValue; } | |
78 | + } | |
79 | + } | |
80 | + | |
81 | + /// <summary> | |
39 | 82 | /// アーカイバDLLを使った書庫展開器 |
40 | 83 | /// </summary> |
41 | 84 | public class CommonArchiverExtracter |
@@ -114,17 +157,25 @@ namespace NaGet.InteropServices | ||
114 | 157 | /// <param name="targetDir">展開先ディレクトリ</param> |
115 | 158 | /// <param name="output">アーカイバDLLの展開時の標準出力を格納する</param> |
116 | 159 | /// <param name="hWnd">親フレーム</param> |
117 | - /// <returns>アーカイバDLLの展開時のエラーコード(0なら正常終了)</returns> | |
118 | - public static int ExtractArchive(string arcFile, string targetDir, System.Text.StringBuilder output, IntPtr hWnd) | |
160 | + /// <returns>アーカイバDLLが見つかって正しく処理できたらtrue、DLLが見つからなかったらfalse</returns> | |
161 | + public static bool ExtractArchive(string arcFile, string targetDir, System.Text.StringBuilder output, IntPtr hWnd) | |
119 | 162 | { |
163 | + bool ret = false; | |
164 | + | |
120 | 165 | foreach (CommonArchiverDllConfig config in Configs) { |
121 | 166 | try { |
122 | - return ExtractArchiveWith(arcFile, targetDir, config, output, hWnd); | |
167 | + ret = ExtractArchiveWith(arcFile, targetDir, config, output, hWnd); | |
168 | + if (ret == true) { | |
169 | + break; | |
170 | + } | |
171 | + } catch (CommonArchiverDllExtractionException) { | |
172 | + throw; | |
123 | 173 | } catch (DllNotFoundException) { |
124 | 174 | } catch (ApplicationException) { |
125 | 175 | } |
126 | 176 | } |
127 | - throw new DllNotFoundException("Not found dll matched for " + arcFile); | |
177 | + | |
178 | + return ret; | |
128 | 179 | } |
129 | 180 | |
130 | 181 | /// <summary> |
@@ -136,10 +187,10 @@ namespace NaGet.InteropServices | ||
136 | 187 | /// <param name="output">アーカイバDLLの展開時の標準出力を格納する</param> |
137 | 188 | /// <param name="hWnd">親フレーム</param> |
138 | 189 | /// <returns>アーカイバDLLの展開時のエラーコード(0なら正常終了)</returns> |
139 | - public static int ExtractArchiveWith(string arcFile, string targetDir, CommonArchiverDllConfig config, System.Text.StringBuilder output, IntPtr hWnd) | |
190 | + public static bool ExtractArchiveWith(string arcFile, string targetDir, CommonArchiverDllConfig config, System.Text.StringBuilder output, IntPtr hWnd) | |
140 | 191 | { |
141 | 192 | if (! File.Exists(arcFile) ) { |
142 | - throw new FileNotFoundException("File not found: ", arcFile); | |
193 | + throw new FileNotFoundException(string.Format("File not found: {0}", arcFile), arcFile); | |
143 | 194 | } |
144 | 195 | if (! Directory.Exists(targetDir)) { |
145 | 196 | throw new DirectoryNotFoundException("Directory not found: " + targetDir); |
@@ -160,7 +211,13 @@ namespace NaGet.InteropServices | ||
160 | 211 | } |
161 | 212 | |
162 | 213 | string cmdLine = string.Format(config.CmdLineFmt, arcFile, targetDir); |
163 | - return ExtractArchiveWith(config.DllName, config.CmdName, cmdLine, arcFile, output, hWnd); | |
214 | + int retVal = ExtractArchiveWith(config.DllName, config.CmdName, cmdLine, arcFile, output, hWnd); | |
215 | + if (retVal != 0) { | |
216 | + string errorMsg = string.Format("Extraction failure: {0}#{1}() returns {2}.", config.DllName, config.CmdName, retVal); | |
217 | + throw new CommonArchiverDllExtractionException(errorMsg, config.DllName, retVal); | |
218 | + } | |
219 | + | |
220 | + return true; | |
164 | 221 | } |
165 | 222 | |
166 | 223 | protected static int ExtractArchiveWith(string dllName, string cmdName, string cmdLine, string arcFile, System.Text.StringBuilder output, IntPtr hWnd) |
@@ -53,6 +53,8 @@ | ||
53 | 53 | </ItemGroup> |
54 | 54 | <ItemGroup> |
55 | 55 | <Compile Include="AssemblyInfo.cs" /> |
56 | + <Compile Include="NaGet.ArchiveExtractionHelpers\ArchiveExtract.cs" /> | |
57 | + <Compile Include="NaGet.ArchiveExtractionHelpers\SevenZipExtract.cs" /> | |
56 | 58 | <Compile Include="NaGet.InteropServices\ComDirectAccess.cs" /> |
57 | 59 | <Compile Include="NaGet.InteropServices\CommonArchiverExtracter.cs" /> |
58 | 60 | <Compile Include="NaGet.InteropServices\CreateProcessCaller.cs" /> |
@@ -99,6 +101,7 @@ | ||
99 | 101 | <Compile Include="NaGet.Packages.Install\InstalledPackage.cs" /> |
100 | 102 | </ItemGroup> |
101 | 103 | <ItemGroup> |
104 | + <Folder Include="NaGet.ArchiveExtractionHelpers" /> | |
102 | 105 | <Folder Include="NaGet.InteropServices" /> |
103 | 106 | <Folder Include="NaGet.SubCommands" /> |
104 | 107 | <Folder Include="NaGet.SubCommands.SubTask" /> |