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();
form.UpdatePackageList();
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();
form.UpdatePackageList();
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();
}
}
}
}
}