OSDN Git Service

na-get-lib,不使用メソッドの削除
[applistation/AppliStation.git] / na-get-lib / NaGet.Packages.Install / Installation.cs
index f8ab19d..1102ea2 100644 (file)
@@ -23,13 +23,13 @@ namespace NaGet.Packages.Install
                        set {\r
                                installedPackage = value;\r
                                \r
+                               installerIndex = getPreferInstallerIndex(value);\r
                                installerFile = getArchiveFilePath();\r
-                               installerIndex = GetPreferInstallerIndex(value);\r
                        }\r
                }\r
 \r
                /// <summary>\r
-               /// (保存される)インストーラのファイルのパス\r
+               /// (ä¿\9då­\98ã\81\95ã\82\8cã\82\8b\83¼ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\81®ã\83\95ã\82¡ã\82¤ã\83«ã\81®ã\83\91ã\82¹\r
                /// </summary>\r
                private string installerFile;\r
 \r
@@ -44,7 +44,7 @@ namespace NaGet.Packages.Install
                private bool silent = false;\r
          \r
                /// <summary>\r
-               /// 起動するインストーラのインデックス番号\r
+               /// èµ·å\8b\95ã\81\99ã\82\8bã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\83¼ã\81®ã\82¤ã\83³ã\83\87ã\83\83ã\82¯ã\82¹ç\95ªå\8f·\r
                /// </summary>\r
                protected int installerIndex = 0;\r
                \r
@@ -75,14 +75,14 @@ namespace NaGet.Packages.Install
                }\r
                \r
                /// <summary>\r
-               /// インストーラファイルを取得する\r
+               /// ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\83¼ã\83\95ã\82¡ã\82¤ã\83«ã\82\92å\8f\96å¾\97ã\81\99ã\82\8b\r
                /// </summary>\r
                public string InstallerFile {\r
                        get { return installerFile; }\r
                }\r
                \r
                \r
-               #region ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©状態チェック関連\r
+               #region ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83«状態チェック関連\r
                \r
                /// <summary>\r
                /// インストール可能か否か\r
@@ -109,12 +109,15 @@ namespace NaGet.Packages.Install
                }\r
                \r
                /// <summary>\r
-               /// インストーラの処理が成功してインストールされたプログラムが確認できるか否か。\r
+               /// ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\83¼ã\81®å\87¦ç\90\86ã\81\8cæ\88\90å\8a\9fã\81\97ã\81¦ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83«ã\81\95ã\82\8cã\81\9fã\83\97ã\83­ã\82°ã\83©ã\83 ã\81\8c確èª\8dã\81§ã\81\8dã\82\8bã\81\8bå\90¦ã\81\8bã\80\82\r
                /// </summary>\r
                public bool InstallSuccessed {\r
                        get {\r
                                switch (InstalledPackage.Type) {\r
-                                       case InstallerType.ARCHIVE: // アーカイブインストーラはフォルダの確認\r
+                                       case InstallerType.ARCHIVE:\r
+                                       case InstallerType.ITSELF:\r
+                                               // アーカイブインストーラーおよび配布exeそれ自身が実行ファイルのとき、\r
+                                               // (AppliStationの作る)プログラムフォルダーの存在のみで確認を行う。\r
                                                return Directory.Exists(Path.Combine(NaGet.Env.ArchiveProgramFiles, InstalledPackage.Name));\r
                                        case InstallerType.EXEC_INSTALLER:\r
                                        case InstallerType.MSI_PACKAGE:\r
@@ -144,6 +147,7 @@ namespace NaGet.Packages.Install
                        get {\r
                                switch (InstalledPackage.Type) {\r
                                        case InstallerType.ARCHIVE:\r
+                                       case InstallerType.ITSELF:\r
                                        case InstallerType.MSI_PACKAGE:\r
                                                return true;\r
                                        case InstallerType.EXEC_INSTALLER:\r
@@ -158,7 +162,10 @@ namespace NaGet.Packages.Install
                /// サイレントインストールだけをサポートしているか否か\r
                /// </summary>\r
                public bool SupportsSilentOnly {\r
-                       get { return InstalledPackage.Type == InstallerType.ARCHIVE; }\r
+                       get {\r
+                               return (InstalledPackage.Type == InstallerType.ARCHIVE)\r
+                                       || (InstalledPackage.Type == InstallerType.ITSELF);\r
+                       }\r
                }\r
                \r
                /// <summary>\r
@@ -166,7 +173,10 @@ namespace NaGet.Packages.Install
                /// </summary>\r
                /// <remark>RunAsが必要か否かの判断にしようされる</remark>\r
                public bool TargetPC {\r
-                       get { return InstalledPackage.Type != InstallerType.ARCHIVE; }\r
+                       get {\r
+                               return (InstalledPackage.Type != InstallerType.ARCHIVE)\r
+                                       && (InstalledPackage.Type != InstallerType.ITSELF);\r
+                       }\r
                }\r
                \r
                #endregion\r
@@ -187,31 +197,38 @@ namespace NaGet.Packages.Install
                                        File.Move(installerFile, newFile);\r
                                        installerFile = newFile;\r
                                }\r
+                               \r
+                               // 権限を親フォルダーに落とす\r
+                               try {\r
+                                       string targetDir = Path.GetDirectoryName(installerFile);\r
+                                       NaGet.Utils.SetAccessControlRecursive(targetDir, File.GetAccessControl(Path.GetDirectoryName(targetDir)));\r
+                               } catch (Exception) {} // 失敗時は何もしない\r
                        }\r
                }\r
                \r
                /// <summary>\r
-               /// インストーラファイルをスキャンする\r
+               /// ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\83¼ã\83\95ã\82¡ã\82¤ã\83«ã\82\92ã\82¹ã\82­ã\83£ã\83³ã\81\99ã\82\8b\r
                /// </summary>\r
                /// <remarks>ウイルスのため退避・削除されたときも例外を投げずにあたかも正常かのように動作しえます。</remarks>\r
                /// <exception cref="ComException">スキャンで意図せぬ動作があったとき</exception>\r
-               /// <exception cref="FileNotFoundException">スキャン後にインストーラファイルが存在しないとき</exception>\r
                /// <param name="scanner">スキャナーオブジェクト</param>\r
-               public void ScanInstallerFile(DownloadScanner scanner)\r
+               /// <returns>スキャン結果</returns>\r
+               public DownloadScannerResult ScanInstallerFile(DownloadScanner scanner)\r
                {\r
+                       DownloadScannerResult result;\r
                        Exception e = null;\r
                        try {\r
-                               scanner.Scan(installerFile, InstalledPackage.Installer[installerIndex].Url.Href);\r
-                       } catch (System.Runtime.InteropServices.COMException ex) {\r
+                               result = scanner.Scan(installerFile, InstalledPackage.Installer[installerIndex].Url.Href);\r
+                       } catch (Exception ex) {\r
+                               result = DownloadScannerResult.ScannerNotFound;\r
                                e = ex;\r
                        }\r
                        \r
-                       if (! File.Exists(installerFile)) {\r
-                               // ファイルが消されているならばFileNotFoundExceptionを出す\r
-                               throw new FileNotFoundException(string.Empty, installerFile, e);\r
-                       } else if ( e != null ) {\r
+                       if ( e != null ) {\r
                                // ファイルが消されていないが例外が発生していたときは、その例外を投げる\r
                                throw e;\r
+                       } else {\r
+                               return result;\r
                        }\r
                }\r
                \r
@@ -268,14 +285,23 @@ namespace NaGet.Packages.Install
                                        hProcess = Process.Start("msiexec", msiexecArgs);\r
                                        break;\r
                                case InstallerType.ARCHIVE:\r
+                               case InstallerType.ITSELF:\r
                                        string argument = string.Format("-i \"{0}\" \"{1}\"", installerfile, this.InstalledPackage.Name);\r
                                        hProcess = createExtractArchiveProcess(argument,\r
                                                                               this.OutputDataReceived,\r
                                                                               this.ErrorDataReceived);\r
+                                       // Note: ARCHIVEかITSELFの判断はarchive-instが行う\r
                                        break;\r
                                default:\r
                                        throw new NotImplementedException("Not implemented archive installation yet");\r
                                }\r
+                               \r
+                               if (NaGet.Env.InstallProcessOnBackground) {\r
+                                       try {\r
+                                               hProcess.PriorityClass = ProcessPriorityClass.Idle;\r
+                                       } catch (Exception) {}\r
+                               }\r
+                               \r
                                hProcess.WaitForExit();\r
                                \r
                                return hProcess.ExitCode;\r
@@ -287,9 +313,9 @@ namespace NaGet.Packages.Install
                }\r
                \r
                /// <summary>\r
-               /// インストーラ等を起動してインストール作業を行う\r
+               /// インストーラ等を起動してインストール作業を行う\r
                /// </summary>\r
-               /// <returns>インストーラの終了コード</returns>\r
+               /// <returns>ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\83¼ã\81®çµ\82äº\86ã\82³ã\83¼ã\83\89</returns>\r
                public int Install()\r
                {\r
                        string installerFile = this.installerFile;\r
@@ -303,6 +329,12 @@ namespace NaGet.Packages.Install
                                using (Process hProcess = createExtractArchiveProcess(argument,\r
                                                                                      this.OutputDataReceived,\r
                                                                                      this.ErrorDataReceived)) {\r
+                                       if (NaGet.Env.InstallProcessOnBackground) {\r
+                                               try {\r
+                                                       hProcess.PriorityClass = ProcessPriorityClass.Idle;\r
+                                               } catch (Exception) {}\r
+                                       }\r
+                                       \r
                                        hProcess.WaitForExit();\r
                                \r
                                        if (hProcess.ExitCode != 0) {\r
@@ -323,11 +355,13 @@ namespace NaGet.Packages.Install
                        return exitCode;\r
                }\r
                \r
+               #region インストーラーファイル設定時の処理\r
+               \r
                /// <summary>\r
-               /// もっともふさわしいインストーラ番号を返す\r
+               /// もっともふさわしいインストーラ番号を返す\r
                /// </summary>\r
                /// <returns></returns>\r
-               public static int GetPreferInstallerIndex(Package InstalledPackage)\r
+               private static int getPreferInstallerIndex(Package InstalledPackage)\r
                {\r
                        if (InstalledPackage.Type == InstallerType.CANNOT_INSTALL) { // インストール不能パッケージ\r
                                return -1;\r
@@ -356,16 +390,18 @@ namespace NaGet.Packages.Install
                }\r
                \r
                /// <summary>\r
-               /// ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\81®ä¸\80æ\99\82保存先パスを生成\r
+               /// ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\83¼ã\81®保存先パスを生成\r
                /// </summary>\r
+               /// <remarks>installerIndexが求まっているものとして仮定して処理する</remarks>\r
                private string getArchiveFilePath()\r
                {\r
                        Package package = this.InstalledPackage;\r
                        \r
                        string folderName = string.Format("{0}({1})", package.Name, package.Version);\r
-                       string fileName = NaGet.Utils.Url2filename(package.Installer[0].Url.Href);\r
+                       string subFolderName = string.Format("installer.{0}", (installerIndex >= 0)? installerIndex.ToString("D") : "X");\r
+                       string fileName = NaGet.Utils.Url2filename(new Uri(package.Installer[0].Url.Href));\r
                        \r
-                       string folder = Path.Combine(NaGet.Env.ArchiveFolderPath, folderName);\r
+                       string folder = Path.Combine(NaGet.Env.ArchiveFolderPath, Path.Combine(folderName, subFolderName));\r
                        \r
                        if (! File.Exists(Path.Combine(folder, fileName))) {\r
                                if (Directory.Exists(folder)) {\r
@@ -374,32 +410,25 @@ namespace NaGet.Packages.Install
                                        }\r
                                } else {\r
                                        Directory.CreateDirectory(folder);\r
+                                       \r
+                                       // 権限を親フォルダーに合わせる\r
+                                       try {\r
+                                               Directory.SetAccessControl(folder, Directory.GetAccessControl(Path.GetDirectoryName(folder)));\r
+                                       } catch (Exception) {} // 失敗時無視\r
                                }\r
                        }\r
                        \r
                        return Path.Combine(folder, fileName);\r
                }\r
                \r
+               #endregion\r
+                               \r
                /// <summary>\r
-               /// すでにインストールされているパッケージを取得する\r
-               /// </summary>\r
-               /// <param name="installedPkgs">\r
-               /// インストールドリスト\r
-               /// </param>\r
-               /// <returns>\r
-               /// インストールされているパッケージの情報。インストールされたパッケージが見つからないならばnullを返す  \r
-               /// </returns>\r
-               public InstalledPackage GetInstalledPackage(PackageList<InstalledPackage> installedPkgs)\r
-               {\r
-                       return installedPkgs.GetPackageForName(InstalledPackage.Name);\r
-               }\r
-               \r
-               /// <summary>\r
-               /// インストーラファイルを探す\r
+               /// インストーラーファイルを探す\r
                /// </summary>\r
-               /// <param name="basedir">探すフォルダ</param>\r
-               /// <param name="type">インストーラの種類</param>\r
-               /// <returns>探し出されたインストーラファイルのフルパス。存在しないならばnull</returns>\r
+               /// <param name="basedir">探すフォルダ</param>\r
+               /// <param name="type">ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\83¼ã\81®ç¨®é¡\9e</param>\r
+               /// <returns>æ\8e¢ã\81\97å\87ºã\81\95ã\82\8cã\81\9fã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\83¼ã\83\95ã\82¡ã\82¤ã\83«ã\81®ã\83\95ã\83«ã\83\91ã\82¹ã\80\82å­\98å\9c¨ã\81\97ã\81ªã\81\84ã\81ªã\82\89ã\81°null</returns>\r
                private static string seekInstallerFile(string basedir, InstallerType type)\r
                {\r
                        if (! Directory.Exists(basedir)) {\r
@@ -421,6 +450,9 @@ namespace NaGet.Packages.Install
                                        list.AddRange(Directory.GetFiles(basedir, "*.7z"));\r
                                        list.AddRange(Directory.GetFiles(basedir, "*.tar*"));\r
                                        break;\r
+                               case InstallerType.ITSELF:\r
+                                       list.AddRange(Directory.GetFiles(basedir, "*.exe"));\r
+                                       break;\r
                                default:\r
                                        return null;\r
                        }\r
@@ -451,7 +483,7 @@ namespace NaGet.Packages.Install
                /// <param name="outputReceived">標準出力用リスナ(null可)</param>\r
                /// <param name="errorReceived">エラー出力用リスナ(null可)</param>\r
                /// <returns>実行プロセス</returns>\r
-               private Process createExtractArchiveProcess(string archiveInstArgs,\r
+               private static Process createExtractArchiveProcess(string archiveInstArgs,\r
                                                  EventHandler<NaGet.Utils.AnyDataEventArgs<string>> outputReceived,\r
                                                  EventHandler<NaGet.Utils.AnyDataEventArgs<string>> errorReceived)\r
                {\r
@@ -462,6 +494,8 @@ namespace NaGet.Packages.Install
                                                               new FileNotFoundException(errMsg, archiveInstExe));\r
                        }\r
                        \r
+                       \r
+                       \r
                        ProcessStartInfo procInfo = new ProcessStartInfo(archiveInstExe, archiveInstArgs);\r
                        procInfo.UseShellExecute = false;\r
                        procInfo.CreateNoWindow = true;\r
@@ -494,6 +528,8 @@ namespace NaGet.Packages.Install
                        return string.Join(" ", strs);\r
                }\r
                \r
+               #region 便利メソッド群\r
+               \r
                /// <summary>\r
                /// パッケージ配列をインストール処理配列に変換する便利メソッド\r
                /// </summary>\r
@@ -507,5 +543,18 @@ namespace NaGet.Packages.Install
                        }\r
                        return insts;\r
                }\r
+               \r
+               /// <summary>\r
+               /// パッケージがインストール可能かを戻します。\r
+               /// </summary>\r
+               /// <param name="pkg">検査対象のパッケージ</param>\r
+               /// <returns>インストール可能か否か</returns>\r
+               public static bool IsInstallablePackage(Package pkg)\r
+               {\r
+                       int installerIndex = getPreferInstallerIndex(pkg);\r
+                       return installerIndex >= 0;\r
+               }\r
+               \r
+               #endregion\r
        }\r
 }\r