+using System;
+using System.IO;
+using System.Diagnostics;
+
+namespace NaGet.ArchiveExtractionHelpers
+{
+ /// <summary>
+ /// 7zG.exe呼び出しによるアーカイブ展開のエラー
+ /// </summary>
+ public class SevenZipExtractException : ApplicationException {
+ /// <summary>
+ /// 戻り値
+ /// </summary>
+ private int returnValue;
+
+ /// <summary>
+ /// 7z.exe呼び出しによるアーカイブ展開のエラー
+ /// </summary>
+ /// <param name="message">メッセージ</param>
+ /// <param name="dllName">対象DLL名</param>
+ /// <param name="returnValue">戻り値</param>
+ public SevenZipExtractException(string message, int returnValue)
+ : base(message)
+ {
+ this.returnValue = returnValue;
+ }
+
+ /// <summary>
+ /// 戻り値(非0)
+ /// </summary>
+ public int ReturnValue {
+ get { return returnValue; }
+ }
+ }
+
+ /// <summary>
+ /// 7zG.exe呼び出しによるアーカイブ展開
+ /// </summary>
+ public class SevenZipExtract
+ {
+ /// <summary>
+ /// 7zG.exeのパスを返す
+ /// </summary>
+ private static string SevenZipExeFilePath {
+ get {
+ string subPath = Path.Combine("7-Zip", "7zG.exe");
+ string path = null;
+
+ if (! string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ProgramFiles"))) {
+ string programFiles = Environment.GetEnvironmentVariable("ProgramFiles");
+ if (File.Exists(Path.Combine(programFiles, subPath))) {
+ path = Path.Combine(programFiles, subPath);
+ } else if (programFiles.EndsWith(" (x86)")) {
+ // WOW64対策として手動で" (x86)"を抜く
+ programFiles = programFiles.Substring(0, programFiles.Length - " (x86)".Length);
+ if (File.Exists(Path.Combine(programFiles, subPath))) {
+ path = Path.Combine(programFiles, subPath);
+ }
+ }
+ } else if (! string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ProgramFiles(x86)"))) {
+ string programFiles = Environment.GetEnvironmentVariable("ProgramFiles(x86)");
+ if (File.Exists(Path.Combine(programFiles, subPath))) {
+ path = Path.Combine(programFiles, subPath);
+ }
+ }
+ return path;
+ }
+ }
+
+ /// <summary>
+ /// アーカイブを展開する。
+ /// </summary>
+ /// <param name="arcFile">アーカイブのパス</param>
+ /// <param name="targetDir">展開先ディレクトリ</param>
+ /// <param name="output">アーカイバの展開時の標準出力を格納する</param>
+ /// <returns>7zG.exe が見つかって正しく処理できたらtrue、7zG.exe が見つからなかったらfalse</returns>
+ public static bool ExtractArchive(string arcFile, string targetDir)
+ {
+ bool retVal = false;
+
+ if (! string.IsNullOrEmpty(SevenZipExeFilePath)) {
+
+ if (Directory.Exists(targetDir)) {
+ NaGet.Utils.SetAttributeRecursive(targetDir, FileAttributes.Normal);
+ Directory.Delete(targetDir, true);
+ }
+ Directory.CreateDirectory(targetDir);
+
+ ProcessStartInfo procInfo = new ProcessStartInfo();
+ procInfo.FileName = SevenZipExeFilePath;
+ procInfo.Arguments = string.Format("x \"{0}\" -o\"{1}\"", arcFile, targetDir);
+ procInfo.WorkingDirectory = targetDir;
+ //procInfo.WindowStyle = ProcessWindowStyle.Hidden;
+
+ Process hProcess = Process.Start(procInfo);
+ hProcess.WaitForExit();
+ if (hProcess.ExitCode == 0) {
+ retVal = true;
+ } else {
+ string errorMsg = string.Format("Extraction failure: \"{0}\" returns {1}.", SevenZipExeFilePath, hProcess.ExitCode);
+ throw new SevenZipExtractException(errorMsg, hProcess.ExitCode);
+ }
+ }
+
+ return retVal;
+ }
+ }
+}