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 } }