OSDN Git Service

AppliStation-All,アンインストール処理を新方式(NaGetUninstall2)に変更。
[applistation/AppliStation.git] / na-get-lib / NaGet.Packages / PackageListsManager.cs
1 using System;\r
2 using System.IO;\r
3 using System.Collections.Generic;\r
4 using NaGet.Packages;\r
5 using NaGet.Packages.Install;\r
6 \r
7 namespace NaGet.Packages\r
8 {\r
9         /// <summary>\r
10         /// パッケージリスト達をひとまとめにして管理する\r
11         /// </summary>\r
12         public class PackageListsManager\r
13         {\r
14                 internal PackageList<Package> availablePkgList;\r
15                 internal PackageList<InstalledPackage> installedPkgList;\r
16                 internal PackageList<InstalledPackage> systemInstalledPkgList;\r
17                 \r
18                 /// <summary>\r
19                 /// ファイルリストから読み込まれたパッケージのリスト\r
20                 /// </summary>\r
21                 public PackageList<Package> AvailablePkgList {\r
22                         get { return availablePkgList; }\r
23                 }\r
24                 \r
25                 /// <summary>\r
26                 /// 本ソフトウェアを介してインストールされたパッケージのリスト\r
27                 /// </summary>\r
28                 public PackageList<InstalledPackage> InstalledPkgList {\r
29                         get { return installedPkgList; }\r
30                 }\r
31                 \r
32                 /// <summary>\r
33                 /// システムから検出されたパッケージのリスト\r
34                 /// </summary>\r
35                 public PackageList<InstalledPackage> SystemInstalledPkgList {\r
36                         get { return systemInstalledPkgList; }\r
37                 }\r
38                 \r
39                 /// <summary>\r
40                 /// 初期化をする。データの読み込みは明示的にLoadPackageLists()を呼び出さなければならない。\r
41                 /// </summary>\r
42                 public PackageListsManager()\r
43                 {\r
44                         availablePkgList = new PackageList<Package>();\r
45                         installedPkgList = new PackageList<InstalledPackage>();\r
46                         systemInstalledPkgList = new PackageList<InstalledPackage>();\r
47                 }\r
48                 \r
49                 #region ファイル読み書き\r
50                 \r
51                 /// <summary>\r
52                 /// ファイルを読み込んで更新する\r
53                 /// </summary>\r
54                 public void LoadPackageLists()\r
55                 {\r
56                         System.Xml.Serialization.XmlSerializer sr;\r
57                         \r
58                         // ソフトリストのパッケージリスト読み込み\r
59                         sr = new System.Xml.Serialization.XmlSerializer(typeof(PackageList<Package>));\r
60                         if (File.Exists(NaGet.Env.PackageListFile)) {\r
61                                 availablePkgList = (PackageList<Package>) NaGet.Utils.GetDeserializedObject(NaGet.Env.PackageListFile, sr);\r
62                         } else {\r
63                                 availablePkgList = new PackageList<Package>();\r
64                         }\r
65                         \r
66                         sr = new System.Xml.Serialization.XmlSerializer(typeof(PackageList<InstalledPackage>));\r
67                         if (File.Exists(NaGet.Env.ArchiveInstalledPackageListFile)) {\r
68                                 installedPkgList = (PackageList<InstalledPackage>) NaGet.Utils.GetDeserializedObject(NaGet.Env.ArchiveInstalledPackageListFile, sr);\r
69                         } else {\r
70                                 installedPkgList = new PackageList<InstalledPackage>();\r
71                         }\r
72                         \r
73                         //sr = new System.Xml.Serialization.XmlSerializer(typeof(PackageList<InstalledPackage>));\r
74                         if (File.Exists(NaGet.Env.SystemInstalledPackageListFile)) {\r
75                                 systemInstalledPkgList = (PackageList<InstalledPackage>) NaGet.Utils.GetDeserializedObject(NaGet.Env.SystemInstalledPackageListFile, sr);\r
76                         } else {\r
77                                 systemInstalledPkgList = new PackageList<InstalledPackage>();\r
78                         }\r
79                 }\r
80                 \r
81                 /// <summary>\r
82                 /// ファイルリストから読み込まれたパッケージのリスト\r
83                 /// をファイルに書き込む。\r
84                 /// </summary>\r
85                 public void SaveAvailablePackageList()\r
86                 {\r
87                         NaGet.Utils.PutSerializeObject(NaGet.Env.PackageListFile, availablePkgList);\r
88                 }\r
89                 /// <summary>\r
90                 /// 本ソフトウェアを介してインストールされたパッケージのリスト\r
91                 /// をファイルに書き込む。\r
92                 /// </summary>\r
93                 public void SaveInstalledPackageList()\r
94                 {\r
95                         NaGet.Utils.PutSerializeObject(NaGet.Env.ArchiveInstalledPackageListFile, installedPkgList);\r
96                 }\r
97                 /// <summary>\r
98                 /// システムから検出されたパッケージのリスト\r
99                 /// をファイルに書き込む。\r
100                 /// </summary>\r
101                 public void SaveSystemInstalledPackageList()\r
102                 {\r
103                         NaGet.Utils.PutSerializeObject(NaGet.Env.SystemInstalledPackageListFile, systemInstalledPkgList);\r
104                 }\r
105                 \r
106                 /// <summary>\r
107                 /// 本オブジェクトの保有しているパッケージ情報の全てをファイルに書き出す。\r
108                 /// </summary>\r
109                 public void CommitToFile()\r
110                 {\r
111                         SaveAvailablePackageList();\r
112                         SaveInstalledPackageList();\r
113                         SaveSystemInstalledPackageList();\r
114                 }\r
115                 \r
116                 #endregion\r
117                 \r
118                 #region パッケージインストール検知関連\r
119                 \r
120                 /// <summary>\r
121                 /// 本ソフトウェアを介してインストールされたパッケージを検出する。\r
122                 /// 具体的には<see cref="NaGet.Env.ArchiveProgramFiles" />\r
123                 /// で指定されたフォルダーの下を見る。\r
124                 /// </summary>\r
125                 public void DetectInstalledPkgs()\r
126                 {\r
127                         PackageList<InstalledPackage> pkgList = new PackageList<InstalledPackage>();\r
128                         if (Directory.Exists(NaGet.Env.ArchiveProgramFiles)) {\r
129                                 foreach (string path in NaGet.Utils.ExtendWildcardFile(NaGet.Env.ArchiveProgramFiles, Path.Combine("*", ".applistation.package.xml"))) {\r
130                                         pkgList.AddPackage(NaGet.Utils.GetDeserializedObject<InstalledPackage>(path));\r
131                                 }\r
132                                 this.installedPkgList = pkgList;\r
133                         }\r
134                 }\r
135                 \r
136                 /// <summary>\r
137                 /// レジストリから、コンピュータにインストールされたパッケージを検出し、\r
138                 /// インストールトリストに登録(更新)をする。このとき、\r
139                 /// インストールのログを見て可能な限りパッケージ情報を補完する。\r
140                 /// </summary>\r
141                 public void DetectSystemInstalledPkgs()\r
142                 {\r
143                         List<InstalledPackage> installedPkgList = new List<InstalledPackage>();\r
144                         List<InstallationLog>  systemInstalledLogList = getSystemInstallerLog();\r
145                         \r
146                         installedPkgList.AddRange(RegistriedUninstallers.DetectInstalledPackages(availablePkgList));\r
147                         \r
148                         // インストールのログを見て可能な限りパッケージ情報を補完する。\r
149                         for (int i = 0; i < installedPkgList.Count; i++) {\r
150                                 InstalledPackage pkg = installedPkgList[i];                             \r
151                                 int count = installedPkgList.FindAll(PackageList<InstalledPackage>.GetPredicateForPackageName(pkg.Name)).Count;\r
152 \r
153                                 foreach (InstallationLog log in systemInstalledLogList.FindAll(createPackageNamePredicator(pkg))) {\r
154                                         // 1. バージョンがアンインストール情報から取得できなかったときは無条件で登録\r
155                                         // 2. 同一名パッケージがない場合は無条件で登録\r
156                                         // 3. 複数個同一パッケージがインストールされている場合は、バージョン比較して登録。\r
157                                         if (string.IsNullOrEmpty(pkg.Version) ||\r
158                                             count < 2 ||\r
159                                             log.Package.Version == pkg.Version) {\r
160                                                 \r
161                                                 // 補完したパッケージ情報への差し替え\r
162                                                 UninstallInformation pkgUninstInfo = pkg.UninstallInfo;\r
163                                                 NaGet.Utils.FieldCopy<Package,InstalledPackage>(log.Package, ref pkg);\r
164                                                 pkg.UninstallInfo = pkgUninstInfo;\r
165                                                 if (pkg.UninstallInfo.InstallDate == null) { // インストール日時の補完\r
166                                                         pkg.UninstallInfo.InstallDate = log.Date;\r
167                                                 }\r
168                                                 \r
169                                                 break;\r
170                                         }\r
171                                 }\r
172                         }\r
173                         \r
174                         this.systemInstalledPkgList.SetPackages(installedPkgList);\r
175                 }\r
176                 \r
177                 #endregion\r
178                 \r
179                 #region パッケージ便利メソッド\r
180                 \r
181                 /// <summary>\r
182                 /// 全て(すなわち、本ソフトウェアを介してインストールされたものと、\r
183                 /// システムにインストールされたもの)のインストールされたパッケージを返す便利メソッド\r
184                 /// </summary>\r
185                 /// <returns>全てのインストールされたパッケージのイテレータ</returns>\r
186                 public IEnumerable<InstalledPackage> GetAllInstalledPackages()\r
187                 {\r
188                         return NaGet.Utils.MergeEnumerable<InstalledPackage>(\r
189                                 installedPkgList.GetEnumerator(),\r
190                                 systemInstalledPkgList.GetEnumerator()\r
191                         );\r
192                 }\r
193                 \r
194                 /// <summary>\r
195                 /// 全てのパッケージをイテレータで返す便利メソッド。\r
196                 /// </summary>\r
197                 /// <returns>パッケージのイテレータ</returns>\r
198                 public IEnumerable<Package> GetAllPackages()\r
199                 {\r
200                         return NaGet.Utils.MergeEnumerable<Package>(\r
201                                 availablePkgList.GetEnumerator(),\r
202                                 (IEnumerator<Package>) GetAllInstalledPackages().GetEnumerator()\r
203                         );\r
204                 }\r
205                 \r
206                 #endregion\r
207                 \r
208                 #region インストールログ関連\r
209                 \r
210                 /// <summary>\r
211                 /// インストールログのリストを作って返す。\r
212                 /// </summary>\r
213                 /// <returns>インストールログのリスト</returns>\r
214                 private static List<InstallationLog> getSystemInstallerLog()\r
215                 {\r
216                         List<InstallationLog> systemInstalledLogList;\r
217                         \r
218                         try {\r
219                                 systemInstalledLogList = NaGet.Utils.GetDeserializedObject<List<InstallationLog>>(NaGet.Env.SystemInstalledPackageLogFile);\r
220                         } catch (Exception) {\r
221                                 systemInstalledLogList = new List<InstallationLog>();   \r
222                         }\r
223                         \r
224                         return systemInstalledLogList;\r
225                 }\r
226                 \r
227                 /// <summary>\r
228                 /// インストールログを保存する。\r
229                 /// </summary>\r
230                 /// <param name="systemInstalledLogList">インストールログデータ</param>\r
231                 private static void setSystemInstallerLog(List<InstallationLog> systemInstalledLogList)\r
232                 {\r
233                         NaGet.Utils.PutSerializeObject(NaGet.Env.SystemInstalledPackageLogFile, systemInstalledLogList);\r
234                 }\r
235                 \r
236                 /// <summary>\r
237                 /// 指定パッケージ名に対応するログを判定するPredicate\r
238                 /// </summary>\r
239                 /// <param name="pkg">判定する指定パッケージ</param>\r
240                 /// <returns>Predicate</returns>\r
241                 private static Predicate<InstallationLog> createPackageNamePredicator(Package pkg)\r
242                 {\r
243                         return delegate(InstallationLog log) {\r
244                                 return log.Package.Name == pkg.Name;\r
245                         };\r
246                 }\r
247                 \r
248                 /// <summary>\r
249                 /// インストールログにインストール情報を追加する。\r
250                 /// ファイルへの書き込みは行われない。\r
251                 /// </summary>\r
252                 /// <remarks>過去の同一パッケージ名のログは消去される</remarks>\r
253                 /// <param name="inst">書き込むインストール情報</param>\r
254                 public void WriteInstallationLog(Installation inst)\r
255                 {\r
256                         List<InstallationLog> systemInstalledLogList = getSystemInstallerLog();\r
257                         \r
258                         // 重複は削除\r
259                         systemInstalledLogList.RemoveAll(createPackageNamePredicator(inst.InstalledPackage));\r
260                         \r
261                         InstallationLog newLog = new InstallationLog();\r
262                         newLog.Date = DateTime.Now;\r
263                         newLog.Package = inst.InstalledPackage;\r
264                         \r
265                         systemInstalledLogList.Add(newLog);\r
266                         \r
267                         setSystemInstallerLog(systemInstalledLogList);\r
268                 }\r
269                 \r
270                 #endregion\r
271         }\r
272 }\r