OSDN Git Service

na-get-lib,依存関係解決関数群を微修正
[applistation/AppliStation.git] / na-get-lib / NaGet.Packages.Install / UninstallInformation.cs
1 using System;\r
2 using System.Xml.Serialization;\r
3 using Microsoft.Win32;\r
4 \r
5 namespace NaGet.Packages.Install\r
6 {\r
7         /// <summary>\r
8         /// アンインストール情報の抽象化クラス\r
9         /// </summary>\r
10         public class UninstallInformation\r
11         {\r
12                 /// <summary>\r
13                 /// 名称。DisplayName\r
14                 /// </summary>\r
15                 public string DisplayName;\r
16                 \r
17                 /// <summary>\r
18                 /// バージョン。DisplayVersion\r
19                 /// </summary>\r
20                 public string DisplayVersion;\r
21                 \r
22                 /// <summary>\r
23                 /// 作者。Publisher\r
24                 /// </summary>\r
25                 public string Publisher;\r
26                 \r
27                 /// <summary>\r
28                 /// アイコンのパス。DisplayIcon\r
29                 /// </summary>\r
30                 public string IconPath;\r
31                 \r
32                 /// <summary>\r
33                 /// 「変更」・「修復」のコマンド文字列。ModifyPath\r
34                 /// </summary>\r
35                 public string ModifyPath;\r
36                 \r
37                 /// <summary>\r
38                 /// 「アンインストール」のコマンド文字列。UninstallString\r
39                 /// </summary>\r
40                 public string UninstallString;\r
41                 \r
42                 /// <summary>\r
43                 /// サイレントアンインストールのコマンド文字列。QuietUninstallString\r
44                 /// </summary>\r
45                 public string QuietUninstallString;\r
46                 \r
47                 /// <summary>\r
48                 /// 発行元のURL\r
49                 /// </summary>\r
50                 public string URLInfoAbout;\r
51                 \r
52                 /// <summary>\r
53                 /// 「変更」ができるか否かのフラグ。NoModifyの逆(きちんと動かない??)\r
54                 /// </summary>\r
55                 public bool CanModify;\r
56                 \r
57                 /// <summary>\r
58                 /// 「修復」ができるか否かのフラグ。NoRepairの逆(きちんと動かない??)\r
59                 /// </summary>\r
60                 public bool CanRepair;\r
61                 \r
62                 /// <summary>\r
63                 /// 「アンインストール」ができるか否かのフラグ。NoRemoveの逆\r
64                 /// </summary>\r
65                 public bool CanRemove = true;\r
66                 \r
67                 /// <summary>\r
68                 /// システムコンポーネントか否か\r
69                 /// </summary>\r
70                 public bool IsSystemComponent;\r
71                 \r
72                 /// <summary>\r
73                 /// OSの更新パッチか否か。\r
74                 /// </summary>\r
75                 public bool IsOSPatch;\r
76                 \r
77                 /// <summary>\r
78                 /// アンインストールにmsiexecを使うか否か\r
79                 /// </summary>\r
80                 public bool WindowsInstaller = false;\r
81                 \r
82                 /// <summary>\r
83                 /// ソフトをインストールした日付\r
84                 /// </summary>\r
85                 [XmlIgnore]\r
86                 public DateTime? InstallDate = null;\r
87                 \r
88                 /// <summary>\r
89                 /// ソフトをインストールした日付、のレジストリ登録文字列表現\r
90                 /// </summary>\r
91                 [XmlElement("InstallDate")]\r
92                 public string InstallDateString {\r
93                         get { return (InstallDate != null)? InstallDate.Value.ToString("yyyyMMdd") : null; }\r
94                         set {\r
95                                 if (value == null) {\r
96                                         InstallDate = null;\r
97                                 } else if (System.Text.RegularExpressions.Regex.IsMatch(value, @"^[0-9]{8}$")) {\r
98                                         InstallDate = new DateTime(int.Parse(value.Substring(0,4)),\r
99                                                                    int.Parse(value.Substring(4,2)),\r
100                                                                    int.Parse(value.Substring(6,2)));\r
101                                 } else throw new ArgumentException("Does not match date format (YYYYMMDD)");\r
102                         }\r
103                 }\r
104                 \r
105                 /// <summary>\r
106                 /// インストール先のフォルダ\r
107                 /// </summary>\r
108                 public string InstallLocation;\r
109                 \r
110                 /// <summary>\r
111                 /// (推定の)アプリケーションの占有する容量(キロバイト単位)\r
112                 /// </summary>\r
113                 public int EstimatedSize = 0;\r
114                 \r
115                 #region 変換メソッド\r
116                 \r
117                 /// <summary>\r
118                 /// レジストリのキーからアンインストール情報を取得する\r
119                 /// </summary>\r
120                 /// <param name="regKey">アンインストール情報を示す</param>\r
121                 /// <returns>生成されたアンインストール</returns>\r
122                 public static UninstallInformation NewInstance(RegistryKey regKey)\r
123                 {\r
124                         UninstallInformation uninstInfo = new UninstallInformation();\r
125                         \r
126                         uninstInfo.DisplayName = (string) regKey.GetValue("DisplayName");\r
127                         uninstInfo.DisplayVersion = (string) regKey.GetValue("DisplayVersion", null);\r
128                         uninstInfo.Publisher = (string) regKey.GetValue("Publisher", null);\r
129                         uninstInfo.URLInfoAbout = (string) regKey.GetValue("URLInfoAbout", null);\r
130                         uninstInfo.IconPath = (string) regKey.GetValue("DisplayIcon", null);\r
131                         uninstInfo.ModifyPath = (string) regKey.GetValue("ModifyPath", null);\r
132                         uninstInfo.UninstallString = (string) regKey.GetValue("UninstallString", null);\r
133                         uninstInfo.QuietUninstallString = (string) regKey.GetValue("QuietUninstallString", null);\r
134                         uninstInfo.CanModify = ((int) regKey.GetValue("NoModify", 1)) != 1;\r
135                         uninstInfo.CanRepair = ((int) regKey.GetValue("NoRepair", 1)) != 1;\r
136                         uninstInfo.CanRemove = ((int) regKey.GetValue("NoRemove", 1)) != 1; \r
137                         uninstInfo.WindowsInstaller = ((int) regKey.GetValue("WindowsInstaller", 0)) == 1; \r
138                         uninstInfo.IsSystemComponent = ((int) regKey.GetValue("SystemComponent", 0)) > 0;\r
139                         uninstInfo.IsOSPatch = ((string) regKey.GetValue("ParentKeyName", null)) == "OperatingSystem";\r
140                         try {\r
141                                 uninstInfo.InstallDateString = (string) regKey.GetValue("InstallDate", null);\r
142                         } catch (ArgumentException) {}\r
143                         uninstInfo.InstallLocation = (string) regKey.GetValue("InstallLocation", null);\r
144                         uninstInfo.EstimatedSize = (int) regKey.GetValue("EstimatedSize", 0);\r
145                         \r
146                         PrefixWithSlowInfoCache(ref uninstInfo, regKey);\r
147                         \r
148                         return uninstInfo;\r
149                 }\r
150                 \r
151                 /// <summary>\r
152                 /// SlowInfoCacheを読み込んで情報を補完\r
153                 /// </summary>\r
154                 /// <param name="uninstInfo">アンインストール情報</param>\r
155                 /// <param name="regKey">元のレジストリキー</param>\r
156                 private static void PrefixWithSlowInfoCache(ref UninstallInformation uninstInfo, RegistryKey regKey)\r
157                 {\r
158                         try {\r
159                                 byte[] slowInfoCache;\r
160                                 \r
161                                 string arpCacheKey = string.Format(@"{0}\..\..\App Management\ARPCache\{1}", regKey.Name, System.IO.Path.GetFileName(regKey.Name));\r
162                                 arpCacheKey = NaGet.Utils.GetDotsRemovedPath(arpCacheKey);\r
163                                 slowInfoCache = (byte[]) Registry.GetValue(arpCacheKey, "SlowInfoCache", null);\r
164                                 \r
165                                 if (slowInfoCache == null || slowInfoCache.Length <= 0) {\r
166                                         arpCacheKey = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\App Management\ARPCache\"+System.IO.Path.GetFileName(regKey.Name);\r
167                                         slowInfoCache = (byte[]) Registry.GetValue(arpCacheKey, "SlowInfoCache", null);\r
168                                 }\r
169                                 \r
170                                 if (slowInfoCache != null && slowInfoCache.Length > 0) {\r
171                                         Int32 size = BitConverter.ToInt32(slowInfoCache, 0);\r
172                                         Int32 hasName = BitConverter.ToInt32(slowInfoCache, 4);\r
173                                         Int64 installSize = BitConverter.ToInt64(slowInfoCache, 8);\r
174                                         //Int64 lastUsed = BitConverter.ToInt64(slowInfoCache, 16);\r
175                                         //Int32 freq = BitConverter.ToInt32(slowInfoCache, 24);\r
176                                         \r
177                                         if (installSize > 0) {\r
178                                                 uninstInfo.EstimatedSize = (int)(installSize >> 10);\r
179                                         }\r
180                                         \r
181                                         string filename = null;\r
182                                         if (hasName != 0) {\r
183                                                 int offset = 28;\r
184                                                 int pos = offset;\r
185                                                 while (pos < slowInfoCache.Length) {\r
186                                                         if (slowInfoCache[pos] == 0) {\r
187                                                                 break;\r
188                                                         }\r
189                                                         pos += 2;\r
190                                                 }\r
191                                                 \r
192                                                 filename = System.Text.Encoding.Unicode.GetString(slowInfoCache, offset, pos-offset);\r
193                                                 \r
194                                                 if (string.IsNullOrEmpty(uninstInfo.IconPath) && System.IO.File.Exists(filename)) {\r
195                                                         uninstInfo.IconPath = filename;\r
196                                                 }\r
197                                         }\r
198                                 }\r
199                         } catch (Exception) {\r
200                         }\r
201                 }\r
202                 \r
203                 /// <summary>\r
204                 /// パッケージ情報からアンインストーラ情報を生成する\r
205                 /// </summary>\r
206                 /// <param name="pkg">パッケージ</param>\r
207                 /// <returns>生成されたアンインストール</returns>\r
208                 public static UninstallInformation NewInstance(Package pkg)\r
209                 {\r
210                         UninstallInformation uninstInfo = new UninstallInformation();\r
211                         \r
212                         uninstInfo.DisplayName = pkg.Name;\r
213                         uninstInfo.DisplayVersion = pkg.Version;\r
214                         uninstInfo.Publisher = pkg.Author;\r
215                         uninstInfo.URLInfoAbout = pkg.Url.Href;\r
216                         uninstInfo.IconPath = null; // TODO\r
217                         uninstInfo.ModifyPath = null;\r
218                         uninstInfo.UninstallString = null; // TODO\r
219                         uninstInfo.CanModify = false;\r
220                         uninstInfo.CanRepair = false;\r
221                         uninstInfo.CanRemove = true;\r
222                         uninstInfo.WindowsInstaller = false;\r
223                         uninstInfo.IsSystemComponent = false;\r
224                         uninstInfo.IsOSPatch = false;\r
225                         uninstInfo.InstallLocation = null;\r
226                         uninstInfo.InstallDate = null;\r
227                         uninstInfo.EstimatedSize = 0;\r
228                         \r
229                         return uninstInfo;\r
230                 }\r
231                 \r
232                 #endregion\r
233         }\r
234 }\r