2 using System.Collections.Generic;
\r
3 using NaGet.Packages.Install;
\r
4 using NaGet.Packages;
\r
8 namespace NaGet.SubCommands
\r
10 public class NaGetInstall : NaGetTaskSet
\r
12 private bool done = false;
\r
14 private int currentTaskSetIndex = -1;
\r
16 private PackageListsManager pkgListMan;
\r
19 /// ダウンロードに使うダウンローダオブジェクト
\r
21 public Downloader Downloader {
\r
23 if (downloader == null) {
\r
24 downloader = new Downloader();
\r
25 downloader.DownloadEventRaised += delegate(object sender, DownloadEventArgs e) {
\r
26 if (e.DownloadTaskType == DownloadEventType.DOWNLOADING && e.ProgressPercent > 0) {
\r
27 RaiseTaskSetEvent(TaskEventType.PING, string.Empty, GetProgressPercent(TaskEventType.PING, e.ProgressPercent));
\r
35 private Downloader downloader;
\r
37 private bool packageInstallerDownloaded = false;
\r
39 public override bool Cancelable {
\r
40 get { return ! done; }
\r
46 public Installation[] Installations;
\r
51 /// <param name="pkgs">インストールするパッケージ</param>
\r
52 public NaGetInstall(PackageListsManager pkgListMan, Package[] pkgs)
\r
53 : this(pkgListMan, Installation.ConvertInstallations(pkgs))
\r
60 /// <param name="installations">インストール処理の配列</param>
\r
61 public NaGetInstall(PackageListsManager pkgMan, Installation[] installations)
\r
63 pkgListMan = pkgMan;
\r
65 Installations = installations;
\r
66 initializeMainTaskSetNames();
\r
69 private void initializeMainTaskSetNames()
\r
71 taskSetNames = new List<string>();
\r
73 for (int i =0; i < Installations.Length; i++) {
\r
74 taskSetNames.Add(string.Format("取得: {0}", Installations[i].ToString()));
\r
75 taskSetNames.Add(string.Format("ウイルススキャン: {0}", Installations[i].ToString()));
\r
77 taskSetNames.Add("インストーラーの検証");
\r
78 for (int i =0; i < Installations.Length; i++) {
\r
79 taskSetNames.Add(string.Format("インストール: {0}", Installations[i].ToString()));
\r
81 taskSetNames.Add(string.Format("リスト更新: {0}", NaGet.Env.ArchiveInstalledPackageListFile));
\r
82 taskSetNames.Add(string.Format("リスト更新: {0}", NaGet.Env.SystemInstalledPackageListFile));
\r
85 public override void Run()
\r
87 currentTaskSetIndex = 0;
\r
88 RaiseTaskSetEvent(TaskEventType.STARTED, "インストール処理開始");
\r
92 List<Installation> invalidInstallers = null;
\r
95 currentTaskSetIndex = 0;
\r
96 packageInstallerDownloaded = false;
\r
98 runDownloadAndVirusCheckInstallers();
\r
99 if (done) return; // もしrunDownloadInstallers()内でエラー終了していたなら終了
\r
101 packageInstallerDownloaded = true;
\r
104 RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, taskSetNames[currentTaskSetIndex]);
\r
106 // ハッシュの壊れているインストーラーを取得
\r
107 invalidInstallers = runCheckHashForInstaller();
\r
110 if (invalidInstallers.Count > 0) {
\r
111 System.Text.StringBuilder invalidInstallerNames = new System.Text.StringBuilder();
\r
112 foreach (Installation invalidInst in invalidInstallers) {
\r
113 invalidInstallerNames.AppendFormat(" - {0}\n", invalidInst.ToString());
\r
116 string msg = string.Format("以下の{0}個のパッケージでファイルが壊れている可能性があります。\n{1}\n強制的にインストールを続行しますか?",
\r
117 invalidInstallers.Count, invalidInstallerNames.ToString());
\r
118 NaGetTaskQueryResult result = NaGetTaskQueryResult.CANCEL;
\r
120 if (!cancelCalled) {
\r
121 result = RaiseTaskSetQueryEvent(msg, NaGetTaskQueryResult.CONTINUE
\r
122 | NaGetTaskQueryResult.RETRY
\r
123 | NaGetTaskQueryResult.CANCEL);
\r
127 case NaGetTaskQueryResult.CONTINUE:
\r
128 RaiseTaskSetEvent(TaskEventType.WARNING, "ハッシュの非整合を無視してインストールを継続");
\r
129 invalidInstallers.Clear(); // ハッシュ非適合パッケージを強制的に抹消
\r
131 case NaGetTaskQueryResult.RETRY:
\r
132 RaiseTaskSetEvent(TaskEventType.INFO, "ダウンロード処理を再試行");
\r
134 foreach (Installation invalidInst in invalidInstallers) {
\r
135 invalidInst.RemoveDownloadedFile();
\r
139 //case NaGetTaskQueryResult.CANCEL:
\r
141 RaiseTaskSetEvent(TaskEventType.CANCELED, "パッケージのインストール処理がキャンセルされました");
\r
147 // もしハッシュが不適合なソフトがあるならばダウンロード処理からやり直す
\r
148 } while (invalidInstallers == null || invalidInstallers.Count > 0);
\r
149 RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, taskSetNames[currentTaskSetIndex]);
\r
150 currentTaskSetIndex ++;
\r
153 foreach (Installation inst in Installations) {
\r
154 string installTaskMsg = taskSetNames[currentTaskSetIndex];
\r
155 if (inst.Silent && (!inst.SupportsSilentOnly)) {
\r
156 installTaskMsg += " (サイレントインストール)";
\r
159 RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, installTaskMsg);
\r
163 inst.ErrorDataReceived += this.ReceivedErrorData;
\r
164 inst.OutputDataReceived += this.ReceivedOutputData;
\r
165 int exitCode = inst.Install();
\r
166 if (exitCode != 0) {
\r
167 RaiseTaskSetEvent(TaskEventType.WARNING, "インストールが正常に終えていない可能性があります。プロセスの終了コード:"+exitCode);
\r
170 pkgListMan.WriteInstallationLog(inst);
\r
171 } catch (Exception e) {
\r
172 RaiseTaskSetEvent(TaskEventType.ERROR, e.Message);
\r
176 RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, installTaskMsg);
\r
177 currentTaskSetIndex ++;
\r
179 if (cancelCalled) {
\r
180 RaiseTaskSetEvent(TaskEventType.CANCELED, "パッケージのインストール処理がキャンセルされました");
\r
190 RaiseTaskSetEvent(TaskEventType.COMPLETED, "終了", 100);
\r
195 /// 処理内容のダウンロード・ウイルススキャン部分のサブルーチン
\r
197 private void runDownloadAndVirusCheckInstallers()
\r
199 using (DownloadScannerService scanner = new DownloadScannerService()) {
\r
201 foreach (Installation inst in Installations) {
\r
202 if (! inst.IsInstallablePackage()) {
\r
203 string msg = string.Format("{0}はインストールすることができません", inst.ToString());
\r
205 RaiseTaskSetEvent(TaskEventType.ERROR, msg);
\r
210 RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, taskSetNames[currentTaskSetIndex]);
\r
212 if (! inst.Downloaded) {
\r
214 inst.Download(Downloader);
\r
215 } catch (TaskCanceledException) {
\r
216 RaiseTaskSetEvent(TaskEventType.CANCELED, "インストーラーのダウンロード処理がキャンセルされました");
\r
219 } catch (System.Net.WebException e) {
\r
220 RaiseTaskSetEvent(TaskEventType.WARNING, e.Message);
\r
221 if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()) {
\r
222 RaiseTaskSetEvent(TaskEventType.ERROR, "ネットワークに接続されていません。");
\r
224 RaiseTaskSetEvent(TaskEventType.ERROR, "ネットワークに接続できませんでした。ネットワークが切断されているか、ファイアウォールによって遮断された可能性があります。");
\r
228 } catch (Exception e) {
\r
229 RaiseTaskSetEvent(TaskEventType.ERROR, e.Message);
\r
235 if (! inst.Downloaded) { // ダウンロードが完了せずに終わった=失敗=エラー
\r
236 RaiseTaskSetEvent(TaskEventType.ERROR, string.Format("{0}のインストーラーファイルを正常にダウンロードできませんでした", inst.ToString()));
\r
240 RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, taskSetNames[currentTaskSetIndex]);
\r
241 currentTaskSetIndex ++;
\r
243 RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, taskSetNames[currentTaskSetIndex]);
\r
244 if (! NaGet.Env.EnableScanInstallerFile) {
\r
245 RaiseTaskSetEvent(TaskEventType.INFO, "ウイルススキャンを行わない設定のため、ダウンロードしたファイルはウイルススキャンされませんでした");
\r
246 } else if (!scanner.HasScanner) {
\r
247 RaiseTaskSetEvent(TaskEventType.INFO, "ダウンロードしたファイルはウイルススキャンされませんでした(ウイルススキャンソフトが検出できませんでした)");
\r
250 DownloadScannerResult result = inst.ScanInstallerFile(scanner);
\r
253 case DownloadScannerResult.ScannerNotFound:
\r
254 RaiseTaskSetEvent(TaskEventType.INFO, "ダウンロードしたファイルはウイルススキャンされませんでした(ウイルススキャンソフトが検出できませんでした)");
\r
256 case DownloadScannerResult.InfectedAndCleaned:
\r
257 RaiseTaskSetEvent(TaskEventType.ERROR,
\r
258 "インストーラーファイルからウイルス感染が検出されたため、削除されました。");
\r
261 case DownloadScannerResult.InfectedButNotCleaned:
\r
262 RaiseTaskSetEvent(TaskEventType.ERROR,
\r
263 "インストーラーファイルからウイルス感染が検出されました。");
\r
266 case DownloadScannerResult.ErrorNotFound:
\r
267 throw new System.IO.FileNotFoundException(string.Empty);
\r
271 } catch (System.Runtime.InteropServices.COMException ex) {
\r
272 RaiseTaskSetEvent(TaskEventType.WARNING,
\r
273 string.Format("{0} (E{1})", ex.Message, ex.ErrorCode));
\r
274 } catch (System.IO.FileNotFoundException ex) {
\r
275 if (ex.InnerException is System.Runtime.InteropServices.COMException) {
\r
276 RaiseTaskSetEvent(TaskEventType.WARNING,
\r
277 string.Format("{0} (E{1})", ex.InnerException.Message, ((System.Runtime.InteropServices.COMException) ex.InnerException).ErrorCode));
\r
279 RaiseTaskSetEvent(TaskEventType.ERROR, "インストーラーファイルがウイルススキャナーによって削除されました。");
\r
284 RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, taskSetNames[currentTaskSetIndex]);
\r
285 currentTaskSetIndex ++;
\r
287 if (cancelCalled) {
\r
288 RaiseTaskSetEvent(TaskEventType.CANCELED, "パッケージのインストール処理がキャンセルされました");
\r
297 /// ダウンロードしたパッケージが整合したか否かハッシュでチェック
\r
299 /// <returns>整合しなかったインストーラーのリスト</returns>
\r
300 private List<Installation> runCheckHashForInstaller()
\r
302 List<Installation> invalidInstallers = new List<Installation>();
\r
305 foreach (Installation inst in Installations) {
\r
306 float percent = (CurrentTaskSetIndex+((float)i / Installations.Length))*100f/taskSetNames.Count;
\r
308 if (inst.GetRegisteredHashCount() > 0) {
\r
309 RaiseTaskSetEvent(TaskEventType.INFO, "検証: "+inst.ToString(), percent);
\r
311 if (inst.IsInstallablePackage() && inst.VerifyHashValues() == false) {
\r
312 invalidInstallers.Add(inst);
\r
313 RaiseTaskSetEvent(TaskEventType.WARNING, "検証: "+inst.ToString() + " 非整合", percent);
\r
315 RaiseTaskSetEvent(TaskEventType.INFO, "検証: "+inst.ToString() + " OK", percent);
\r
321 return invalidInstallers;
\r
324 private void runLocalUpdate()
\r
327 RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, taskSetNames[currentTaskSetIndex]);
\r
328 pkgListMan.DetectInstalledPkgs();
\r
329 pkgListMan.SaveInstalledPackageList();
\r
330 RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, taskSetNames[currentTaskSetIndex]);
\r
331 currentTaskSetIndex++;
\r
333 // システムにインストールされているリストの更新
\r
334 RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, taskSetNames[currentTaskSetIndex]);
\r
335 pkgListMan.DetectSystemInstalledPkgs();
\r
336 pkgListMan.SaveSystemInstalledPackageList();
\r
337 RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, taskSetNames[currentTaskSetIndex]);
\r
338 currentTaskSetIndex++;
\r
341 public override bool Done {
\r
342 get { return done; }
\r
345 public override int CurrentTaskSetIndex {
\r
346 get { return currentTaskSetIndex; }
\r
349 private bool cancelCalled = false;
\r
351 public override bool Cancel()
\r
353 cancelCalled = true;
\r
354 if (! packageInstallerDownloaded) {
\r
355 return Downloader.Cancel();
\r
356 } else return true;
\r