OSDN Git Service

initial build for opensource
[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                 /// ソフトをインストールした日付\r
79                 /// </summary>\r
80                 [XmlIgnore]\r
81                 public DateTime? InstallDate = null;\r
82                 \r
83                 /// <summary>\r
84                 /// ソフトをインストールした日付、のレジストリ登録文字列表現\r
85                 /// </summary>\r
86                 [XmlElement("InstallDate")]\r
87                 public string InstallDateString {\r
88                         get { return (InstallDate != null)? InstallDate.Value.ToString("yyyyMMdd") : null; }\r
89                         set {\r
90                                 if (value == null) {\r
91                                         InstallDate = null;\r
92                                 } else if (System.Text.RegularExpressions.Regex.IsMatch(value, @"^[0-9]{8}$")) {\r
93                                         InstallDate = new DateTime(int.Parse(value.Substring(0,4)),\r
94                                                                    int.Parse(value.Substring(4,2)),\r
95                                                                    int.Parse(value.Substring(6,2)));\r
96                                 } else throw new ArgumentException("Does not match date format (YYYYMMDD)");\r
97                         }\r
98                 }\r
99                 \r
100                 /// <summary>\r
101                 /// インストール先のフォルダ\r
102                 /// </summary>\r
103                 public string InstallLocation;\r
104                 \r
105                 /// <summary>\r
106                 /// (推定の)アプリケーションの占有する容量(キロバイト単位)\r
107                 /// </summary>\r
108                 public int EstimatedSize = 0;\r
109                 \r
110                 #region 変換メソッド\r
111                 \r
112                 /// <summary>\r
113                 /// レジストリのキーからアンインストール情報を取得する\r
114                 /// </summary>\r
115                 /// <param name="regKey">アンインストール情報を示す</param>\r
116                 /// <returns>生成されたアンインストール</returns>\r
117                 public static UninstallInformation NewInstance(RegistryKey regKey)\r
118                 {\r
119                         UninstallInformation uninstInfo = new UninstallInformation();\r
120                         \r
121                         uninstInfo.DisplayName = (string) regKey.GetValue("DisplayName");\r
122                         uninstInfo.DisplayVersion = (string) regKey.GetValue("DisplayVersion", null);\r
123                         uninstInfo.Publisher = (string) regKey.GetValue("Publisher", null);\r
124                         uninstInfo.URLInfoAbout = (string) regKey.GetValue("URLInfoAbout", null);\r
125                         uninstInfo.IconPath = (string) regKey.GetValue("DisplayIcon", null);\r
126                         uninstInfo.ModifyPath = (string) regKey.GetValue("ModifyPath", null);\r
127                         uninstInfo.UninstallString = (string) regKey.GetValue("UninstallString", null);\r
128                         uninstInfo.QuietUninstallString = (string) regKey.GetValue("QuietUninstallString", null);\r
129                         uninstInfo.CanModify = ((int) regKey.GetValue("NoModify", 1)) != 1;\r
130                         uninstInfo.CanRepair = ((int) regKey.GetValue("NoRepair", 1)) != 1;\r
131                         uninstInfo.CanRemove = ((int) regKey.GetValue("NoRemove", 1)) != 1; \r
132                         uninstInfo.IsSystemComponent = ((int) regKey.GetValue("SystemComponent", 0)) > 0;\r
133                         uninstInfo.IsOSPatch = ((string) regKey.GetValue("ParentKeyName", null)) == "OperatingSystem";\r
134                         try {\r
135                                 uninstInfo.InstallDateString = (string) regKey.GetValue("InstallDate", null);\r
136                         } catch (ArgumentException) {}\r
137                         uninstInfo.InstallLocation = (string) regKey.GetValue("InstallLocation", null);\r
138                         uninstInfo.EstimatedSize = (int) regKey.GetValue("EstimatedSize", 0);\r
139                         \r
140                         PrefixWithSlowInfoCache(ref uninstInfo, regKey);\r
141                         \r
142                         return uninstInfo;\r
143                 }\r
144                 \r
145                 /// <summary>\r
146                 /// SlowInfoCacheを読み込んで情報を補完\r
147                 /// </summary>\r
148                 /// <param name="uninstInfo">アンインストール情報</param>\r
149                 /// <param name="regKey">元のレジストリキー</param>\r
150                 private static void PrefixWithSlowInfoCache(ref UninstallInformation uninstInfo, RegistryKey regKey)\r
151                 {\r
152                         try {\r
153                                 byte[] slowInfoCache;\r
154                                 \r
155                                 string arpCacheKey = string.Format(@"{0}\..\..\App Management\ARPCache\{1}", regKey.Name, System.IO.Path.GetFileName(regKey.Name));\r
156                                 arpCacheKey = NaGet.Utils.GetDotsRemovedPath(arpCacheKey);\r
157                                 slowInfoCache = (byte[]) Registry.GetValue(arpCacheKey, "SlowInfoCache", null);\r
158                                 \r
159                                 if (slowInfoCache == null || slowInfoCache.Length <= 0) {\r
160                                         arpCacheKey = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\App Management\ARPCache\"+System.IO.Path.GetFileName(regKey.Name);\r
161                                         slowInfoCache = (byte[]) Registry.GetValue(arpCacheKey, "SlowInfoCache", null);\r
162                                 }\r
163                                 \r
164                                 if (slowInfoCache != null && slowInfoCache.Length > 0) {\r
165                                         Int32 size = BitConverter.ToInt32(slowInfoCache, 0);\r
166                                         Int32 hasName = BitConverter.ToInt32(slowInfoCache, 4);\r
167                                         Int64 installSize = BitConverter.ToInt64(slowInfoCache, 8);\r
168                                         //Int64 lastUsed = BitConverter.ToInt64(slowInfoCache, 16);\r
169                                         //Int32 freq = BitConverter.ToInt32(slowInfoCache, 24);\r
170                                         \r
171                                         if (installSize > 0) {\r
172                                                 uninstInfo.EstimatedSize = (int)(installSize >> 10);\r
173                                         }\r
174                                         \r
175                                         string filename = null;\r
176                                         if (hasName != 0) {\r
177                                                 int offset = 28;\r
178                                                 int pos = offset;\r
179                                                 while (pos < slowInfoCache.Length) {\r
180                                                         if (slowInfoCache[pos] == 0) {\r
181                                                                 break;\r
182                                                         }\r
183                                                         pos += 2;\r
184                                                 }\r
185                                                 \r
186                                                 filename = System.Text.Encoding.Unicode.GetString(slowInfoCache, offset, pos-offset);\r
187                                                 \r
188                                                 if (string.IsNullOrEmpty(uninstInfo.IconPath) && System.IO.File.Exists(filename)) {\r
189                                                         uninstInfo.IconPath = filename;\r
190                                                 }\r
191                                         }\r
192                                 }\r
193                         } catch (Exception) {\r
194                         }\r
195                 }\r
196                 \r
197                 /// <summary>\r
198                 /// パッケージ情報からアンインストーラ情報を生成する\r
199                 /// </summary>\r
200                 /// <param name="pkg">パッケージ</param>\r
201                 /// <returns>生成されたアンインストール</returns>\r
202                 public static UninstallInformation NewInstance(Package pkg)\r
203                 {\r
204                         UninstallInformation uninstInfo = new UninstallInformation();\r
205                         \r
206                         uninstInfo.DisplayName = pkg.Name;\r
207                         uninstInfo.DisplayVersion = pkg.Version;\r
208                         uninstInfo.Publisher = pkg.Author;\r
209                         uninstInfo.URLInfoAbout = pkg.Url.Href;\r
210                         uninstInfo.IconPath = null; // TODO\r
211                         uninstInfo.ModifyPath = null;\r
212                         uninstInfo.UninstallString = null; // TODO\r
213                         uninstInfo.CanModify = false;\r
214                         uninstInfo.CanRepair = false;\r
215                         uninstInfo.CanRemove = true;\r
216                         uninstInfo.IsSystemComponent = false;\r
217                         uninstInfo.IsOSPatch = false;\r
218                         uninstInfo.InstallLocation = null;\r
219                         uninstInfo.InstallDate = null;\r
220                         uninstInfo.EstimatedSize = 0;\r
221                         \r
222                         return uninstInfo;\r
223                 }\r
224                 \r
225                 #endregion\r
226         }\r
227 }\r