2 using System.Diagnostics;
\r
3 using System.Text.RegularExpressions;
\r
4 using System.Collections;
\r
5 using System.CodeDom.Compiler;
\r
8 namespace NaGet.Packages.Install
\r
11 /// Description of Uninstallation.
\r
13 public class Uninstallation
\r
18 public InstalledPackage UninstalledPackage;
\r
21 /// 外部アプリのエラー出力の受信ハンドラ
\r
23 public event EventHandler<NaGet.Utils.AnyDataEventArgs<string>> ErrorDataReceived;
\r
26 /// 外部アプリの標準出力の受信ハンドラ
\r
28 public event EventHandler<NaGet.Utils.AnyDataEventArgs<string>> OutputDataReceived;
\r
31 /// サイレントアンインストールするか否か
\r
33 public bool Silent = false;
\r
38 /// <param name="package">アンインストールするパッケージ</param>
\r
39 public Uninstallation(InstalledPackage package)
\r
41 UninstalledPackage = package;
\r
47 public bool Installed
\r
50 if ((UninstalledPackage.Type == InstallerType.ARCHIVE)
\r
51 || UninstalledPackage.Type == InstallerType.ITSELF) {
\r
52 return Directory.Exists(UninstalledPackage.UninstallInfo.InstallLocation);
\r
54 foreach (UninstallInformation info in RegistriedUninstallers.Uninstallers) {
\r
55 if (! string.IsNullOrEmpty(UninstalledPackage.UninstallerKey)) {
\r
56 Match match = Regex.Match(info.DisplayName, UninstalledPackage.UninstallerKey);
\r
58 if (match.Success) {
\r
69 /// アンインストーラー等を起動してアンインストール作業を行う
\r
71 /// <returns>アンインストーラーの終了コード</returns>
\r
72 public int Uninstall()
\r
75 throw new ApplicationException("Program not found, may be already uninstalled");
\r
79 string uninstallString = Silent? UninstalledPackage.UninstallInfo.QuietUninstallString : UninstalledPackage.UninstallInfo.UninstallString;
\r
80 if (string.IsNullOrEmpty(uninstallString)) {
\r
81 throw new ApplicationException(string.Format("Could not found {0}install script", Silent? "silent " : ""));
\r
84 if (UninstalledPackage.Type == InstallerType.ARCHIVE
\r
85 || UninstalledPackage.Type == InstallerType.ITSELF) {
\r
87 string argument = string.Format("-x \"{0}\"", UninstalledPackage.Name);
\r
88 using (Process hProcess = createExtractArchiveProcess(argument,
\r
89 this.OutputDataReceived,
\r
90 this.ErrorDataReceived)) {
\r
92 if (NaGet.Env.InstallProcessOnBackground) {
\r
94 hProcess.PriorityClass = ProcessPriorityClass.Idle;
\r
95 } catch (Exception) {}
\r
98 hProcess.WaitForExit();
\r
100 exitValue = hProcess.ExitCode;
\r
102 } else if (UninstalledPackage.UninstallInfo.WindowsInstaller &&
\r
103 Regex.Match(uninstallString.Substring("MsiExec.exe /I".Length),
\r
104 @"^\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\}$").Success) {
\r
105 string guid = uninstallString.Substring("MsiExec.exe /I".Length);
\r
106 using (Process hProcess = NaGet.Utils.ProcessStartWithOutputCapture(
\r
107 new ProcessStartInfo("msiexec", string.Format("/X{0}", guid)),
\r
108 this.OutputDataReceived,
\r
109 this.ErrorDataReceived) ) {
\r
111 if (NaGet.Env.InstallProcessOnBackground) {
\r
113 hProcess.PriorityClass = ProcessPriorityClass.Idle;
\r
114 } catch (Exception) {}
\r
117 hProcess.WaitForExit();
\r
119 exitValue = hProcess.ExitCode;
\r
121 } else if (File.Exists(uninstallString)) {
\r
123 using (Process hProcess = NaGet.Utils.ProcessStartWithOutputCapture(
\r
124 new ProcessStartInfo(uninstallString),
\r
125 this.OutputDataReceived,
\r
126 this.ErrorDataReceived) ) {
\r
128 if (NaGet.Env.InstallProcessOnBackground) {
\r
130 hProcess.PriorityClass = ProcessPriorityClass.Idle;
\r
131 } catch (Exception) {}
\r
134 hProcess.WaitForExit();
\r
136 exitValue = hProcess.ExitCode;
\r
139 ProcessStartInfo procInfo = new ProcessStartInfo(null, uninstallString);
\r
140 procInfo.UseShellExecute = false;
\r
141 procInfo.CreateNoWindow = true;
\r
142 using (NaGet.InteropServices.CreateProcessCaller p = new NaGet.InteropServices.CreateProcessCaller(procInfo)) {
\r
144 if (NaGet.Env.InstallProcessOnBackground) {
\r
146 p.PriorityClass = ProcessPriorityClass.Idle;
\r
147 } catch (Exception) {}
\r
152 exitValue = p.ExitCode;
\r
160 /// アーカイブファイルのアンインストールを行う
\r
162 /// <param name="archiveInstArgs">"archive-inst.exe"への引数</param>
\r
163 /// <param name="outputReceived">標準出力用リスナ(null可)</param>
\r
164 /// <param name="errorReceived">エラー出力用リスナ(null可)</param>
\r
165 /// <returns>実行プロセス</returns>
\r
166 private static Process createExtractArchiveProcess(string archiveInstArgs,
\r
167 EventHandler<NaGet.Utils.AnyDataEventArgs<string>> outputReceived,
\r
168 EventHandler<NaGet.Utils.AnyDataEventArgs<string>> errorReceived)
\r
170 string archiveInstExe = Path.GetFullPath("archive-inst.exe");
\r
171 if (! File.Exists(archiveInstExe)) {
\r
172 string errMsg = string.Format("\"{0}\" does not found!");
\r
173 throw new ApplicationException(errMsg,
\r
174 new FileNotFoundException(errMsg, archiveInstExe));
\r
179 ProcessStartInfo procInfo = new ProcessStartInfo(archiveInstExe, archiveInstArgs);
\r
180 procInfo.UseShellExecute = false;
\r
181 procInfo.CreateNoWindow = true;
\r
182 procInfo.WorkingDirectory = Environment.CurrentDirectory;
\r
184 return NaGet.Utils.ProcessStartWithOutputCapture(procInfo, outputReceived, errorReceived);
\r
187 public override string ToString()
\r
189 return string.Format("{0}({1})", UninstalledPackage.Name, UninstalledPackage.Version);
\r