Update msvc README file.
[mono.git] / mcs / tools / installutil / installutil.cs
1 //
2 // Authors:
3 //   Miguel de Icaza (miguel@novell.com)
4 //
5 // (C) 2007 Novell, Inc
6 //
7
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System;
30 using System.IO;
31 using System.Collections;
32 using System.ComponentModel;
33 using System.Reflection;
34 using System.Configuration.Install;
35
36 public class InstallUtil {
37
38         static bool showcallstack = false;
39         static bool logtoconsole = false;
40         static string assembly = null;
41         
42         static void ShowHelpForAssembly (string assembly)
43         {
44                 Console.WriteLine ("Help for assembly not implemented");
45         }
46         
47         static void ShowHelp ()
48         {
49                 Console.WriteLine ("installutil -- Installs Assemblies that use System.Configuration.Install");
50                 Console.WriteLine ("Usage is: installutil commands\n");
51                 Console.WriteLine ("\n" + 
52                                    "   /help            Shows help\n" +
53                                    "   /help ASSEM      Shows help for the given assembly\n" +
54                                    "   /logfile[=out]   Specifies a log file\n" +
55                                    "   /uninstall ASSEM Uninstall the given assembly\n");
56         }
57
58         static void Call (Installer instance, string method, object arg)
59         {
60                 Console.WriteLine ("M: " + method);
61                 MethodInfo mi = typeof (Installer).GetMethod (method, BindingFlags.Public|BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.Static);
62                 mi.Invoke (instance, new object [] { arg });
63         }
64
65         static void Error (string st)
66         {
67                 Console.Error.WriteLine (st);
68         }
69         
70         static void Perform (bool install, string executable)
71         {
72                 ArrayList order = new ArrayList ();
73                 Hashtable states = new Hashtable ();
74                 
75                 try {
76                         Assembly a;
77
78                         if (assembly != null)
79                                 a = Assembly.Load (assembly);
80                         else
81                                 a = Assembly.LoadFrom (executable);
82                         
83                         Type [] types = a.GetTypes ();
84
85                         // todo: pass arguments, they are kind of useless though.
86                         InstallContext ctx = new InstallContext ();
87                         
88                         foreach (Type t in types){
89                                 if (!t.IsSubclassOf (typeof (Installer)))
90                                         continue;
91
92                                 object [] attrs = t.GetCustomAttributes (typeof (RunInstallerAttribute), false);
93                                 if (attrs == null || attrs.Length == 0)
94                                         continue;
95
96                                 RunInstallerAttribute ria = attrs [0] as RunInstallerAttribute;
97                                 if (ria == null || !ria.RunInstaller)
98                                         continue;
99
100                                 try {
101                                         Installer installer = (Installer) Activator.CreateInstance (t);
102                                         Hashtable state = new Hashtable ();
103                                         
104                                         order.Add (installer);
105                                         states [installer] = state;
106                                         
107                                         if (install)
108                                                 Call (installer, "OnBeforeInstall", state);
109                                         else
110                                                 Call (installer, "OnBeforeUninstall", state);
111                                         
112                                         installer.Install (state);
113
114                                         if (install)
115                                                 Call (installer, "OnAfterInstall", state);
116                                         else
117                                                 Call (installer, "OnAfterUninstall", state);
118                                         
119                                 } catch (Exception e) {
120                                         Error (String.Format ("Can not create installer of type {0}", t));
121                                         
122                                         //
123                                         // According to the docs uninstall should not do rollback
124                                         //
125                                         if (install){
126                                                 foreach (Installer installer in order){
127                                                         Hashtable state = (Hashtable) states [installer];
128                                                                 
129                                                         Call (installer, "OnBeforeRollback", state);
130                                                         installer.Rollback (state);
131                                                         Call (installer, "OnAfterRollback", state);
132                                                 }
133                                         }
134                                 }
135                         }
136                         //
137                         // Got it, now commit them
138                         //
139                         if (install){
140                                 foreach (Installer inst in order){
141                                         Hashtable state = (Hashtable) states [inst];
142                                         
143                                         Call (inst, "OnCommitting", state);
144                                         inst.Commit (state);
145                                         Call (inst, "OnCommitted", state);
146                                 }
147                         }
148                 } catch {
149                         Error (String.Format ("Unable to load assembly {0}", assembly));
150                 }               
151         }
152
153         static void Install (string assembly)
154         {
155                 Perform (true, assembly);
156         }
157         
158         static void Uninstall (string assembly)
159         {
160                 Perform (false, assembly);
161         }
162         
163         static int Main (string [] args)
164         {
165                 bool did_something = false;
166                 string logfile = null;
167                 
168                 for (int i = 0; i < args.Length; i++){
169                         string arg = args [i];
170                         char c = arg [0];
171
172                         if (c == '/' || c == '-'){
173                                 switch (arg.ToLower ()){
174                                 case "/help": case "/h": case "/?": 
175                                 case "-help": case "-h": case "-?": 
176                                         if (i + 1 < args.Length){
177                                                 i++;
178                                                 ShowHelpForAssembly (args [i]);
179                                         } else {
180                                                 ShowHelp ();
181                                                 return 1;
182                                         }
183                                         break;
184
185                                 case "-showcallstack":
186                                 case "/showcallstack":
187                                         showcallstack = true;
188                                         break;
189
190                                 case "-logtoconsole":
191                                 case "/logtoconsole":
192                                         logtoconsole = true;
193                                         break;
194
195                                 case "-u": case "-uninstall":
196                                 case "/u": case "/uninstall":
197                                         if (i + 1 < args.Length){
198                                                 i++;
199                                                 Uninstall (args [i]);
200                                                 did_something = true;
201                                         } else {
202                                                 ShowHelp ();
203                                                 return 1;
204                                         }
205                                         break;
206
207                                 case "-assemblyname":
208                                 case "/assemblyname":
209                                         if (i + 1 < args.Length){
210                                                 i++;
211                                                 assembly = args [i];
212                                                 Install ("");
213                                         } else {
214                                                 ShowHelp ();
215                                                 return 1;
216                                         }
217                                         break;
218                                         
219                                 default:
220                                         ShowHelp ();
221                                         return 1;
222                                 }
223                         } else {
224                                 did_something = true;
225                                 Install (args [i]);
226                         }
227                 }
228                 if (!did_something){
229                         ShowHelp ();
230                         return 1;
231                 }
232
233                 return 0;
234         }
235 }