OSDN Git Service

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