OSDN Git Service

AppliStation-GUI,自己インストールのテスト実装
[applistation/AppliStation.git] / AppliStation / Program.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.Windows.Forms;\r
4 using System.IO;\r
5 \r
6 namespace AppliStation\r
7 {\r
8         class Program\r
9         {\r
10                 Form splashScreen;\r
11                 \r
12                 PackageListViewForm form;\r
13                 \r
14                 /// <summary>\r
15                 /// アプリケーションのオプション\r
16                 /// </summary>\r
17                 Dictionary<string, object> appArgs;\r
18                 \r
19                 string[] restAppArgs;\r
20                 \r
21                 public Program()\r
22                 {\r
23                         appArgs = new Dictionary<string, object>();\r
24                         appArgs["noupdate"] = false;\r
25                         appArgs["cmd"] = string.Empty;\r
26                         appArgs["pkgsref"] = string.Empty;\r
27                         appArgs["instsref"] = string.Empty;\r
28                         \r
29                         form = new PackageListViewForm();\r
30                 }\r
31                 \r
32                 void RunNormal()\r
33                 {\r
34                         form.Load += delegate(object sender, EventArgs e) {\r
35                                 hideSplashScreen();\r
36                                 form.updateActionInvoke(((bool)appArgs["noupdate"]) != true);\r
37                                 \r
38                                 form.UpdatePackageList();\r
39                         };\r
40                         Application.Run(form);\r
41                 }\r
42                 \r
43                 void RunInstall()\r
44                 {\r
45                         try {\r
46                                 NaGet.Packages.Install.Installation[] insts = NaGet.Utils.GetDeserializedObject<NaGet.Packages.Install.Installation[]>((string) appArgs["instsref"]);\r
47                                 \r
48                                 hideSplashScreen();\r
49                                 form.installActionInvoke(insts);\r
50                         } catch (UnauthorizedAccessException e) {\r
51                                 MessageBox.Show(string.Format("管理者権限に昇格していないか、実行権限に問題があります。\n(詳細:{0})", e.Message),\r
52                                                 Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);\r
53                         } catch (FileNotFoundException e) {\r
54                                 MessageBox.Show(string.Format("ソフト指定ファイル{0}が見つかりません", e.FileName),\r
55                                                 Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);\r
56                         }\r
57                 }\r
58                 \r
59                 void RunUninstall()\r
60                 {\r
61                         try {\r
62                                 NaGet.Packages.Install.InstalledPackage[] pkgs = NaGet.Utils.GetDeserializedObject<NaGet.Packages.Install.InstalledPackage[]>((string) appArgs["pkgsref"]);\r
63                                 \r
64                                 hideSplashScreen();\r
65                                 form.uninstallActionInvoke(pkgs);\r
66                         } catch (UnauthorizedAccessException e) {\r
67                                 MessageBox.Show(string.Format("管理者権限に昇格していないか、実行権限に問題があります。\n(詳細:{0})", e.Message),\r
68                                                 Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);\r
69                         } catch (FileNotFoundException e) {\r
70                                 MessageBox.Show(string.Format("ソフト指定ファイル{0}が見つかりません", e.FileName),\r
71                                                 Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);\r
72                         }\r
73                 }\r
74                 \r
75                 void RunUpdateAppliStation()\r
76                 {\r
77                         System.Threading.Thread.Sleep(5000); /* 5sec待って呼び出しもとの終了を待つ */\r
78                         \r
79                         string newAppliStationDir = Application.StartupPath;\r
80                         string targetDir = Environment.CurrentDirectory;\r
81                         foreach (string file in Directory.GetFiles(newAppliStationDir)) {\r
82                                 string ext = Path.GetExtension(file).ToLower();\r
83                                 if ((ext == ".exe") || (ext == ".dll") ||\r
84                                     (ext == ".pdb") || (ext == ".png")) {\r
85                                         File.Copy(file, Path.Combine(targetDir, Path.GetFileName(file)), true);\r
86                                 }\r
87                         }\r
88 MessageBox.Show("Installation is completed.");\r
89                         System.Threading.Thread.Sleep(10);\r
90                         System.Diagnostics.Process.Start(Path.Combine(targetDir, Path.GetFileName(Application.ExecutablePath)));\r
91                         hideSplashScreen();\r
92                         //Application.Exit(); // Do nothing = exit\r
93                 }\r
94                 \r
95                 /// <summary>\r
96                 /// AppliStationの自己更新を行う。アーカイブインストーラによってあらかじめインストールされたファイルを、\r
97                 /// カレントディレクトリにコピーするよう新しいAppliStation.exeを呼ぶ。\r
98                 /// コピー元がないまたはそれが新しくないならば何もしない。\r
99                 /// </summary>\r
100                 /// <returns>更新をしたときtrueをかえす。</returns>\r
101                 private bool autoUpdateAppliStation()\r
102                 {\r
103                         if (string.IsNullOrEmpty(appArgs["cmd"].ToString())) {\r
104                                 string newAppliStationDir = Path.Combine(NaGet.Env.ArchiveProgramFiles, "AppliStation");\r
105                                 string thisAppliStation = Application.ExecutablePath;\r
106                                 \r
107                                 if (Directory.Exists(newAppliStationDir)) {\r
108                                         string newAppliStation = Path.Combine(newAppliStationDir, Path.GetFileName(thisAppliStation));\r
109                                         \r
110 MessageBox.Show(string.Format("{0}\r\n{1}", newAppliStation, File.Exists(newAppliStation)));\r
111 MessageBox.Show(string.Format("{0}\r\n{1}", File.GetLastWriteTime(thisAppliStation), File.GetLastWriteTime(newAppliStation)));\r
112 MessageBox.Show(string.Format("{0}", File.GetLastWriteTime(thisAppliStation) < File.GetLastWriteTime(newAppliStation)));\r
113                                         \r
114                                         if ( File.Exists(newAppliStation) &&\r
115                                             (File.GetLastWriteTime(thisAppliStation) < File.GetLastWriteTime(newAppliStation)) ) {\r
116 \r
117                                                 System.Diagnostics.Process.Start(newAppliStation, "--cmd=updateAppliStation");\r
118                                                 return true;\r
119                                         }\r
120                                 }\r
121                         }\r
122                         return false;\r
123                 }\r
124                 \r
125                 private void hideSplashScreen()\r
126                 {\r
127                         if (splashScreen != null && splashScreen.Visible) {\r
128                                 splashScreen.Hide();\r
129                                 splashScreen.Dispose();\r
130                         }\r
131                 }\r
132                 \r
133                 public void Run(string[] args)\r
134                 {\r
135                         try {\r
136                                 parseArgs(args);\r
137                         } catch (ApplicationException e) {\r
138                                 MessageBox.Show(e.Message, "AppliStation 起動引数エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
139                                 return;\r
140                         }\r
141                         \r
142                         // cmd引数がないときに更新処理を試みる。\r
143                         // cmd引数があるときに更新しないのは、AppliStationから「管理者で実行」などで呼び出された場合に\r
144                         // 更新処理にならないようにするため。\r
145                         if ( string.IsNullOrEmpty((string) appArgs["cmd"]) &&\r
146                             autoUpdateAppliStation() ) {\r
147                                 // アップデートしたときは起動しない\r
148                                 return;\r
149                         }\r
150                         \r
151                         \r
152                         switch ((string) appArgs["cmd"]) {\r
153                                 case "install":\r
154                                         RunInstall();\r
155                                         break;\r
156                                 case "uninstall":\r
157                                         RunUninstall();\r
158                                         break;\r
159                                 case "updateAppliStation":\r
160                                         RunUpdateAppliStation();\r
161                                         break;\r
162                                 default:\r
163                                         RunNormal();\r
164                                         break;\r
165                         }\r
166                 }\r
167                 \r
168                 private void parseArgs(string[] args)\r
169                 {\r
170                         NaGet.ArgParser parser = new NaGet.ArgParser(appArgs);\r
171                         restAppArgs = parser.Parse(args);\r
172                 }\r
173                 \r
174                 [STAThread]\r
175                 public static void Main(string[] args)\r
176                 {\r
177                         Form splashScreen = null;\r
178                         \r
179                         try {\r
180                                 if (args.Length <= 0) { // HACK 引数パースの時間さえ待てないので引数の有無で表示を判断\r
181                                         splashScreen = new Form();\r
182                                         splashScreen.FormBorderStyle = FormBorderStyle.None;\r
183                                         splashScreen.BackgroundImage = System.Drawing.Bitmap.FromFile(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "SplashScreen.png"));\r
184                                         splashScreen.Size = splashScreen.BackgroundImage.Size;\r
185                                         splashScreen.ShowIcon = false;\r
186                                         splashScreen.ShowInTaskbar = false;\r
187                                         splashScreen.StartPosition = FormStartPosition.CenterScreen;\r
188                                         splashScreen.Show();\r
189                                 }\r
190                                 \r
191                                 // アーカイブSYSTEM32をパスに足す\r
192                                 NaGet.Utils.AddDirectoryToPath(NaGet.Env.ArchiveSystem32);\r
193                                 \r
194                                 ToolStripManager.VisualStylesEnabled = false; // ToolStripがLunaで青くならないように\r
195                                 Application.EnableVisualStyles(); // LunaやVistaのデザインを有効に\r
196                                 \r
197                                 Application.ThreadException += AppliStation.Util.ExceptionDialogForm.Application_ThrowException;\r
198                                 System.Threading.Thread.GetDomain().UnhandledException += AppliStation.Util.ExceptionDialogForm.Application_ThrowException;\r
199                                 \r
200                                 Program prog = new Program();\r
201                                 prog.splashScreen = splashScreen;\r
202                                 prog.Run(args);\r
203                         } catch (Exception e) {\r
204                                 AppliStation.Util.ExceptionDialogForm.Application_ThrowException(null, new System.Threading.ThreadExceptionEventArgs(e));\r
205                         } finally {\r
206                                 if (splashScreen != null) {\r
207                                         splashScreen.Dispose();\r
208                                 }\r
209                         }\r
210                 }\r
211         }\r
212 }\r