using System;
using System.Collections.Generic;
using NaGet.Packages;
using NaGet.Packages.Install;
using NaGet.SubCommands;
using NaGet.SubCommands.SubTask;
using NaGet.Tasks;
using NaGet.InteropServices;
namespace NaGet.SubCommands
{
///
/// キャッシュへのインストーラファイルのダウンロード処理
///
public class NaGetDownloadToCache2 : NaGetTaskSet2
{
private IList installations;
private DownloadScannerService scanner;
///
/// コンストラクタ
///
/// インストールするパッケージ
public NaGetDownloadToCache2(PackageListsManager pkgListMan, Package[] pkgs)
: this(pkgListMan, Installation.ConvertInstallations(pkgs))
{
}
///
/// コンストラクタ
///
/// インストール処理の配列
public NaGetDownloadToCache2(PackageListsManager pkgMan, IList insts)
{
installations = insts;
scanner = new DownloadScannerService();
scanner.Init();
// taskセットの初期化
initSubTask();
foreach (Installation inst in installations) {
DownloadSubTask dlSTask = new DownloadSubTask(inst.InstallerURL, inst.InstallerFile);
VirusScanSubTask scanSTask = new VirusScanSubTask(scanner, inst.InstallerFile, inst.InstallerURL);
dlSTask.TaskEventRaised += delegate(object sender, TaskEventArgs e) {
if (e.Type == TaskEventType.COMPLETED) {
scanSTask.TargetFilePath = inst.InstallerFile;
}
};
registSubTask(string.Format("ダウンロード: {0}", inst),
dlSTask);
registSubTask(string.Format("ウイルススキャン: {0}", inst),
scanSTask);
}
registSubTask("インストーラーの検証",
new VerifyInstallerFileSubTask(insts));
registSubTask("インストール済みのソフトリスト更新",
new LocalUpdateSubTask(pkgMan));
}
public override void Run()
{
NotifyStarted();
RaiseTaskSetEvent(TaskEventType.STARTED, string.Empty);
try {
while (hasMoreSubTask) {
bool canGoToNextSubTask = true;
RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, currentSubTaskName);
currentSubTask.Run();
RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, currentSubTaskName);
if (runCheckVerify() == false) {
canGoToNextSubTask = false;
NotifyGoToSubTask(0); // 最初からやり直し。
}
if (cancelCalled) {
throw new TaskCanceledException("cancel is called");
}
if (canGoToNextSubTask) {
NotifyGoToNextSubTask();
}
}
} catch (TaskCanceledException) {
cancelCalled = true;
} catch (Exception e) {
RaiseTaskSetEvent(TaskEventType.ERROR, e.Message);
}
if (cancelCalled) {
NotifyCancelled();
RaiseTaskSetEvent(TaskEventType.CANCELED, "キャンセルされました");
} else {
NotifyCompleted();
RaiseTaskSetEvent(TaskEventType.COMPLETED, string.Empty);
}
}
private bool runCheckVerify()
{
bool ret = true;
if (currentSubTask is VerifyInstallerFileSubTask) {
VerifyInstallerFileSubTask verifySTask = currentSubTask as VerifyInstallerFileSubTask;
if (verifySTask.InvalidInstallers != null && verifySTask.InvalidInstallers.Count > 0) {
System.Text.StringBuilder invalidInstallerNames = new System.Text.StringBuilder();
foreach (Installation invalidInst in verifySTask.InvalidInstallers) {
invalidInstallerNames.AppendFormat(" - {0}\n", invalidInst.ToString());
}
string msg = string.Format("以下の{0}個のパッケージでファイルが壊れている可能性があります。\n{1}\nダウンロードし直しますか?",
verifySTask.InvalidInstallers.Count, invalidInstallerNames.ToString());
NaGetTaskQueryResult result = NaGetTaskQueryResult.CANCEL;
if (!cancelCalled) {
result = RaiseTaskSetQueryEvent(msg, NaGetTaskQueryResult.CONTINUE | NaGetTaskQueryResult.CANCEL);
}
switch (result) {
case NaGetTaskQueryResult.CONTINUE:
RaiseTaskSetEvent(TaskEventType.INFO, "ダウンロード処理を再試行");
foreach (Installation invalidInst in verifySTask.InvalidInstallers) {
invalidInst.RemoveDownloadedFile();
}
ret = false;
break;
case NaGetTaskQueryResult.CANCEL:
case NaGetTaskQueryResult.CANCELED_AUTOMATICALLY:
default:
ret = false;
throw new TaskCanceledException("処理の継続のキャンセルが選択されました");
}
}
}
return ret;
}
public override bool Cancelable {
get {
return !cancelCalled && Running && isDuringDownloading;
}
}
private bool isDuringDownloading {
get {
return Running && (currentSubTask is DownloadSubTask);
}
}
}
}