2 using System.Collections.Generic;
4 using NaGet.Packages.Install;
5 using NaGet.SubCommands;
6 using NaGet.SubCommands.SubTask;
8 using NaGet.InteropServices;
10 namespace NaGet.SubCommands
15 public class NaGetInstall2 : NaGetTaskSet2
17 private IList<Installation> installations;
19 private DownloadScannerService scanner;
21 private PackageListsManager pkgListMan;
26 /// <param name="pkgs">インストールするパッケージ</param>
27 public NaGetInstall2(PackageListsManager pkgListMan, Package[] pkgs)
28 : this(pkgListMan, Installation.ConvertInstallations(pkgs))
35 /// <param name="installations">インストール処理の配列</param>
36 public NaGetInstall2(PackageListsManager pkgMan, IList<Installation> insts)
39 installations = insts;
41 scanner = new DownloadScannerService();
47 private void initializeSubTasks()
51 foreach (Installation inst in installations) {
52 VirusScanSubTask scanSTask = new VirusScanSubTask(scanner, inst.InstallerFile, inst.InstallerURL);
54 if (! inst.Downloaded) {
55 DownloadSubTask dlSTask = new DownloadSubTask(inst.InstallerURL, inst.InstallerFile);
57 dlSTask.EnableChangeFileName = true;
58 dlSTask.TaskEventRaised += delegate(object sender, TaskEventArgs e) {
59 if (e.Type == TaskEventType.COMPLETED) {
60 scanSTask.TargetFilePath = inst.InstallerFile = dlSTask.Filepath;
64 registSubTask(string.Format("ダウンロード: {0}", inst),
67 registSubTask(string.Format("ウイルススキャン: {0}", inst),
70 registSubTask("インストーラーの検証",
71 new VerifyInstallerFileSubTask(installations));
72 foreach (Installation inst in installations) {
73 bool isSilentInstall = (inst.Silent && inst.IsSupportsSilent);
74 string msg = string.Format("インストール: {0}{1}",
76 (isSilentInstall)? " (サイレントインストール)" : string.Empty);
78 new FunctionalSubTask<Installation>(runInstall, inst));
80 registSubTask("インストール済みのソフトリスト更新",
81 new LocalUpdateSubTask(pkgListMan));
84 public override void Run()
87 RaiseTaskSetEvent(TaskEventType.STARTED, string.Empty);
90 while (hasMoreSubTask) {
91 bool canGoToNextSubTask = true;
93 RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, currentSubTaskName);
95 RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, currentSubTaskName);
97 if (runCheckVerify() == false) {
98 canGoToNextSubTask = false;
100 NotifyGoToSubTask(0); // 最初からやり直し。
103 throw new TaskCanceledException("cancel is called");
106 if (canGoToNextSubTask) {
107 NotifyGoToNextSubTask();
110 } catch (TaskCanceledException) {
112 } catch (Exception e) {
113 RaiseTaskSetEvent(TaskEventType.ERROR, e.Message);
118 RaiseTaskSetEvent(TaskEventType.CANCELED, "キャンセルされました");
121 RaiseTaskSetEvent(TaskEventType.COMPLETED, string.Empty);
125 private bool runCheckVerify()
129 if (currentSubTask is VerifyInstallerFileSubTask) {
130 VerifyInstallerFileSubTask verifySTask = currentSubTask as VerifyInstallerFileSubTask;
131 if (verifySTask.InvalidInstallers != null && verifySTask.InvalidInstallers.Count > 0) {
132 System.Text.StringBuilder invalidInstallerNames = new System.Text.StringBuilder();
133 foreach (Installation invalidInst in verifySTask.InvalidInstallers) {
134 invalidInstallerNames.AppendFormat(" - {0}\n", invalidInst.ToString());
137 string msg = string.Format("以下の{0}個のパッケージでファイルが壊れている可能性があります。\n{1}\n強制的にインストールを続行しますか?",
138 verifySTask.InvalidInstallers.Count, invalidInstallerNames.ToString());
139 NaGetTaskQueryResult result = NaGetTaskQueryResult.CANCEL;
142 result = RaiseTaskSetQueryEvent(msg, NaGetTaskQueryResult.CONTINUE
143 | NaGetTaskQueryResult.RETRY
144 | NaGetTaskQueryResult.CANCEL);
148 case NaGetTaskQueryResult.CONTINUE:
149 RaiseTaskSetEvent(TaskEventType.WARNING, "ハッシュの非整合を無視してインストールを継続");
152 case NaGetTaskQueryResult.RETRY:
153 RaiseTaskSetEvent(TaskEventType.INFO, "ダウンロード処理を再試行");
155 foreach (Installation invalidInst in verifySTask.InvalidInstallers) {
156 invalidInst.RemoveDownloadedFile();
160 case NaGetTaskQueryResult.CANCEL:
161 case NaGetTaskQueryResult.CANCELED_AUTOMATICALLY:
164 throw new TaskCanceledException("処理の継続のキャンセルが選択されました");
172 private void runInstall(Installation inst)
174 if (! inst.IsInstallablePackage()) {
175 string msg = string.Format("{0}はインストールすることができません", inst.ToString());
176 throw new ApplicationException(msg);
179 inst.ErrorDataReceived += this.ReceivedErrorData;
180 inst.OutputDataReceived += this.ReceivedOutputData;
181 int exitCode = inst.Install();
183 RaiseTaskSetEvent(TaskEventType.WARNING, "インストールが正常に終えていない可能性があります。プロセスの終了コード:"+exitCode);
186 pkgListMan.WriteInstallationLog(inst);
189 public override bool Cancelable {
191 return !cancelCalled && Running && isDuringDownloading;
195 private bool isDuringDownloading {
197 return Running && (currentSubTask is DownloadSubTask);