2 using System.Collections.Generic;
3 using System.Collections.ObjectModel;
5 using NaGet.Packages.Install;
6 using NaGet.SubCommands;
7 using NaGet.SubCommands.SubTask;
9 using NaGet.InteropServices;
11 namespace NaGet.SubCommands
16 public class NaGetInstall2 : NaGetTaskSet2
18 private IList<Installation> installations;
20 private DownloadScannerService scanner;
22 private PackageListsManager pkgListMan;
27 /// <param name="pkgs">インストールするパッケージ</param>
28 public NaGetInstall2(PackageListsManager pkgListMan, Package[] pkgs)
29 : this(pkgListMan, Installation.ConvertInstallations(pkgs))
36 /// <param name="installations">インストール処理の配列</param>
37 public NaGetInstall2(PackageListsManager pkgMan, IList<Installation> insts)
40 installations = new ReadOnlyCollection<Installation>(insts);
42 scanner = new DownloadScannerService();
48 private void initializeSubTasks()
52 registSubTask("セキュリティプロトコル設定の確認",
53 new SecurityProtocolConfigSubTask());
54 foreach (Installation inst in installations) {
55 VirusScanSubTask scanSTask = new VirusScanSubTask(scanner, inst.InstallerFile, inst.InstallerURL);
57 if (! inst.Downloaded) {
58 DownloadSubTask dlSTask = new DownloadSubTask(inst.InstallerURL, inst.InstallerFile);
60 dlSTask.EnableChangeFileName = true;
61 dlSTask.TaskEventRaised += delegate(object sender, TaskEventArgs e) {
62 if (e.Type == TaskEventType.COMPLETED) {
63 scanSTask.TargetFilePath = inst.InstallerFile = dlSTask.Filepath;
67 registSubTask(string.Format("ダウンロード: {0}", inst),
70 registSubTask(string.Format("ウイルススキャン: {0}", inst),
73 registSubTask("インストーラーの検証",
74 new VerifyInstallerFileSubTask(installations));
75 foreach (Installation inst in installations) {
76 bool isSilentInstall = (inst.Silent && inst.IsSupportsSilent);
77 string msg = string.Format("インストール: {0}{1}",
79 (isSilentInstall)? " (サイレントインストール)" : string.Empty);
81 new FunctionalSubTask<Installation>(runInstall, inst));
83 registSubTask("インストール済みのソフトリスト更新",
84 new LocalUpdateSubTask(pkgListMan));
87 public override void Run()
90 RaiseTaskSetEvent(TaskEventType.STARTED, string.Empty);
93 while (hasMoreSubTask) {
94 bool canGoToNextSubTask = true;
96 RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, currentSubTaskName);
98 RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, currentSubTaskName);
100 if (runCheckVerify() == false) {
101 canGoToNextSubTask = false;
102 initializeSubTasks();
103 NotifyGoToSubTask(0); // 最初からやり直し。
106 throw new TaskCanceledException("cancel is called");
109 if (canGoToNextSubTask) {
110 NotifyGoToNextSubTask();
113 } catch (TaskCanceledException) {
115 } catch (Exception e) {
116 RaiseTaskSetEvent(TaskEventType.ERROR, e.Message);
121 RaiseTaskSetEvent(TaskEventType.CANCELED, "キャンセルされました");
124 RaiseTaskSetEvent(TaskEventType.COMPLETED, string.Empty);
128 private bool runCheckVerify()
132 if (currentSubTask is VerifyInstallerFileSubTask) {
133 VerifyInstallerFileSubTask verifySTask = currentSubTask as VerifyInstallerFileSubTask;
134 if (verifySTask.InvalidInstallers != null && verifySTask.InvalidInstallers.Count > 0) {
135 System.Text.StringBuilder invalidInstallerNames = new System.Text.StringBuilder();
136 foreach (Installation invalidInst in verifySTask.InvalidInstallers) {
137 invalidInstallerNames.AppendFormat(" - {0}\n", invalidInst.ToString());
140 string msg = string.Format("以下の{0}個のパッケージでファイルが壊れている可能性があります。\n{1}\n強制的にインストールを続行しますか?",
141 verifySTask.InvalidInstallers.Count, invalidInstallerNames.ToString());
142 NaGetTaskQueryResult result = NaGetTaskQueryResult.CANCEL;
145 result = RaiseTaskSetQueryEvent(msg, NaGetTaskQueryResult.CONTINUE
146 | NaGetTaskQueryResult.RETRY
147 | NaGetTaskQueryResult.CANCEL);
151 case NaGetTaskQueryResult.CONTINUE:
152 RaiseTaskSetEvent(TaskEventType.WARNING, "ハッシュの非整合を無視してインストールを継続");
155 case NaGetTaskQueryResult.RETRY:
156 RaiseTaskSetEvent(TaskEventType.INFO, "ダウンロード処理を再試行");
158 foreach (Installation invalidInst in verifySTask.InvalidInstallers) {
159 invalidInst.RemoveDownloadedFile();
163 case NaGetTaskQueryResult.CANCEL:
164 case NaGetTaskQueryResult.CANCELED_AUTOMATICALLY:
167 throw new TaskCanceledException("処理の継続のキャンセルが選択されました");
175 private void runInstall(Installation inst)
177 if (! inst.IsInstallablePackage()) {
178 string msg = string.Format("{0}はインストールすることができません", inst.ToString());
179 throw new ApplicationException(msg);
182 inst.ErrorDataReceived += this.ReceivedErrorData;
183 inst.OutputDataReceived += this.ReceivedOutputData;
184 int exitCode = inst.Install();
186 RaiseTaskSetEvent(TaskEventType.WARNING, "インストールが正常に終えていない可能性があります。プロセスの終了コード:"+exitCode);
189 pkgListMan.WriteInstallationLog(inst);
192 public override bool Cancelable {
194 return !cancelCalled && Running && isDuringDownloading;
198 private bool isDuringDownloading {
200 return Running && (currentSubTask is DownloadSubTask);