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.TaskEventRaised += delegate(object sender, TaskEventArgs e) {
58 if (e.Type == TaskEventType.COMPLETED) {
59 scanSTask.TargetFilePath = inst.InstallerFile;
63 registSubTask(string.Format("ダウンロード: {0}", inst),
66 registSubTask(string.Format("ウイルススキャン: {0}", inst),
69 registSubTask("インストーラーの検証",
70 new VerifyInstallerFileSubTask(installations));
71 foreach (Installation inst in installations) {
72 bool isSilentInstall = (inst.Silent && inst.IsSupportsSilent);
73 string msg = string.Format("インストール: {0}{1}",
75 (isSilentInstall)? " (サイレントインストール)" : string.Empty);
77 new FunctionalSubTask(runInstall, inst));
79 registSubTask("インストール済みのソフトリスト更新",
80 new LocalUpdateSubTask(pkgListMan));
83 public override void Run()
86 RaiseTaskSetEvent(TaskEventType.STARTED, string.Empty);
89 while (hasMoreSubTask) {
90 bool canGoToNextSubTask = true;
92 RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, currentSubTaskName);
94 RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, currentSubTaskName);
96 if (runCheckVerify() == false) {
97 canGoToNextSubTask = false;
99 NotifyGoToSubTask(0); // 最初からやり直し。
102 throw new TaskCanceledException("cancel is called");
105 if (canGoToNextSubTask) {
106 NotifyGoToNextSubTask();
109 } catch (TaskCanceledException) {
111 } catch (Exception e) {
112 RaiseTaskSetEvent(TaskEventType.ERROR, e.Message);
117 RaiseTaskSetEvent(TaskEventType.CANCELED, "キャンセルされました");
120 RaiseTaskSetEvent(TaskEventType.COMPLETED, string.Empty);
124 private bool runCheckVerify()
128 if (currentSubTask is VerifyInstallerFileSubTask) {
129 VerifyInstallerFileSubTask verifySTask = currentSubTask as VerifyInstallerFileSubTask;
130 if (verifySTask.InvalidInstallers != null && verifySTask.InvalidInstallers.Count > 0) {
131 System.Text.StringBuilder invalidInstallerNames = new System.Text.StringBuilder();
132 foreach (Installation invalidInst in verifySTask.InvalidInstallers) {
133 invalidInstallerNames.AppendFormat(" - {0}\n", invalidInst.ToString());
136 string msg = string.Format("以下の{0}個のパッケージでファイルが壊れている可能性があります。\n{1}\n強制的にインストールを続行しますか?",
137 verifySTask.InvalidInstallers.Count, invalidInstallerNames.ToString());
138 NaGetTaskQueryResult result = NaGetTaskQueryResult.CANCEL;
141 result = RaiseTaskSetQueryEvent(msg, NaGetTaskQueryResult.CONTINUE
142 | NaGetTaskQueryResult.RETRY
143 | NaGetTaskQueryResult.CANCEL);
147 case NaGetTaskQueryResult.CONTINUE:
148 RaiseTaskSetEvent(TaskEventType.WARNING, "ハッシュの非整合を無視してインストールを継続");
151 case NaGetTaskQueryResult.RETRY:
152 RaiseTaskSetEvent(TaskEventType.INFO, "ダウンロード処理を再試行");
154 foreach (Installation invalidInst in verifySTask.InvalidInstallers) {
155 invalidInst.RemoveDownloadedFile();
159 case NaGetTaskQueryResult.CANCEL:
160 case NaGetTaskQueryResult.CANCELED_AUTOMATICALLY:
163 throw new TaskCanceledException("処理の継続のキャンセルが選択されました");
171 private void runInstall(object uninstObj)
173 Installation inst = (Installation) uninstObj;
175 if (! inst.IsInstallablePackage()) {
176 string msg = string.Format("{0}はインストールすることができません", inst.ToString());
177 throw new ApplicationException(msg);
180 inst.ErrorDataReceived += this.ReceivedErrorData;
181 inst.OutputDataReceived += this.ReceivedOutputData;
182 int exitCode = inst.Install();
184 RaiseTaskSetEvent(TaskEventType.WARNING, "インストールが正常に終えていない可能性があります。プロセスの終了コード:"+exitCode);
187 pkgListMan.WriteInstallationLog(inst);
190 public override bool Cancelable {
192 return !cancelCalled && Running && isDuringDownloading;
196 private bool isDuringDownloading {
198 return Running && (currentSubTask is DownloadSubTask);