using System;
using System.IO;
using System.Collections.Generic;
using NaGet.Packages;
using NaGet.Packages.Install;
namespace NaGet.Packages
{
///
/// パッケージリスト達をひとまとめにして管理する
///
public class PackageListsManager
{
internal PackageList availablePkgList;
internal PackageList installedPkgList;
internal PackageList systemInstalledPkgList;
///
/// ファイルリストから読み込まれたパッケージのリスト
///
public PackageList AvailablePkgList {
get { return availablePkgList; }
}
///
/// 本ソフトウェアを介してインストールされたパッケージのリスト
///
public PackageList InstalledPkgList {
get { return installedPkgList; }
}
///
/// システムから検出されたパッケージのリスト
///
public PackageList SystemInstalledPkgList {
get { return systemInstalledPkgList; }
}
///
/// インストールログ
///
private List systemInstalledLogList;
///
/// 初期化をする。ファイル群を読み込んで更新がなされる。
///
public PackageListsManager()
{
LoadPackageLists();
}
#region ファイル読み書き
///
/// ファイルを読み込んで更新する
///
public void LoadPackageLists()
{
try {
availablePkgList = NaGet.Utils.GetDeserializedObject>(NaGet.Env.PackageListFile);
} catch (FileNotFoundException) {
availablePkgList = new PackageList();
}
try {
installedPkgList = NaGet.Utils.GetDeserializedObject>(NaGet.Env.ArchiveInstalledPackageListFile);
} catch (FileNotFoundException) {
installedPkgList = new PackageList();
}
try {
systemInstalledPkgList = NaGet.Utils.GetDeserializedObject>(NaGet.Env.SystemInstalledPackageListFile);
} catch (FileNotFoundException) {
systemInstalledPkgList = new PackageList();
}
systemInstalledLogList = new List();
try {
systemInstalledLogList.AddRange(
NaGet.Utils.GetDeserializedObject(NaGet.Env.SystemInstalledPackageLogFile)
);
} catch (Exception) {
// do nothing
}
}
///
/// ファイルリストから読み込まれたパッケージのリスト
/// をファイルに書き込む。
///
public void SaveAvailablePackageList()
{
NaGet.Utils.PutSerializeObject(NaGet.Env.PackageListFile, availablePkgList);
}
///
/// 本ソフトウェアを介してインストールされたパッケージのリスト
/// をファイルに書き込む。
///
public void SaveInstalledPackageList()
{
NaGet.Utils.PutSerializeObject(NaGet.Env.ArchiveInstalledPackageListFile, installedPkgList);
}
///
/// システムから検出されたパッケージのリスト
/// をファイルに書き込む。
///
public void SaveSystemInstalledPackageList()
{
NaGet.Utils.PutSerializeObject(NaGet.Env.SystemInstalledPackageListFile, systemInstalledPkgList);
}
///
/// インストールログ
/// をファイルに書き込む。
///
public void SaveSystemInstalledLogList()
{
NaGet.Utils.PutSerializeObject(NaGet.Env.SystemInstalledPackageLogFile, systemInstalledLogList);
}
///
/// 本オブジェクトの保有しているパッケージ情報の全てをファイルに書き出す。
///
public void CommitToFile()
{
SaveAvailablePackageList();
SaveInstalledPackageList();
SaveSystemInstalledPackageList();
SaveSystemInstalledLogList();
}
#endregion
#region パッケージインストール検知関連
///
/// 本ソフトウェアを介してインストールされたパッケージを検出する。
/// 具体的には
/// で指定されたフォルダの下を見る。
///
public void DetectInstalledPkgs()
{
PackageList pkgList = new PackageList();
if (Directory.Exists(NaGet.Env.ArchiveProgramFiles)) {
foreach (string path in NaGet.Utils.ExtendWildcardFile(NaGet.Env.ArchiveProgramFiles, Path.Combine("*", ".applistation.package.xml"))) {
pkgList.AddPackage(NaGet.Utils.GetDeserializedObject(path));
}
this.installedPkgList = pkgList;
}
}
///
/// レジストリから、コンピュータにインストールされたパッケージを検出し、
/// インストールトリストに登録(更新)をする。このとき、
/// インストールのログを見て可能な限りパッケージ情報を補完する。
///
public void DetectSystemInstalledPkgs()
{
List installedPkgList = new List();
installedPkgList.AddRange(RegistriedUninstallers.DetectInstalledPackages(availablePkgList));
// インストールのログを見て可能な限りパッケージ情報を補完する。
for (int i = 0; i < installedPkgList.Count; i++) {
InstalledPackage pkg = installedPkgList[i];
int count = installedPkgList.FindAll(PackageList.GetPredicateForPackageName(pkg.Name)).Count;
foreach (InstallationLog log in systemInstalledLogList.FindAll(createPackageNamePredicator(pkg))) {
// 1. バージョンがアンインストール情報から取得できなかったときは無条件で登録
// 2. 同一名パッケージがない場合は無条件で登録
// 3. 複数個同一パッケージがインストールされている場合は、バージョン比較して登録。
if (string.IsNullOrEmpty(pkg.Version) ||
count < 2 ||
log.Package.Version == pkg.Version) {
// 補完したパッケージ情報への差し替え
UninstallInformation pkgUninstInfo = pkg.UninstallInfo;
NaGet.Utils.FieldCopy((Package) log.Package, ref pkg);
pkg.UninstallInfo = pkgUninstInfo;
if (pkg.UninstallInfo.InstallDate == null) { // インストール日時の補完
pkg.UninstallInfo.InstallDate = log.Date;
}
break;
}
}
}
this.systemInstalledPkgList.Packages = installedPkgList.ToArray();
}
#endregion
#region パッケージ便利メソッド
///
/// 全て(すなわち、本ソフトウェアを介してインストールされたものと、
/// システムにインストールされたもの)のインストールされたパッケージを返す便利メソッド
///
/// 全てのインストールされたパッケージのイテレータ
public IEnumerable GetAllInstalledPackages()
{
return NaGet.Utils.MeargeEnumerable(
installedPkgList.GetEnumerator(),
systemInstalledPkgList.GetEnumerator()
);
}
///
/// 全てのパッケージをイテレータで返す便利メソッド。
///
/// パッケージのイテレータ
public IEnumerable GetAllPackages()
{
return NaGet.Utils.MeargeEnumerable(
availablePkgList.GetEnumerator(),
(IEnumerator) GetAllInstalledPackages().GetEnumerator()
);
}
#endregion
#region インストールログ関連
///
/// 指定パッケージ名に対応するログを判定するPredicate
///
/// 判定する指定パッケージ
/// Predicate
private Predicate createPackageNamePredicator(Package pkg)
{
return delegate(InstallationLog log) {
return log.Package.Name == pkg.Name;
};
}
///
/// インストールログにインストール情報を追加する。
/// ファイルへの書き込みは行われない。
///
/// 過去の同一パッケージ名のログは消去される
/// 書き込むインストール情報
public void WriteInstallationLog(Installation inst)
{
// 重複は削除
systemInstalledLogList.RemoveAll(createPackageNamePredicator(inst.InstalledPackage));
InstallationLog newLog = new InstallationLog();
newLog.Date = DateTime.Now;
newLog.Package = inst.InstalledPackage;
systemInstalledLogList.Add(newLog);
}
#endregion
}
}