using System;
using System.Xml.Serialization;
using Microsoft.Win32;
namespace NaGet.Packages.Install
{
///
/// アンインストール情報の抽象化クラス
///
public class UninstallInformation
{
///
/// 名称。DisplayName
///
public string DisplayName;
///
/// バージョン。DisplayVersion
///
public string DisplayVersion;
///
/// 作者。Publisher
///
public string Publisher;
///
/// アイコンのパス。DisplayIcon
///
public string IconPath;
///
/// 「変更」・「修復」のコマンド文字列。ModifyPath
///
public string ModifyPath;
///
/// 「アンインストール」のコマンド文字列。UninstallString
///
public string UninstallString;
///
/// サイレントアンインストールのコマンド文字列。QuietUninstallString
///
public string QuietUninstallString;
///
/// 発行元のURL
///
public string URLInfoAbout;
///
/// 「変更」ができるか否かのフラグ。NoModifyの逆(きちんと動かない??)
///
public bool CanModify = false;
///
/// 「修復」ができるか否かのフラグ。NoRepairの逆(きちんと動かない??)
///
public bool CanRepair = false;
///
/// 「アンインストール」ができるか否かのフラグ。NoRemoveの逆
///
public bool CanRemove = true;
///
/// システムコンポーネントか否か
///
public bool IsSystemComponent = false;
///
/// OSの更新パッチか否か。
///
public bool IsOSPatch = false;
///
/// アンインストールにmsiexecを使うか否か
///
public bool WindowsInstaller = false;
///
/// ソフトをインストールした日付
///
[XmlIgnore]
public DateTime? InstallDate = null;
///
/// ソフトをインストールした日付、のレジストリ登録文字列表現
///
[XmlElement("InstallDate")]
public string InstallDateString {
get { return (InstallDate != null)? InstallDate.Value.ToString("yyyyMMdd") : null; }
set {
if ((! string.IsNullOrEmpty(value)) &&
System.Text.RegularExpressions.Regex.IsMatch(value, @"^[0-9]{8}$")) {
try {
InstallDate = new DateTime(
int.Parse(value.Substring(0,4)),
int.Parse(value.Substring(4,2)),
int.Parse(value.Substring(6,2))
);
} catch (Exception) {
}
} else {
InstallDate = null;
}
}
}
///
/// インストール先のフォルダー
///
public string InstallLocation;
///
/// (推定の)アプリケーションの占有する容量(キロバイト単位)
///
public int EstimatedSize = 0;
#region 変換メソッド
///
/// レジストリのキーからアンインストール情報を取得する
///
/// アンインストール情報を示す
/// 生成されたアンインストール
public static UninstallInformation NewInstance(RegistryKey regKey)
{
UninstallInformation uninstInfo = new UninstallInformation();
uninstInfo.DisplayName = (regKey.GetValue("DisplayName") as string) ?? string.Empty;
uninstInfo.DisplayVersion = regKey.GetValue("DisplayVersion", null) as string;
uninstInfo.Publisher = regKey.GetValue("Publisher", null) as string;
uninstInfo.URLInfoAbout = regKey.GetValue("URLInfoAbout", null) as string;
uninstInfo.IconPath = regKey.GetValue("DisplayIcon", null) as string;
uninstInfo.ModifyPath = regKey.GetValue("ModifyPath", null) as string;
uninstInfo.UninstallString = regKey.GetValue("UninstallString", null) as string;
uninstInfo.QuietUninstallString = regKey.GetValue("QuietUninstallString", null) as string;
try {
uninstInfo.CanModify = ((int) regKey.GetValue("NoModify", 1)) != 1;
} catch (InvalidCastException) {}
try {
uninstInfo.CanRepair = ((int) regKey.GetValue("NoRepair", 1)) != 1;
} catch (InvalidCastException) {}
try {
uninstInfo.CanRemove = ((int) regKey.GetValue("NoRemove", 1)) != 1;
} catch (InvalidCastException) {}
try {
uninstInfo.WindowsInstaller = ((int) regKey.GetValue("WindowsInstaller", 0)) == 1;
} catch (InvalidCastException) {}
try {
uninstInfo.IsSystemComponent = ((int) regKey.GetValue("SystemComponent", 0)) > 0;
} catch (InvalidCastException) {}
uninstInfo.IsOSPatch = (regKey.GetValue("ParentKeyName", null) as string) == "OperatingSystem";
uninstInfo.InstallDateString = regKey.GetValue("InstallDate", null) as string;
uninstInfo.InstallLocation = regKey.GetValue("InstallLocation", null) as string;
try {
uninstInfo.EstimatedSize = (int) regKey.GetValue("EstimatedSize", 0);
} catch (InvalidCastException) {}
PrefixWithSlowInfoCache(ref uninstInfo, regKey);
return uninstInfo;
}
///
/// SlowInfoCacheを読み込んで情報を補完
///
/// アンインストール情報
/// 元のレジストリキー
private static void PrefixWithSlowInfoCache(ref UninstallInformation uninstInfo, RegistryKey regKey)
{
try {
byte[] slowInfoCache;
string arpCacheKey = string.Format(@"{0}\..\..\App Management\ARPCache\{1}", regKey.Name, System.IO.Path.GetFileName(regKey.Name));
arpCacheKey = NaGet.Utils.GetDotsRemovedPath(arpCacheKey);
slowInfoCache = (byte[]) Registry.GetValue(arpCacheKey, "SlowInfoCache", null);
if (slowInfoCache == null || slowInfoCache.Length <= 0) {
arpCacheKey = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\App Management\ARPCache\"+System.IO.Path.GetFileName(regKey.Name);
slowInfoCache = (byte[]) Registry.GetValue(arpCacheKey, "SlowInfoCache", null);
}
if (slowInfoCache != null && slowInfoCache.Length > 0) {
Int32 size = BitConverter.ToInt32(slowInfoCache, 0);
Int32 hasName = BitConverter.ToInt32(slowInfoCache, 4);
Int64 installSize = BitConverter.ToInt64(slowInfoCache, 8);
//Int64 lastUsed = BitConverter.ToInt64(slowInfoCache, 16);
//Int32 freq = BitConverter.ToInt32(slowInfoCache, 24);
if (installSize > 0) {
uninstInfo.EstimatedSize = (int)(installSize >> 10);
}
string filename = null;
if (hasName != 0) {
int offset = 28;
int pos = offset;
while (pos < slowInfoCache.Length) {
if (slowInfoCache[pos] == 0) {
break;
}
pos += 2;
}
filename = System.Text.Encoding.Unicode.GetString(slowInfoCache, offset, pos-offset);
if (string.IsNullOrEmpty(uninstInfo.IconPath) && System.IO.File.Exists(filename)) {
uninstInfo.IconPath = filename;
}
}
}
} catch (Exception) {
}
}
///
/// パッケージ情報からアンインストーラー情報を生成する
///
/// パッケージ
/// 生成されたアンインストール
public static UninstallInformation NewInstance(Package pkg)
{
UninstallInformation uninstInfo = new UninstallInformation();
uninstInfo.DisplayName = pkg.Name;
uninstInfo.DisplayVersion = pkg.Version;
uninstInfo.Publisher = pkg.Author;
uninstInfo.URLInfoAbout = (pkg.Url != null)? pkg.Url.Href : null;
uninstInfo.IconPath = null; // TODO
uninstInfo.ModifyPath = null;
uninstInfo.UninstallString = null; // TODO
uninstInfo.CanModify = false;
uninstInfo.CanRepair = false;
uninstInfo.CanRemove = true;
uninstInfo.WindowsInstaller = false;
uninstInfo.IsSystemComponent = false;
uninstInfo.IsOSPatch = false;
uninstInfo.InstallLocation = null;
uninstInfo.InstallDate = null;
uninstInfo.EstimatedSize = 0;
return uninstInfo;
}
#endregion
}
}