2 using System.Collections.Generic;
3 using NaGet.Packages.Install;
7 namespace NaGet.SubCommands
9 public class NaGetDownloadToCache : NaGetTaskSet
11 private bool done = false;
13 private int currentTaskSetIndex = -1;
15 private PackageListsManager pkgListMan;
18 /// ダウンロードに使うダウンローダオブジェクト
20 public Downloader Downloader {
22 if (downloader == null) {
23 downloader = new Downloader();
24 downloader.DownloadEventRaised += delegate(object sender, DownloadEventArgs e) {
25 if (e.Type == DownloadEventType.DOWNLOADING && e.TaskProgressPercent > 0) {
26 RaiseTaskSetEvent(NaGetTaskSetEventType.PING, string.Empty, GetProgressPercent(NaGetTaskSetEventType.PING, e.TaskProgressPercent));
34 private Downloader downloader;
36 private bool packageInstallerDownloaded = false;
38 public override bool Cancelable {
39 get { return ! done; }
45 public Installation[] Installations;
50 /// <param name="pkgs">インストールするパッケージ</param>
51 public NaGetDownloadToCache(PackageListsManager pkgListMan, Package[] pkgs)
52 : this(pkgListMan, Installation.ConvertInstallations(pkgs))
59 /// <param name="installations">インストール処理の配列</param>
60 public NaGetDownloadToCache(PackageListsManager pkgMan, Installation[] installations)
64 Installations = installations;
65 initializeMainTaskSetNames();
68 private void initializeMainTaskSetNames()
70 List<string> taskSetNames = new List<string>();
72 for (int i =0; i < Installations.Length; i++) {
73 taskSetNames.Add(string.Format("取得: {0}", Installations[i].ToString()));
74 taskSetNames.Add(string.Format("ウイルススキャン: {0}", Installations[i].ToString()));
76 taskSetNames.Add("インストーラーの検証");
77 taskSetNames.Add(string.Format("リスト更新: {0}", NaGet.Env.ArchiveInstalledPackageListFile));
78 taskSetNames.Add(string.Format("リスト更新: {0}", NaGet.Env.SystemInstalledPackageListFile));
80 TaskSetNames = taskSetNames.ToArray();
83 public override void Run()
85 currentTaskSetIndex = 0;
86 RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED, "インストール処理開始");
90 List<Installation> invalidInstallers = null;
93 currentTaskSetIndex = 0;
94 packageInstallerDownloaded = false;
96 runDownloadAndVirusCheckInstallers();
97 if (done) return; // もしrunDownloadInstallers()内でエラー終了していたなら終了
99 packageInstallerDownloaded = true;
102 RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]);
104 // ハッシュの壊れているインストーラーを取得
105 invalidInstallers = runCheckHashForInstaller();
108 if (invalidInstallers.Count > 0) {
109 System.Text.StringBuilder invalidInstallerNames = new System.Text.StringBuilder();
110 foreach (Installation invalidInst in invalidInstallers) {
111 invalidInstallerNames.AppendFormat(" - {0}\n", invalidInst.ToString());
114 string msg = string.Format("以下の{0}個のパッケージでファイルが壊れている可能性があります。\n{1}\nダウンロードし直しますか?",
115 invalidInstallers.Count, invalidInstallerNames.ToString());
116 NaGetTaskQueryResult result = NaGetTaskQueryResult.CANCEL;
119 result = RaiseTaskSetQueryEvent(msg, NaGetTaskQueryResult.CONTINUE
120 | NaGetTaskQueryResult.CANCEL);
124 case NaGetTaskQueryResult.CONTINUE:
125 RaiseTaskSetEvent(NaGetTaskSetEventType.INFO, "ダウンロード処理を再試行");
127 foreach (Installation invalidInst in invalidInstallers) {
128 invalidInst.RemoveDownloadedFile();
132 //case NaGetTaskQueryResult.CANCEL:
134 RaiseTaskSetEvent(NaGetTaskSetEventType.CANCELED, "パッケージのダウンロード処理がキャンセルされました");
140 // もしハッシュが不適合なソフトがあるならばダウンロード処理からやり直す
141 } while (invalidInstallers == null || invalidInstallers.Count > 0);
142 RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex]);
143 currentTaskSetIndex ++;
150 RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED, "終了", 100);
155 /// 処理内容のダウンロード・ウイルススキャン部分のサブルーチン
157 private void runDownloadAndVirusCheckInstallers()
159 using (DownloadScanner scanner = new DownloadScanner()) {
161 foreach (Installation inst in Installations) {
162 RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]);
164 if (! inst.Downloaded) {
166 inst.Download(Downloader);
167 } catch (NaGetTaskCanceledException) {
168 RaiseTaskSetEvent(NaGetTaskSetEventType.CANCELED, "インストーラーのダウンロード処理がキャンセルされました");
171 } catch (System.Net.WebException e) {
172 RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, e.Message);
173 if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()) {
174 RaiseTaskSetEvent(NaGetTaskSetEventType.ERROR, "ネットワークに接続されていません。");
176 RaiseTaskSetEvent(NaGetTaskSetEventType.ERROR, "ネットワークに接続できませんでした。ネットワークが切断されているか、ファイアウォールによって遮断された可能性があります。");
180 } catch (Exception e) {
181 RaiseTaskSetEvent(NaGetTaskSetEventType.ERROR, e.Message);
187 if (! inst.Downloaded) { // ダウンロードが完了せずに終わった=失敗=エラー
188 RaiseTaskSetEvent(NaGetTaskSetEventType.ERROR, string.Format("{0}のインストーラーファイルを正常にダウンロードできませんでした", inst.ToString()));
192 RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex]);
193 currentTaskSetIndex ++;
195 RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]);
196 if (! NaGet.Env.EnableScanInstallerFile) {
197 RaiseTaskSetEvent(NaGetTaskSetEventType.INFO, "ウイルススキャンを行わない設定のため、ダウンロードしたファイルはウイルススキャンされませんでした");
198 } else if (!scanner.HasScanner) {
199 RaiseTaskSetEvent(NaGetTaskSetEventType.INFO, "ダウンロードしたファイルはウイルススキャンされませんでした(ウイルススキャンソフトが検出できませんでした)");
202 DownloadScannerResult result = inst.ScanInstallerFile(scanner);
205 case DownloadScannerResult.ScannerNotFound:
206 RaiseTaskSetEvent(NaGetTaskSetEventType.INFO, "ダウンロードしたファイルはウイルススキャンされませんでした(ウイルススキャンソフトが検出できませんでした)");
208 case DownloadScannerResult.InfectedAndCleaned:
209 RaiseTaskSetEvent(NaGetTaskSetEventType.ERROR,
210 "インストーラーファイルからウイルス感染が検出されたため、削除されました。");
213 case DownloadScannerResult.InfectedButNotCleaned:
214 RaiseTaskSetEvent(NaGetTaskSetEventType.ERROR,
215 "インストーラーファイルからウイルス感染が検出されました。");
218 case DownloadScannerResult.ErrorNotFound:
219 throw new System.IO.FileNotFoundException(string.Empty);
223 } catch (System.Runtime.InteropServices.COMException ex) {
224 RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING,
225 string.Format("{0} (E{1})", ex.Message, ex.ErrorCode));
226 } catch (System.IO.FileNotFoundException ex) {
227 if (ex.InnerException is System.Runtime.InteropServices.COMException) {
228 RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING,
229 string.Format("{0} (E{1})", ex.InnerException.Message, ((System.Runtime.InteropServices.COMException) ex.InnerException).ErrorCode));
231 RaiseTaskSetEvent(NaGetTaskSetEventType.ERROR, "インストーラーファイルがウイルススキャナーによって削除されました。");
236 RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex]);
237 currentTaskSetIndex ++;
240 RaiseTaskSetEvent(NaGetTaskSetEventType.CANCELED, "パッケージのインストール処理がキャンセルされました");
249 /// ダウンロードしたパッケージが整合したか否かハッシュでチェック
251 /// <returns>整合しなかったインストーラーのリスト</returns>
252 private List<Installation> runCheckHashForInstaller()
254 List<Installation> invalidInstallers = new List<Installation>();
257 foreach (Installation inst in Installations) {
258 float percent = (CurrentTaskSetIndex+((float)i / Installations.Length))*100f/TaskSetNames.Length;
260 if (inst.GetRegisteredHashCount() > 0) {
261 RaiseTaskSetEvent(NaGetTaskSetEventType.INFO, "検証: "+inst.ToString(), percent);
263 if (inst.IsInstallablePackage() && inst.VerifyHashValues() == false) {
264 invalidInstallers.Add(inst);
265 RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, "検証: "+inst.ToString() + " 非整合", percent);
267 RaiseTaskSetEvent(NaGetTaskSetEventType.INFO, "検証: "+inst.ToString() + " OK", percent);
273 return invalidInstallers;
276 private void runLocalUpdate()
279 RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]);
280 pkgListMan.DetectInstalledPkgs();
281 pkgListMan.SaveInstalledPackageList();
282 RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex]);
283 currentTaskSetIndex++;
285 // システムにインストールされているリストの更新
286 RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]);
287 pkgListMan.DetectSystemInstalledPkgs();
288 pkgListMan.SaveSystemInstalledPackageList();
289 RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex]);
290 currentTaskSetIndex++;
293 public override bool Done {
297 public override int CurrentTaskSetIndex {
298 get { return currentTaskSetIndex; }
301 private bool cancelCalled = false;
303 public override bool Cancel()
306 if (! packageInstallerDownloaded) {
307 return Downloader.Cancel();