OSDN Git Service

na-get-lib, 7-Zipがインストールされているならば 7z.exe で展開するコードを追加 (cab他対策)。 v1.4.4
authorttp <ttp@users.sourceforge.jp>
Mon, 21 Jul 2014 14:43:40 +0000 (23:43 +0900)
committerttp <ttp@users.sourceforge.jp>
Mon, 21 Jul 2014 14:43:40 +0000 (23:43 +0900)
archive-inst/Program.cs
na-get-lib/NaGet.ArchiveExtractionHelpers/ArchiveExtract.cs [new file with mode: 0644]
na-get-lib/NaGet.ArchiveExtractionHelpers/SevenZipExtract.cs [new file with mode: 0644]
na-get-lib/NaGet.InteropServices/CommonArchiverExtracter.cs
na-get-lib/na-get-lib.csproj

index 934a584..5b1cc24 100644 (file)
@@ -13,15 +13,6 @@ namespace ArchiveInstall
                \r
                public const string InstalledPackageFileName = ".applistation.package.xml";\r
                \r
                \r
                public const string InstalledPackageFileName = ".applistation.package.xml";\r
                \r
-               private static void extract(string arcFile, string extractDestDir)\r
-               {\r
-                       StringBuilder output = new StringBuilder(1024);\r
-                       int res = NaGet.InteropServices.CommonArchiverExtracter.ExtractArchive(arcFile, extractDestDir, output, IntPtr.Zero);\r
-                       if (res != 0) {\r
-                               Environment.Exit(res);\r
-                       }\r
-               }\r
-               \r
                private static void install(string fakeTargetDir, string targetDir)\r
                {\r
                        // ハッシュ比較\r
                private static void install(string fakeTargetDir, string targetDir)\r
                {\r
                        // ハッシュ比較\r
@@ -316,6 +307,8 @@ namespace ArchiveInstall
                                Console.WriteLine("\t{0} -i archive.zip PackageName\tInstall", executeFileName);\r
                                Console.WriteLine("\t{0} -x PackageName\t\tUninstall", executeFileName);\r
                                Console.WriteLine();\r
                                Console.WriteLine("\t{0} -i archive.zip PackageName\tInstall", executeFileName);\r
                                Console.WriteLine("\t{0} -x PackageName\t\tUninstall", executeFileName);\r
                                Console.WriteLine();\r
+                               \r
+                               Environment.ExitCode = 1;\r
                        }\r
 \r
                        // インストールおよび展開処理\r
                        }\r
 \r
                        // インストールおよび展開処理\r
@@ -330,7 +323,7 @@ namespace ArchiveInstall
                                                string destFile = Path.Combine(tempExtractDir, Path.GetFileName(arcFile));\r
                                                File.Copy(arcFile, destFile);\r
                                        } else {\r
                                                string destFile = Path.Combine(tempExtractDir, Path.GetFileName(arcFile));\r
                                                File.Copy(arcFile, destFile);\r
                                        } else {\r
-                                               extract(arcFile, tempExtractDir);\r
+                                               NaGet.ArchiveExtractionHelpers.ArchiveExtract.Extract(arcFile, tempExtractDir);\r
                                        }\r
                                        \r
                                        // インストールの元となるフォルダを決定する\r
                                        }\r
                                        \r
                                        // インストールの元となるフォルダを決定する\r
@@ -354,12 +347,18 @@ namespace ArchiveInstall
                                                // STEP5. パッケージ情報をインストール先(targetDir)に置く\r
                                                storePackageXml(package, targetDir);\r
                                        }\r
                                                // STEP5. パッケージ情報をインストール先(targetDir)に置く\r
                                                storePackageXml(package, targetDir);\r
                                        }\r
-                               } catch (DllNotFoundException) {\r
-                                       Console.Error.WriteLine("E: Does not exist archive dll for {0}", arcFile); // TODO\r
-                                       Environment.Exit(10);\r
+                               } catch (NaGet.InteropServices.CommonArchiverDllExtractionException e) {\r
+                                       Console.Error.WriteLine("E: Error: {0}", e.Message);\r
+                                       Environment.ExitCode = e.ReturnValue;\r
+                               } catch (NaGet.ArchiveExtractionHelpers.SevenZipExtractException e) {\r
+                                       Console.Error.WriteLine("E: Error: {0}", e.Message);\r
+                                       Environment.ExitCode = e.ReturnValue;\r
+                               } catch (ApplicationException e) {\r
+                                       Console.Error.WriteLine("E: Error: {0}", e.Message);\r
+                                       Environment.ExitCode = 1;\r
                                } catch (IOException e) {\r
                                        Console.Error.WriteLine("E: File I/O Error : {0}", e.Message);\r
                                } catch (IOException e) {\r
                                        Console.Error.WriteLine("E: File I/O Error : {0}", e.Message);\r
-                                       Environment.Exit(1);\r
+                                       Environment.ExitCode = 1;\r
                                } finally {\r
                                        Directory.Delete(tempExtractDir, true);\r
                                }\r
                                } finally {\r
                                        Directory.Delete(tempExtractDir, true);\r
                                }\r
diff --git a/na-get-lib/NaGet.ArchiveExtractionHelpers/ArchiveExtract.cs b/na-get-lib/NaGet.ArchiveExtractionHelpers/ArchiveExtract.cs
new file mode 100644 (file)
index 0000000..d868d79
--- /dev/null
@@ -0,0 +1,29 @@
+using System;
+using System.IO;
+using System.Text;
+
+namespace NaGet.ArchiveExtractionHelpers
+{
+       public class ArchiveExtract
+       {
+               private ArchiveExtract()
+               {
+               }
+               
+               public static bool Extract(string arcFile, string extractDestDir)
+               {
+                       bool ret = false;
+                       
+                       if (ret == false) {
+                               StringBuilder output = new StringBuilder(1024);
+                               ret = NaGet.InteropServices.CommonArchiverExtracter.ExtractArchive(arcFile, extractDestDir, output, IntPtr.Zero);
+                       }
+                       
+                       if (ret == false) {
+                               ret = SevenZipExtract.ExtractArchive(arcFile, extractDestDir);
+                       }
+                       
+                       return ret;
+               }
+       }
+}
diff --git a/na-get-lib/NaGet.ArchiveExtractionHelpers/SevenZipExtract.cs b/na-get-lib/NaGet.ArchiveExtractionHelpers/SevenZipExtract.cs
new file mode 100644 (file)
index 0000000..b3f6a84
--- /dev/null
@@ -0,0 +1,108 @@
+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;
+               }
+       }
+}
index 1d3d3c3..714d812 100644 (file)
@@ -36,6 +36,49 @@ namespace NaGet.InteropServices
        }\r
        \r
        /// <summary>\r
        }\r
        \r
        /// <summary>\r
+       /// アーカイバDLLを使った書庫展開のエラー\r
+       /// </summary>\r
+       public class CommonArchiverDllExtractionException : ApplicationException\r
+       {\r
+               /// <summary>\r
+               /// DLLファイル名\r
+               /// </summary>\r
+               private string dllName;\r
+               \r
+               /// <summary>\r
+               /// 戻り値\r
+               /// </summary>\r
+               private int returnValue;\r
+               \r
+               /// <summary>\r
+               /// アーカイバDLLを使った書庫展開のエラー\r
+               /// </summary>\r
+               /// <param name="message">メッセージ</param>\r
+               /// <param name="dllName">対象DLL名</param>\r
+               /// <param name="returnValue">戻り値</param>\r
+               public CommonArchiverDllExtractionException(string message, string dllName, int returnValue)\r
+                       : base(message)\r
+               {\r
+                       this.dllName = dllName;\r
+                       this.returnValue = returnValue;\r
+               }\r
+               \r
+               /// <summary>\r
+               /// DLLファイルの名称\r
+               /// </summary>\r
+               public string DllName {\r
+                       get { return dllName; }\r
+               }\r
+               \r
+               /// <summary>\r
+               /// 戻り値(非0)\r
+               /// </summary>\r
+               public int ReturnValue {\r
+                       get { return returnValue; }\r
+               }\r
+       }\r
+       \r
+       /// <summary>\r
        /// アーカイバDLLを使った書庫展開器\r
        /// </summary>\r
        public class CommonArchiverExtracter\r
        /// アーカイバDLLを使った書庫展開器\r
        /// </summary>\r
        public class CommonArchiverExtracter\r
@@ -114,17 +157,25 @@ namespace NaGet.InteropServices
                /// <param name="targetDir">展開先ディレクトリ</param>\r
                /// <param name="output">アーカイバDLLの展開時の標準出力を格納する</param>\r
                /// <param name="hWnd">親フレーム</param>\r
                /// <param name="targetDir">展開先ディレクトリ</param>\r
                /// <param name="output">アーカイバDLLの展開時の標準出力を格納する</param>\r
                /// <param name="hWnd">親フレーム</param>\r
-               /// <returns>ã\82¢ã\83¼ã\82«ã\82¤ã\83\90DLLã\81®å±\95é\96\8bæ\99\82ã\81®ã\82¨ã\83©ã\83¼ã\82³ã\83¼ã\83\89(0ã\81ªã\82\89正常çµ\82äº\86)</returns>\r
-               public static int ExtractArchive(string arcFile, string targetDir, System.Text.StringBuilder output, IntPtr hWnd)\r
+               /// <returns>ã\82¢ã\83¼ã\82«ã\82¤ã\83\90DLLã\81\8cè¦\8bã\81¤ã\81\8bã\81£ã\81¦æ­£ã\81\97ã\81\8få\87¦ç\90\86ã\81§ã\81\8dã\81\9fã\82\89trueã\80\81DLLã\81\8cè¦\8bã\81¤ã\81\8bã\82\89ã\81ªã\81\8bã\81£ã\81\9fã\82\89false</returns>\r
+               public static bool ExtractArchive(string arcFile, string targetDir, System.Text.StringBuilder output, IntPtr hWnd)\r
                {\r
                {\r
+                       bool ret = false;\r
+                       \r
                        foreach (CommonArchiverDllConfig config in Configs) {\r
                                try {\r
                        foreach (CommonArchiverDllConfig config in Configs) {\r
                                try {\r
-                                       return ExtractArchiveWith(arcFile, targetDir, config, output, hWnd);\r
+                                       ret = ExtractArchiveWith(arcFile, targetDir, config, output, hWnd);\r
+                                       if (ret == true) {\r
+                                               break;\r
+                                       }\r
+                               } catch (CommonArchiverDllExtractionException) {\r
+                                       throw;\r
                                } catch (DllNotFoundException) {\r
                                } catch (ApplicationException) {\r
                                }\r
                        }\r
                                } catch (DllNotFoundException) {\r
                                } catch (ApplicationException) {\r
                                }\r
                        }\r
-                       throw new DllNotFoundException("Not found dll matched for " + arcFile);\r
+                       \r
+                       return ret;\r
                }\r
                \r
                /// <summary>\r
                }\r
                \r
                /// <summary>\r
@@ -136,10 +187,10 @@ namespace NaGet.InteropServices
                /// <param name="output">アーカイバDLLの展開時の標準出力を格納する</param>\r
                /// <param name="hWnd">親フレーム</param>\r
                /// <returns>アーカイバDLLの展開時のエラーコード(0なら正常終了)</returns>\r
                /// <param name="output">アーカイバDLLの展開時の標準出力を格納する</param>\r
                /// <param name="hWnd">親フレーム</param>\r
                /// <returns>アーカイバDLLの展開時のエラーコード(0なら正常終了)</returns>\r
-               public static int ExtractArchiveWith(string arcFile, string targetDir, CommonArchiverDllConfig config, System.Text.StringBuilder output, IntPtr hWnd)\r
+               public static bool ExtractArchiveWith(string arcFile, string targetDir, CommonArchiverDllConfig config, System.Text.StringBuilder output, IntPtr hWnd)\r
                {\r
                        if (! File.Exists(arcFile) ) {\r
                {\r
                        if (! File.Exists(arcFile) ) {\r
-                               throw new FileNotFoundException("File not found: ", arcFile);\r
+                               throw new FileNotFoundException(string.Format("File not found: {0}", arcFile), arcFile);\r
                        }\r
                        if (! Directory.Exists(targetDir)) {\r
                                throw new DirectoryNotFoundException("Directory not found: " + targetDir);\r
                        }\r
                        if (! Directory.Exists(targetDir)) {\r
                                throw new DirectoryNotFoundException("Directory not found: " + targetDir);\r
@@ -160,7 +211,13 @@ namespace NaGet.InteropServices
                        }\r
                        \r
                        string cmdLine = string.Format(config.CmdLineFmt, arcFile, targetDir);\r
                        }\r
                        \r
                        string cmdLine = string.Format(config.CmdLineFmt, arcFile, targetDir);\r
-                       return ExtractArchiveWith(config.DllName, config.CmdName, cmdLine, arcFile, output, hWnd);\r
+                       int retVal = ExtractArchiveWith(config.DllName, config.CmdName, cmdLine, arcFile, output, hWnd);\r
+                       if (retVal != 0) {\r
+                               string errorMsg = string.Format("Extraction failure: {0}#{1}() returns {2}.", config.DllName, config.CmdName, retVal);\r
+                               throw new CommonArchiverDllExtractionException(errorMsg, config.DllName, retVal);\r
+                       }\r
+                       \r
+                       return true;\r
                }\r
                \r
                protected static int ExtractArchiveWith(string dllName, string cmdName, string cmdLine, string arcFile, System.Text.StringBuilder output, IntPtr hWnd)\r
                }\r
                \r
                protected static int ExtractArchiveWith(string dllName, string cmdName, string cmdLine, string arcFile, System.Text.StringBuilder output, IntPtr hWnd)\r
index 465bc5d..02993a8 100644 (file)
@@ -53,6 +53,8 @@
   </ItemGroup>\r
   <ItemGroup>\r
     <Compile Include="AssemblyInfo.cs" />\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Compile Include="AssemblyInfo.cs" />\r
+    <Compile Include="NaGet.ArchiveExtractionHelpers\ArchiveExtract.cs" />\r
+    <Compile Include="NaGet.ArchiveExtractionHelpers\SevenZipExtract.cs" />\r
     <Compile Include="NaGet.InteropServices\ComDirectAccess.cs" />\r
     <Compile Include="NaGet.InteropServices\CommonArchiverExtracter.cs" />\r
     <Compile Include="NaGet.InteropServices\CreateProcessCaller.cs" />\r
     <Compile Include="NaGet.InteropServices\ComDirectAccess.cs" />\r
     <Compile Include="NaGet.InteropServices\CommonArchiverExtracter.cs" />\r
     <Compile Include="NaGet.InteropServices\CreateProcessCaller.cs" />\r
     <Compile Include="NaGet.Packages.Install\InstalledPackage.cs" />\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Compile Include="NaGet.Packages.Install\InstalledPackage.cs" />\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <Folder Include="NaGet.ArchiveExtractionHelpers" />\r
     <Folder Include="NaGet.InteropServices" />\r
     <Folder Include="NaGet.SubCommands" />\r
     <Folder Include="NaGet.SubCommands.SubTask" />\r
     <Folder Include="NaGet.InteropServices" />\r
     <Folder Include="NaGet.SubCommands" />\r
     <Folder Include="NaGet.SubCommands.SubTask" />\r