using System; using System.Collections.Generic; using System.Windows.Forms; using System.IO; namespace AppliStation { class Program { Form splashScreen; PackageListViewForm form; /// /// アプリケーションのオプション /// Dictionary appArgs; public Program() { appArgs = new Dictionary(); appArgs["noupdate"] = false; appArgs["cmd"] = string.Empty; appArgs["pkgsref"] = string.Empty; appArgs["instsref"] = string.Empty; } void RunNormal() { form = new PackageListViewForm(); form.Load += delegate(object sender, EventArgs e) { hideSplashScreen(); form.updateActionInvoke(((bool)appArgs["noupdate"]) != true); form.UpdatePackageList(); }; Application.Run(form); } void RunInstall() { try { NaGet.Packages.Install.Installation[] insts = NaGet.Utils.GetDeserializedObject((string) appArgs["instsref"]); form = new PackageListViewForm(); hideSplashScreen(); form.installActionInvoke(insts); } catch (UnauthorizedAccessException e) { MessageBox.Show(string.Format("管理者権限に昇格していないか、実行権限に問題があります。\n(詳細:{0})", e.Message), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); } catch (FileNotFoundException e) { MessageBox.Show(string.Format("ソフト指定ファイル{0}が見つかりません", e.FileName), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); } } void RunUninstall() { try { NaGet.Packages.Install.InstalledPackage[] pkgs = NaGet.Utils.GetDeserializedObject((string) appArgs["pkgsref"]); form = new PackageListViewForm(); hideSplashScreen(); form.uninstallActionInvoke(pkgs); } catch (UnauthorizedAccessException e) { MessageBox.Show(string.Format("管理者権限に昇格していないか、実行権限に問題があります。\n(詳細:{0})", e.Message), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); } catch (FileNotFoundException e) { MessageBox.Show(string.Format("ソフト指定ファイル{0}が見つかりません", e.FileName), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); } } void RunUpdateAppliStation() { if ( splashScreen == null ) { splashScreen = createAndOpenSplashScreen(); } System.Threading.Thread.Sleep(5000); /* 5sec待って呼び出しもとの終了を待つ */ string newAppliStationDir = Application.StartupPath; string targetDir = Environment.CurrentDirectory; foreach (string file in Directory.GetFiles(newAppliStationDir)) { string ext = Path.GetExtension(file).ToLower(); if ((ext == ".exe") || (ext == ".dll") || (ext == ".pdb") || (ext == ".png")) { while (true) { /* loop for retry */ try { File.Copy(file, Path.Combine(targetDir, Path.GetFileName(file)), true); break; } catch (IOException ex) { DialogResult result = MessageBox.Show(string.Format("AppliStationの更新に失敗しました。\r\n\r\n{0}", ex.Message), "AppliStation", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error); if (result == DialogResult.Retry) { continue; /* retry */ } else { MessageBox.Show("AppliStationの更新は中断されました。", "AppliStation", MessageBoxButtons.OK, MessageBoxIcon.Error); hideSplashScreen(); return; } } } } } System.Threading.Thread.Sleep(10); System.Diagnostics.Process.Start(Path.Combine(targetDir, Path.GetFileName(Application.ExecutablePath))); hideSplashScreen(); //Application.Exit(); // Do nothing = exit } /// /// AppliStationの自己更新を行う。アーカイブインストーラーによってあらかじめインストールされたファイルを、 /// カレントディレクトリにコピーするよう新しいAppliStation.exeを呼ぶ。 /// コピー元がないまたはそれが新しくないならば何もしない。 /// /// 更新をしたときtrueをかえす。 private bool autoUpdateAppliStation() { if (string.IsNullOrEmpty(appArgs["cmd"].ToString())) { string newAppliStationDir = Path.Combine(NaGet.Env.ArchiveProgramFiles, "AppliStation"); string thisAppliStation = Application.ExecutablePath; if (Directory.Exists(newAppliStationDir)) { string newAppliStation = Path.Combine(newAppliStationDir, Path.GetFileName(thisAppliStation)); if ( File.Exists(newAppliStation) && (File.GetLastWriteTime(thisAppliStation) != File.GetLastWriteTime(newAppliStation)) ) { System.Diagnostics.Process.Start(newAppliStation, "--cmd=updateAppliStation"); return true; } } } return false; } private void hideSplashScreen() { if (splashScreen != null && splashScreen.Visible) { splashScreen.Hide(); splashScreen.Dispose(); } } public void Run(string[] args) { try { parseArgs(args); } catch (ApplicationException e) { MessageBox.Show(e.Message, "AppliStation 起動引数エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // cmd引数がないときに更新処理を試みる。 // cmd引数があるときに更新しないのは、AppliStationから「管理者で実行」などで呼び出された場合に // 更新処理にならないようにするため。 if ( string.IsNullOrEmpty((string) appArgs["cmd"]) && autoUpdateAppliStation() ) { // アップデートしたときは起動しない return; } switch ((string) appArgs["cmd"]) { case "install": RunInstall(); break; case "uninstall": RunUninstall(); break; case "updateAppliStation": RunUpdateAppliStation(); break; default: RunNormal(); break; } } private void parseArgs(string[] args) { NaGet.ArgParser parser = new NaGet.ArgParser(appArgs); string[] restAppArgs = parser.Parse(args); } private static Form createAndOpenSplashScreen() { System.Drawing.Bitmap bitmap; bitmap = new System.Drawing.Bitmap(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "SplashScreen.png")); Form splashScreen = AppliStation.Util.SprashScreenLayered.CreateSprashScreenLayered(bitmap, System.Drawing.Color.Black); splashScreen.Text = "AppliStation"; splashScreen.Icon = System.Drawing.Icon.ExtractAssociatedIcon(Application.ExecutablePath); splashScreen.Show(); return splashScreen; } [STAThread] public static void Main(string[] args) { Form splashScreen = null; try { if (args.Length <= 0) { // HACK 引数パースの時間さえ待てないので引数の有無で表示を判断 splashScreen = createAndOpenSplashScreen(); } // アーカイブSYSTEM32をパスに足す NaGet.Utils.AddDirectoryToPath(NaGet.Env.ArchiveSystem32); ToolStripManager.VisualStylesEnabled = false; // ToolStripがLunaで青くならないように Application.EnableVisualStyles(); // LunaやVistaのデザインを有効に // デバッガがアタッチしていないなら、Exceptionを自力でハンドルする if (! System.Diagnostics.Debugger.IsAttached) { Application.ThreadException += AppliStation.Util.ExceptionDialogForm.Application_ThrowException; System.Threading.Thread.GetDomain().UnhandledException += AppliStation.Util.ExceptionDialogForm.Application_ThrowException; } Program prog = new Program(); prog.splashScreen = splashScreen; prog.Run(args); } catch (Exception e) { AppliStation.Util.ExceptionDialogForm.Application_ThrowException(null, new System.Threading.ThreadExceptionEventArgs(e)); } finally { if (splashScreen != null) { splashScreen.Dispose(); } } } } }