using System; using System.Diagnostics; using System.Text.RegularExpressions; using System.Collections; using System.CodeDom.Compiler; using System.IO; namespace NaGet.Packages.Install { /// /// Description of Uninstallation. /// public class Uninstallation { /// /// アンインストールするパッケージ /// public InstalledPackage UninstalledPackage; /// /// 外部アプリのエラー出力の受信ハンドラ /// public event EventHandler> ErrorDataReceived; /// /// 外部アプリの標準出力の受信ハンドラ /// public event EventHandler> OutputDataReceived; /// /// サイレントアンインストールするか否か /// public bool Silent = false; /// /// コンストラクタ /// /// アンインストールするパッケージ public Uninstallation(InstalledPackage package) { UninstalledPackage = package; } /// /// インストールされた状態か否か /// public bool Installed { get { if ((UninstalledPackage.Type == InstallerType.ARCHIVE) || UninstalledPackage.Type == InstallerType.ITSELF) { return Directory.Exists(UninstalledPackage.UninstallInfo.InstallLocation); } else { foreach (UninstallInformation info in RegistriedUninstallers.Uninstallers) { if (! string.IsNullOrEmpty(UninstalledPackage.UninstallerKey)) { Match match = Regex.Match(info.DisplayName, UninstalledPackage.UninstallerKey); if (match.Success) { return true; } } } } return false; } } /// /// アンインストーラー等を起動してアンインストール作業を行う /// /// アンインストーラーの終了コード public int Uninstall() { if (! Installed) { throw new ApplicationException("Program not found, may be already uninstalled"); } int exitValue = 0; string uninstallString = Silent? UninstalledPackage.UninstallInfo.QuietUninstallString : UninstalledPackage.UninstallInfo.UninstallString; if (string.IsNullOrEmpty(uninstallString)) { throw new ApplicationException(string.Format("Could not found {0}install script", Silent? "silent " : "")); } if (UninstalledPackage.Type == InstallerType.ARCHIVE || UninstalledPackage.Type == InstallerType.ITSELF) { string argument = string.Format("-x \"{0}\"", UninstalledPackage.Name); using (Process hProcess = createExtractArchiveProcess(argument, this.OutputDataReceived, this.ErrorDataReceived)) { if (NaGet.Env.InstallProcessOnBackground) { try { hProcess.PriorityClass = ProcessPriorityClass.Idle; } catch (Exception) {} } hProcess.WaitForExit(); exitValue = hProcess.ExitCode; } } else if (UninstalledPackage.UninstallInfo.WindowsInstaller && Regex.Match(uninstallString.Substring("MsiExec.exe /I".Length), @"^\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\}$").Success) { string guid = uninstallString.Substring("MsiExec.exe /I".Length); using (Process hProcess = NaGet.Utils.ProcessStartWithOutputCapture( new ProcessStartInfo("msiexec", string.Format("/X{0}", guid)), this.OutputDataReceived, this.ErrorDataReceived) ) { if (NaGet.Env.InstallProcessOnBackground) { try { hProcess.PriorityClass = ProcessPriorityClass.Idle; } catch (Exception) {} } hProcess.WaitForExit(); exitValue = hProcess.ExitCode; } } else if (File.Exists(uninstallString)) { // 単独のファイルの場合 using (Process hProcess = NaGet.Utils.ProcessStartWithOutputCapture( new ProcessStartInfo(uninstallString), this.OutputDataReceived, this.ErrorDataReceived) ) { if (NaGet.Env.InstallProcessOnBackground) { try { hProcess.PriorityClass = ProcessPriorityClass.Idle; } catch (Exception) {} } hProcess.WaitForExit(); exitValue = hProcess.ExitCode; } } else { ProcessStartInfo procInfo = new ProcessStartInfo(null, uninstallString); procInfo.UseShellExecute = false; procInfo.CreateNoWindow = true; using (NaGet.InteropServices.CreateProcessCaller p = new NaGet.InteropServices.CreateProcessCaller(procInfo)) { if (NaGet.Env.InstallProcessOnBackground) { try { p.PriorityClass = ProcessPriorityClass.Idle; } catch (Exception) {} } p.WaitForExit(); exitValue = p.ExitCode; } } return exitValue; } /// /// アーカイブファイルのアンインストールを行う /// /// "archive-inst.exe"への引数 /// 標準出力用リスナ(null可) /// エラー出力用リスナ(null可) /// 実行プロセス private static Process createExtractArchiveProcess(string archiveInstArgs, EventHandler> outputReceived, EventHandler> errorReceived) { string archiveInstExe = Path.GetFullPath("archive-inst.exe"); if (! File.Exists(archiveInstExe)) { string errMsg = string.Format("\"{0}\" does not found!"); throw new ApplicationException(errMsg, new FileNotFoundException(errMsg, archiveInstExe)); } ProcessStartInfo procInfo = new ProcessStartInfo(archiveInstExe, archiveInstArgs); procInfo.UseShellExecute = false; procInfo.CreateNoWindow = true; procInfo.WorkingDirectory = Environment.CurrentDirectory; return NaGet.Utils.ProcessStartWithOutputCapture(procInfo, outputReceived, errorReceived); } public override string ToString() { return string.Format("{0}({1})", UninstalledPackage.Name, UninstalledPackage.Version); } } }