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; }
}
///
/// 初期化をする。データの読み込みは明示的にLoadPackageLists()を呼び出さなければならない。
///
public PackageListsManager()
{
availablePkgList = new PackageList();
installedPkgList = new PackageList();
systemInstalledPkgList = new PackageList();
}
#region ファイル読み書き
///
/// ファイルを読み込んで更新する
///
public void LoadPackageLists()
{
System.Xml.Serialization.XmlSerializer sr;
// ソフトリストのパッケージリスト読み込み
sr = new System.Xml.Serialization.XmlSerializer(typeof(PackageList));
if (File.Exists(NaGet.Env.PackageListFile)) {
availablePkgList = (PackageList) NaGet.Utils.GetDeserializedObject(NaGet.Env.PackageListFile, sr);
} else {
availablePkgList = new PackageList();
}
sr = new System.Xml.Serialization.XmlSerializer(typeof(PackageList));
if (File.Exists(NaGet.Env.ArchiveInstalledPackageListFile)) {
installedPkgList = (PackageList) NaGet.Utils.GetDeserializedObject(NaGet.Env.ArchiveInstalledPackageListFile, sr);
} else {
installedPkgList = new PackageList();
}
//sr = new System.Xml.Serialization.XmlSerializer(typeof(PackageList));
if (File.Exists(NaGet.Env.SystemInstalledPackageListFile)) {
systemInstalledPkgList = (PackageList) NaGet.Utils.GetDeserializedObject(NaGet.Env.SystemInstalledPackageListFile, sr);
} else {
systemInstalledPkgList = new PackageList();
}
}
///
/// ファイルリストから読み込まれたパッケージのリスト
/// をファイルに書き込む。
///
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 CommitToFile()
{
SaveAvailablePackageList();
SaveInstalledPackageList();
SaveSystemInstalledPackageList();
}
#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();
List systemInstalledLogList = getSystemInstallerLog();
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(log.Package, ref pkg);
pkg.UninstallInfo = pkgUninstInfo;
if (pkg.UninstallInfo.InstallDate == null) { // インストール日時の補完
pkg.UninstallInfo.InstallDate = log.Date;
}
break;
}
}
}
this.systemInstalledPkgList.SetPackages(installedPkgList);
}
#endregion
#region パッケージ便利メソッド
///
/// 全て(すなわち、本ソフトウェアを介してインストールされたものと、
/// システムにインストールされたもの)のインストールされたパッケージを返す便利メソッド
///
/// 全てのインストールされたパッケージのイテレータ
public IEnumerable GetAllInstalledPackages()
{
return NaGet.Utils.MergeEnumerable(
installedPkgList.GetEnumerator(),
systemInstalledPkgList.GetEnumerator()
);
}
///
/// 全てのパッケージをイテレータで返す便利メソッド。
///
/// パッケージのイテレータ
public IEnumerable GetAllPackages()
{
return NaGet.Utils.MergeEnumerable(
availablePkgList.GetEnumerator(),
(IEnumerator) GetAllInstalledPackages().GetEnumerator()
);
}
#endregion
#region インストールログ関連
///
/// インストールログのリストを作って返す。
///
/// インストールログのリスト
private static List getSystemInstallerLog()
{
List systemInstalledLogList;
try {
systemInstalledLogList = NaGet.Utils.GetDeserializedObject>(NaGet.Env.SystemInstalledPackageLogFile);
} catch (Exception) {
systemInstalledLogList = new List();
}
return systemInstalledLogList;
}
///
/// インストールログを保存する。
///
/// インストールログデータ
private static void setSystemInstallerLog(List systemInstalledLogList)
{
NaGet.Utils.PutSerializeObject(NaGet.Env.SystemInstalledPackageLogFile, systemInstalledLogList);
}
///
/// 指定パッケージ名に対応するログを判定するPredicate
///
/// 判定する指定パッケージ
/// Predicate
private static Predicate createPackageNamePredicator(Package pkg)
{
return delegate(InstallationLog log) {
return log.Package.Name == pkg.Name;
};
}
///
/// インストールログにインストール情報を追加する。
/// ファイルへの書き込みは行われない。
///
/// 過去の同一パッケージ名のログは消去される
/// 書き込むインストール情報
public void WriteInstallationLog(Installation inst)
{
List systemInstalledLogList = getSystemInstallerLog();
// 重複は削除
systemInstalledLogList.RemoveAll(createPackageNamePredicator(inst.InstalledPackage));
InstallationLog newLog = new InstallationLog();
newLog.Date = DateTime.Now;
newLog.Package = inst.InstalledPackage;
systemInstalledLogList.Add(newLog);
setSystemInstallerLog(systemInstalledLogList);
}
#endregion
}
}