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