Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
Program.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Collections.Generic;
5 using System.Diagnostics;
6 using System.IO;
7 using System.Linq;
8 using System.Net.Mime;
9 using System.Threading;
10 using System.Windows.Forms;
11 using SiliconStudio.Assets;
12 using SiliconStudio.Core.Windows;
13 
14 namespace SiliconStudio.LauncherApp
15 {
16  class Program
17  {
18  private const string LaunchAppRestartOption = "/LaunchAppRestart";
19  private LauncherApp launcherApp;
20  private SplashForm splashscreen;
21  private int previousComplete;
22 
23  private bool isPostDownloading;
24  bool relaunchThisProcess = false;
25 
26  [STAThread]
27  [LoaderOptimization(LoaderOptimization.MultiDomainHost)] // Optimize loading of AppDomain assemblies
28  private static void Main()
29  {
30  // Setup the SiliconStudioParadoxDir to make sure that it is passed to the underlying process (msbuild...etc.)
31  Environment.SetEnvironmentVariable("SiliconStudioParadoxDir", Path.GetDirectoryName(typeof(Program).Assembly.Location));
32 
33  var program = new Program();
34  program.RunSafe(() => program.Run(AppHelper.GetCommandLineArgs()));
35  }
36 
37  private void RunSafe(Action action)
38  {
39  try
40  {
41  action();
42  }
43  catch (Exception exception)
44  {
45  ShowUnhandledException(exception);
46  }
47  }
48 
49  private void ShowUnhandledException(Exception exception)
50  {
51  var message = AppHelper.BuildErrorToClipboard(exception, string.Format("LauncherApp Version: {0}\n", LauncherApp.Version));
52  MessageBox.Show(GetCurrentWindow(), "An unhandled exception has occured (copied to the clipboard) : \n\n" + message, "Launcher error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
53  }
54 
55  private void Run(string[] args)
56  {
57  if (args.Length > 0 && args[0] == LaunchAppRestartOption)
58  {
59  Console.WriteLine("Restart, wait for 200ms");
60  Thread.Sleep(200);
61  args = args.Skip(1).ToArray();
62  }
63 
64  using (launcherApp = new LauncherApp())
65  {
66  launcherApp.DialogAvailable += launcherApp_DialogAvailable;
67  launcherApp.UnhandledException += (sender, exception) => ShowUnhandledException(exception);
68 
69  var evt = new ManualResetEvent(false);
70 
71  var splashThread = new Thread(
72  () =>
73  {
74  splashscreen = new SplashForm();
75  splashscreen.Initialize(launcherApp);
76  splashscreen.Show();
77 
78  launcherApp.MainWindowHandle = splashscreen.Handle;
79  evt.Set();
80 
81  Application.Run(splashscreen);
82  splashscreen = null;
83  });
84  splashThread.Start();
85 
86  evt.WaitOne();
87 
88  launcherApp.ProgressAvailable += launcherApp_ProgressAvailable;
89  launcherApp.LogAvailable += launcherApp_LogAvailable;
90  var runningForm = splashscreen;
91  launcherApp.Running += (sender, eventArgs) => SafeWindowClose(runningForm);
92 
93  var result = launcherApp.Run(args);
94 
95  // Make sure the splashscreen is closed in case of an error
96  if (result != 0)
97  {
98  runningForm.ExitOnUserClose = false;
99  SafeWindowClose(runningForm);
100  }
101 
102  // Reopen the SplashForm if we are still downloading files
103  if (launcherApp.IsDownloading)
104  {
105  isPostDownloading = true;
106  launcherApp.DownloadFinished += launcherApp_DownloadFinished;
107 
108  splashscreen = new SplashForm();
109  splashscreen.Initialize(launcherApp, "Downloading new version");
110  splashscreen.Show();
111  Application.Run(splashscreen);
112  splashscreen = null;
113  }
114  }
115  launcherApp = null;
116 
117  // Relaunch this application if necessary
118  if (relaunchThisProcess)
119  {
120  var newArgs = new List<string>() { LaunchAppRestartOption };
121  newArgs.AddRange(args);
122  var startInfo = new ProcessStartInfo(typeof(Program).Assembly.Location)
123  {
124  Arguments = string.Join(" ", newArgs),
125  WorkingDirectory = Environment.CurrentDirectory,
126  UseShellExecute = true
127  };
128  Process.Start(startInfo);
129  }
130  }
131 
132  static int GetLauncherAppProcessCount()
133  {
134  return Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length;
135  }
136 
137  private static void SafeWindowClose(Form form)
138  {
139  if (form != null)
140  {
141  form.InvokeSafe(() =>
142  {
143  if (!form.IsDisposed)
144  {
145  form.Close();
146  }
147  });
148  };
149  }
150 
151  void launcherApp_DownloadFinished(object sender, EventArgs e)
152  {
153  if (splashscreen != null)
154  {
155  // Propose to re-launch GameStudio only if this is a new package and there is only a single launcher
156  var launcherCount = GetLauncherAppProcessCount();
157  if (launcherApp.IsNewPackageAvailable && isPostDownloading && launcherCount == 1)
158  {
159  var result = MessageBox.Show(GetCurrentWindow(), "Do you want to install and run the new version now?", "Launcher", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
160  relaunchThisProcess = result == DialogResult.Yes;
161  }
162 
163  var form = splashscreen;
164  splashscreen.InvokeSafe(form.Close);
165  }
166  }
167 
168  void launcherApp_DialogAvailable(object sender, DialogEventArgs e)
169  {
170  e.Result = MessageBox.Show(GetCurrentWindow(), e.Text, e.Caption, e.Buttons, e.Icon, e.DefaultButton, e.Options);
171  }
172 
173  void launcherApp_ProgressAvailable(object sender, NuGet.ProgressEventArgs e)
174  {
175  if (previousComplete != e.PercentComplete)
176  {
177  Console.WriteLine("Download {0} {1}", e.Operation, e.PercentComplete);
178  }
179  previousComplete = e.PercentComplete;
180  }
181 
182  static void launcherApp_LogAvailable(object sender, NugetLogEventArgs e)
183  {
184  Console.WriteLine(e);
185  }
186 
187  IWin32Window GetCurrentWindow()
188  {
189  // When debugger is attached, don't try to have a current window for show dialog (bug?)
190  if (System.Diagnostics.Debugger.IsAttached)
191  {
192  return null;
193  }
194 
195  // Trying to get the main window handle when splashscreen is not displayed is not working?
196  var windowHandler = Process.GetCurrentProcess().MainWindowHandle;
197  var wnd = windowHandler != IntPtr.Zero ? NativeWindow.FromHandle(windowHandler) : null;
198 
199  return splashscreen != null && !splashscreen.IsDisposed ? (IWin32Window)splashscreen : wnd;
200  }
201  }
202 }
static string[] GetCommandLineArgs()
Definition: AppHelper.cs:12
Operation
Enumeration of the different operations in the new Assimp's material stack.