2 using System.Xml.Serialization;
\r
3 using Microsoft.Win32;
\r
5 namespace NaGet.Packages.Install
\r
8 /// アンインストール情報の抽象化クラス
\r
10 public class UninstallInformation
\r
15 public string DisplayName;
\r
18 /// バージョン。DisplayVersion
\r
20 public string DisplayVersion;
\r
25 public string Publisher;
\r
28 /// アイコンのパス。DisplayIcon
\r
30 public string IconPath;
\r
33 /// 「変更」・「修復」のコマンド文字列。ModifyPath
\r
35 public string ModifyPath;
\r
38 /// 「アンインストール」のコマンド文字列。UninstallString
\r
40 public string UninstallString;
\r
43 /// サイレントアンインストールのコマンド文字列。QuietUninstallString
\r
45 public string QuietUninstallString;
\r
50 public string URLInfoAbout;
\r
53 /// 「変更」ができるか否かのフラグ。NoModifyの逆(きちんと動かない??)
\r
55 public bool CanModify;
\r
58 /// 「修復」ができるか否かのフラグ。NoRepairの逆(きちんと動かない??)
\r
60 public bool CanRepair;
\r
63 /// 「アンインストール」ができるか否かのフラグ。NoRemoveの逆
\r
65 public bool CanRemove = true;
\r
70 public bool IsSystemComponent;
\r
75 public bool IsOSPatch;
\r
78 /// アンインストールにmsiexecを使うか否か
\r
80 public bool WindowsInstaller = false;
\r
86 public DateTime? InstallDate = null;
\r
89 /// ソフトをインストールした日付、のレジストリ登録文字列表現
\r
91 [XmlElement("InstallDate")]
\r
92 public string InstallDateString {
\r
93 get { return (InstallDate != null)? InstallDate.Value.ToString("yyyyMMdd") : null; }
\r
95 if (value == 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
108 public string InstallLocation;
\r
111 /// (推定の)アプリケーションの占有する容量(キロバイト単位)
\r
113 public int EstimatedSize = 0;
\r
118 /// レジストリのキーからアンインストール情報を取得する
\r
120 /// <param name="regKey">アンインストール情報を示す</param>
\r
121 /// <returns>生成されたアンインストール</returns>
\r
122 public static UninstallInformation NewInstance(RegistryKey regKey)
\r
124 UninstallInformation uninstInfo = new UninstallInformation();
\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
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
146 PrefixWithSlowInfoCache(ref uninstInfo, regKey);
\r
152 /// SlowInfoCacheを読み込んで情報を補完
\r
154 /// <param name="uninstInfo">アンインストール情報</param>
\r
155 /// <param name="regKey">元のレジストリキー</param>
\r
156 private static void PrefixWithSlowInfoCache(ref UninstallInformation uninstInfo, RegistryKey regKey)
\r
159 byte[] slowInfoCache;
\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
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
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
177 if (installSize > 0) {
\r
178 uninstInfo.EstimatedSize = (int)(installSize >> 10);
\r
181 string filename = null;
\r
182 if (hasName != 0) {
\r
185 while (pos < slowInfoCache.Length) {
\r
186 if (slowInfoCache[pos] == 0) {
\r
192 filename = System.Text.Encoding.Unicode.GetString(slowInfoCache, offset, pos-offset);
\r
194 if (string.IsNullOrEmpty(uninstInfo.IconPath) && System.IO.File.Exists(filename)) {
\r
195 uninstInfo.IconPath = filename;
\r
199 } catch (Exception) {
\r
204 /// パッケージ情報からアンインストーラー情報を生成する
\r
206 /// <param name="pkg">パッケージ</param>
\r
207 /// <returns>生成されたアンインストール</returns>
\r
208 public static UninstallInformation NewInstance(Package pkg)
\r
210 UninstallInformation uninstInfo = new UninstallInformation();
\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