2 using System.Collections.Generic;
3 using NaGet.Packages.Install;
8 namespace NaGet.SubCommands
10 public class NaGetDownloadToCache : NaGetTaskSet
12 private bool done = false;
14 private int currentTaskSetIndex = -1;
16 private PackageListsManager pkgListMan;
19 /// ダウンロードに使うダウンローダオブジェクト
21 public Downloader Downloader {
23 if (downloader == null) {
24 downloader = new Downloader();
25 downloader.DownloadEventRaised += delegate(object sender, DownloadEventArgs e) {
26 if (e.DownloadTaskType == DownloadEventType.DOWNLOADING && e.ProgressPercent > 0) {
27 RaiseTaskSetEvent(TaskEventType.PING, string.Empty, GetProgressPercent(TaskEventType.PING, e.ProgressPercent));
35 private Downloader downloader;
37 private bool packageInstallerDownloaded = false;
39 public override bool Cancelable {
40 get { return ! done; }
46 public Installation[] Installations;
51 /// <param name="pkgs">インストールするパッケージ</param>
52 public NaGetDownloadToCache(PackageListsManager pkgListMan, Package[] pkgs)
53 : this(pkgListMan, Installation.ConvertInstallations(pkgs))
60 /// <param name="installations">インストール処理の配列</param>
61 public NaGetDownloadToCache(PackageListsManager pkgMan, Installation[] installations)
65 Installations = installations;
66 initializeMainTaskSetNames();
69 private void initializeMainTaskSetNames()
71 taskSetNames = new List<string>();
73 for (int i =0; i < Installations.Length; i++) {
74 taskSetNames.Add(string.Format("取得: {0}", Installations[i].ToString()));
75 taskSetNames.Add(string.Format("ウイルススキャン: {0}", Installations[i].ToString()));
77 taskSetNames.Add("インストーラーの検証");
78 taskSetNames.Add(string.Format("リスト更新: {0}", NaGet.Env.ArchiveInstalledPackageListFile));
79 taskSetNames.Add(string.Format("リスト更新: {0}", NaGet.Env.SystemInstalledPackageListFile));
82 public override void Run()
84 currentTaskSetIndex = 0;
85 RaiseTaskSetEvent(TaskEventType.STARTED, "インストール処理開始");
89 List<Installation> invalidInstallers = null;
92 currentTaskSetIndex = 0;
93 packageInstallerDownloaded = false;
95 runDownloadAndVirusCheckInstallers();
96 if (done) return; // もしrunDownloadInstallers()内でエラー終了していたなら終了
98 packageInstallerDownloaded = true;
101 RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, taskSetNames[currentTaskSetIndex]);
103 // ハッシュの壊れているインストーラーを取得
104 invalidInstallers = runCheckHashForInstaller();
107 if (invalidInstallers.Count > 0) {
108 System.Text.StringBuilder invalidInstallerNames = new System.Text.StringBuilder();
109 foreach (Installation invalidInst in invalidInstallers) {
110 invalidInstallerNames.AppendFormat(" - {0}\n", invalidInst.ToString());
113 string msg = string.Format("以下の{0}個のパッケージでファイルが壊れている可能性があります。\n{1}\nダウンロードし直しますか?",
114 invalidInstallers.Count, invalidInstallerNames.ToString());
115 NaGetTaskQueryResult result = NaGetTaskQueryResult.CANCEL;
118 result = RaiseTaskSetQueryEvent(msg, NaGetTaskQueryResult.CONTINUE
119 | NaGetTaskQueryResult.CANCEL);
123 case NaGetTaskQueryResult.CONTINUE:
124 RaiseTaskSetEvent(TaskEventType.INFO, "ダウンロード処理を再試行");
126 foreach (Installation invalidInst in invalidInstallers) {
127 invalidInst.RemoveDownloadedFile();
131 //case NaGetTaskQueryResult.CANCEL:
133 RaiseTaskSetEvent(TaskEventType.CANCELED, "パッケージのダウンロード処理がキャンセルされました");
139 // もしハッシュが不適合なソフトがあるならばダウンロード処理からやり直す
140 } while (invalidInstallers == null || invalidInstallers.Count > 0);
141 RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, taskSetNames[currentTaskSetIndex]);
142 currentTaskSetIndex ++;
149 RaiseTaskSetEvent(TaskEventType.COMPLETED, "終了", 100);
154 /// 処理内容のダウンロード・ウイルススキャン部分のサブルーチン
156 private void runDownloadAndVirusCheckInstallers()
158 using (DownloadScannerService scanner = new DownloadScannerService()) {
160 foreach (Installation inst in Installations) {
161 RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, taskSetNames[currentTaskSetIndex]);
163 if (! inst.Downloaded) {
165 inst.Download(Downloader);
166 } catch (TaskCanceledException) {
167 RaiseTaskSetEvent(TaskEventType.CANCELED, "インストーラーのダウンロード処理がキャンセルされました");
170 } catch (System.Net.WebException e) {
171 RaiseTaskSetEvent(TaskEventType.WARNING, e.Message);
172 if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()) {
173 RaiseTaskSetEvent(TaskEventType.ERROR, "ネットワークに接続されていません。");
175 RaiseTaskSetEvent(TaskEventType.ERROR, "ネットワークに接続できませんでした。ネットワークが切断されているか、ファイアウォールによって遮断された可能性があります。");
179 } catch (Exception e) {
180 RaiseTaskSetEvent(TaskEventType.ERROR, e.Message);
186 if (! inst.Downloaded) { // ダウンロードが完了せずに終わった=失敗=エラー
187 RaiseTaskSetEvent(TaskEventType.ERROR, string.Format("{0}のインストーラーファイルを正常にダウンロードできませんでした", inst.ToString()));
191 RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, taskSetNames[currentTaskSetIndex]);
192 currentTaskSetIndex ++;
194 RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, taskSetNames[currentTaskSetIndex]);
195 if (! NaGet.Env.EnableScanInstallerFile) {
196 RaiseTaskSetEvent(TaskEventType.INFO, "ウイルススキャンを行わない設定のため、ダウンロードしたファイルはウイルススキャンされませんでした");
197 } else if (!scanner.HasScanner) {
198 RaiseTaskSetEvent(TaskEventType.INFO, "ダウンロードしたファイルはウイルススキャンされませんでした(ウイルススキャンソフトが検出できませんでした)");
201 DownloadScannerResult result = inst.ScanInstallerFile(scanner);
204 case DownloadScannerResult.ScannerNotFound:
205 RaiseTaskSetEvent(TaskEventType.INFO, "ダウンロードしたファイルはウイルススキャンされませんでした(ウイルススキャンソフトが検出できませんでした)");
207 case DownloadScannerResult.InfectedAndCleaned:
208 RaiseTaskSetEvent(TaskEventType.ERROR,
209 "インストーラーファイルからウイルス感染が検出されたため、削除されました。");
212 case DownloadScannerResult.InfectedButNotCleaned:
213 RaiseTaskSetEvent(TaskEventType.ERROR,
214 "インストーラーファイルからウイルス感染が検出されました。");
217 case DownloadScannerResult.ErrorNotFound:
218 throw new System.IO.FileNotFoundException(string.Empty);
222 } catch (System.Runtime.InteropServices.COMException ex) {
223 RaiseTaskSetEvent(TaskEventType.WARNING,
224 string.Format("{0} (E{1})", ex.Message, ex.ErrorCode));
225 } catch (System.IO.FileNotFoundException ex) {
226 if (ex.InnerException is System.Runtime.InteropServices.COMException) {
227 RaiseTaskSetEvent(TaskEventType.WARNING,
228 string.Format("{0} (E{1})", ex.InnerException.Message, ((System.Runtime.InteropServices.COMException) ex.InnerException).ErrorCode));
230 RaiseTaskSetEvent(TaskEventType.ERROR, "インストーラーファイルがウイルススキャナーによって削除されました。");
235 RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, taskSetNames[currentTaskSetIndex]);
236 currentTaskSetIndex ++;
239 RaiseTaskSetEvent(TaskEventType.CANCELED, "パッケージのインストール処理がキャンセルされました");
248 /// ダウンロードしたパッケージが整合したか否かハッシュでチェック
250 /// <returns>整合しなかったインストーラーのリスト</returns>
251 private List<Installation> runCheckHashForInstaller()
253 List<Installation> invalidInstallers = new List<Installation>();
256 foreach (Installation inst in Installations) {
257 float percent = (CurrentTaskSetIndex+((float)i / Installations.Length))*100f/taskSetNames.Count;
259 if (inst.GetRegisteredHashCount() > 0) {
260 RaiseTaskSetEvent(TaskEventType.INFO, "検証: "+inst.ToString(), percent);
262 if (inst.IsInstallablePackage() && inst.VerifyHashValues() == false) {
263 invalidInstallers.Add(inst);
264 RaiseTaskSetEvent(TaskEventType.WARNING, "検証: "+inst.ToString() + " 非整合", percent);
266 RaiseTaskSetEvent(TaskEventType.INFO, "検証: "+inst.ToString() + " OK", percent);
272 return invalidInstallers;
275 private void runLocalUpdate()
278 RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, taskSetNames[currentTaskSetIndex]);
279 pkgListMan.DetectInstalledPkgs();
280 pkgListMan.SaveInstalledPackageList();
281 RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, taskSetNames[currentTaskSetIndex]);
282 currentTaskSetIndex++;
284 // システムにインストールされているリストの更新
285 RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, taskSetNames[currentTaskSetIndex]);
286 pkgListMan.DetectSystemInstalledPkgs();
287 pkgListMan.SaveSystemInstalledPackageList();
288 RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, taskSetNames[currentTaskSetIndex]);
289 currentTaskSetIndex++;
292 public override bool Done {
296 public override int CurrentTaskSetIndex {
297 get { return currentTaskSetIndex; }
300 private bool cancelCalled = false;
302 public override bool Cancel()
305 if (! packageInstallerDownloaded) {
306 return Downloader.Cancel();