OSDN Git Service

AppliStation,サイレントインストールのロジック部分とall-get.exeからの部分を書いた
[applistation/AppliStation.git] / na-get-lib / NaGet.Packages.Install / Uninstallation.cs
1 using System;\r
2 using System.Diagnostics;\r
3 using System.Text.RegularExpressions;\r
4 using System.Collections;\r
5 using System.CodeDom.Compiler;\r
6 using System.IO;\r
7 \r
8 namespace NaGet.Packages.Install\r
9 {\r
10         /// <summary>\r
11         /// Description of Uninstallation.\r
12         /// </summary>\r
13         public class Uninstallation\r
14         {\r
15                 /// <summary>\r
16                 /// アンインストールするパッケージ\r
17                 /// </summary>\r
18                 public InstalledPackage UninstalledPackage;\r
19                 \r
20                 /// <summary>\r
21                 /// 外部アプリのエラー出力の受信ハンドラ\r
22                 /// </summary>\r
23                 public event EventHandler<NaGet.Utils.AnyDataEventArgs<string>> ErrorDataReceived;\r
24                 \r
25                 /// <summary>\r
26                 /// 外部アプリの標準出力の受信ハンドラ\r
27                 /// </summary>\r
28                 public event EventHandler<NaGet.Utils.AnyDataEventArgs<string>> OutputDataReceived;\r
29                 \r
30                 /// <summary>\r
31                 /// サイレントアンインストールするか否か\r
32                 /// </summary>\r
33                 public bool Silent = false;\r
34                 \r
35                 /// <summary>\r
36                 /// コンストラクタ\r
37                 /// </summary>\r
38                 /// <param name="package">アンインストールするパッケージ</param>\r
39                 public Uninstallation(InstalledPackage package)\r
40                 {\r
41                         UninstalledPackage = package;\r
42                 }\r
43                 \r
44                 /// <summary>\r
45                 /// インストールされた状態か否か\r
46                 /// </summary>\r
47                 public bool Installed\r
48                 {\r
49                         get {\r
50                                 if (Directory.Exists(UninstalledPackage.UninstallInfo.InstallLocation)) {\r
51                                         return true;\r
52                                 } else if (UninstalledPackage.Type == InstallerType.ARCHIVE) {\r
53                                         return false;\r
54                                 }\r
55                                 \r
56                                 foreach (UninstallInformation info in RegistriedUninstallers.Uninstallers) {\r
57                                         Match match = Regex.Match(info.DisplayName, UninstalledPackage.UninstallerKey);\r
58                                         \r
59                                         if (match.Success) {\r
60                                                 return true;\r
61                                         }\r
62                                 }\r
63                                 return false;\r
64                         }\r
65                 }\r
66                 \r
67                 /// <summary>\r
68                 /// アンインストーラ等を起動してアンインストール作業を行う\r
69                 /// </summary>\r
70                 /// <returns>アンインストーラの終了コード</returns>\r
71                 public int Uninstall()\r
72                 {\r
73                         if (! Installed) {\r
74                                 throw new ApplicationException("Program not found, may be already uninstalled");\r
75                         }\r
76                         \r
77                         int exitValue = 0;\r
78                         string uninstallString = Silent? UninstalledPackage.UninstallInfo.QuietUninstallString : UninstalledPackage.UninstallInfo.UninstallString;\r
79                         if (string.IsNullOrEmpty(uninstallString)) {\r
80                                 throw new ApplicationException(string.Format("Could not found {0}install script", Silent? "silent " : ""));\r
81                         }\r
82                         \r
83                         if (UninstalledPackage.UninstallInfo.WindowsInstaller &&\r
84                             Regex.Match(uninstallString.Substring("MsiExec.exe /I".Length),\r
85                                         @"^\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\}$").Success) {\r
86                                 string guid = uninstallString.Substring("MsiExec.exe /I".Length);\r
87                                 using (Process hProcess = NaGet.Utils.ProcessStartWithOutputCapture(\r
88                                         new ProcessStartInfo("msiexec", string.Format("/X{0}", guid)),\r
89                                         NaGet.Utils.ConvertToDataReceivedEventHandler(OutputDataReceived),\r
90                                         NaGet.Utils.ConvertToDataReceivedEventHandler(ErrorDataReceived)) ) {\r
91                                         \r
92                                         hProcess.WaitForExit();\r
93                                         \r
94                                         exitValue = hProcess.ExitCode;\r
95                                 }\r
96                         } else if (File.Exists(uninstallString)) {\r
97                                 // 単独のファイルの場合\r
98                                 using (Process hProcess = NaGet.Utils.ProcessStartWithOutputCapture(\r
99                                         new ProcessStartInfo(uninstallString),\r
100                                         NaGet.Utils.ConvertToDataReceivedEventHandler(OutputDataReceived),\r
101                                         NaGet.Utils.ConvertToDataReceivedEventHandler(ErrorDataReceived)) ) {\r
102                                         \r
103                                         hProcess.WaitForExit();\r
104                                         \r
105                                         exitValue = hProcess.ExitCode;\r
106                                 }\r
107                         } else {\r
108                                 ProcessStartInfo procInfo = new ProcessStartInfo(null, uninstallString);\r
109                                 procInfo.UseShellExecute = false;\r
110                                 if (UninstalledPackage.Type == InstallerType.ARCHIVE) {\r
111                                         procInfo.CreateNoWindow = true;\r
112                                 }\r
113                                 using (NaGet.InteropServices.CreateProcessCaller p = new NaGet.InteropServices.CreateProcessCaller(procInfo)) {\r
114                                         p.WaitForExit();\r
115                                         \r
116                                         exitValue = p.ExitCode;\r
117                                 }\r
118                         }\r
119                         \r
120                         return exitValue;\r
121                 }\r
122                 \r
123                 public override string ToString()\r
124                 {\r
125                         return string.Format("{0}({1})", UninstalledPackage.Name, UninstalledPackage.Version);\r
126                 }\r
127         }\r
128 }\r