OSDN Git Service

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