📄 appstart.cs
字号:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Xml;
using System.Reflection;
using System.IO;
using System.Threading;
using System.Windows.Forms;
namespace Microsoft.Samples.AppUpdater
{
//**************************************************************
// AppStart Class
// This is the main class for appstart.exe
//**************************************************************
public class AppStart
{
public AppStart() {}
static string AppExePath;
static Process AppProcess;
static string[] CommandLineArgs;
static string[] RestartCommandLineArgs;
static string CommandLineString;
static string RestartCommandLineString;
static Mutex AppStartMutex;
//**************************************************************
// Main()
//**************************************************************
[STAThread]
static void Main(string[] args)
{
//Check to see if AppStart is already running
bool ObtainedOwnership = false;
AppStartMutex = new Mutex(true,"AppStart",out ObtainedOwnership);
if (!ObtainedOwnership)
{
Environment.Exit(1);
}
//Retrive cmdline to pass to new process
CommandLineString = "";
for (int i = 0; i < args.Length; i++)
{
CommandLineString = string.Format ("{0} {1}", CommandLineString, args[i]);
}
CommandLineString += " /appstartversion " + Assembly.GetExecutingAssembly().GetName().Version.ToString();
RestartCommandLineString = CommandLineString + " /restart ";
CommandLineArgs = new String[args.Length+2];
CommandLineArgs[CommandLineArgs.Length-2] = "/appstartversion";
CommandLineArgs[CommandLineArgs.Length-1] = Assembly.GetExecutingAssembly().GetName().Version.ToString();
RestartCommandLineArgs = new String[CommandLineArgs.Length+1];
RestartCommandLineArgs[RestartCommandLineArgs.Length-1] = "/restart";
AppStartConfig Config = LoadConfig();
if (Config.AppLaunchMode == AppStartConfig.LaunchModes.Process)
StartAndWait_Process();
else
StartAndWait_Domain();
}
/*********************************************************************
* StartAndWait_Domain()
**********************************************************************/
private static void StartAndWait_Domain()
{
bool restartApp = true;
int returnCode = 0;
while (restartApp)
{
try
{
returnCode = StartApp_Domain(false);
Debug.WriteLine(returnCode.ToString());
}
catch (Exception e)
{
Debug.WriteLine("APPLICATION STARTER: Process.WaitForExit() failed, it's possible the process is not running");
HandleTerminalError(e);
}
if (returnCode == 2)
{
restartApp = true;
}
else
restartApp = false;
}
}
/*********************************************************************
* StartAndWait_Process()
**********************************************************************/
private static void StartAndWait_Process()
{
bool restartApp = true;
StartApp_Process(false);
while (restartApp)
{
try
{
AppProcess.WaitForExit();
}
catch (Exception e)
{
Debug.WriteLine("APPLICATION STARTER: Process.WaitForExit() failed, it's possible the process is not running");
Debug.WriteLine("APPLICATION STARTER: " + e.ToString());
return;
}
if (AppProcess.ExitCode == 2)
{
restartApp = true;
AppProcess = null;
StartApp_Process(true);
}
else
restartApp = false;
}
}
/*********************************************************************
* StartApp_Domain()
**********************************************************************/
public static int StartApp_Domain(bool restartApp)
{
Debug.WriteLine("APPLICATION STARTER: Starting the app in a seperate domain");
//Load the config file
AppStartConfig Config;
Config = LoadConfig();
AppExePath = Config.AppExePath;
//Load the app
int retValue=0;
try
{
//Create the new app domain
AppDomain NewDomain = AppDomain.CreateDomain (
"New App Domain",
AppDomain.CurrentDomain.Evidence,
Path.GetDirectoryName(AppExePath)+@"\",
"",
false);
//Execute the app in the new appdomain
string[] cmdLineArgs;
if(restartApp)
cmdLineArgs = RestartCommandLineArgs;
else
cmdLineArgs = CommandLineArgs;
retValue = NewDomain.ExecuteAssembly(AppExePath,AppDomain.CurrentDomain.Evidence,cmdLineArgs);
//Unload the app domain
AppDomain.Unload(NewDomain);
}
catch (Exception e)
{
Debug.WriteLine("APPLICATION STARTER: Failed to start app at: " + AppExePath);
HandleTerminalError(e);
}
return (retValue);
}
/*********************************************************************
* StartApp_Process()
**********************************************************************/
public static void StartApp_Process(bool restartApp)
{
Debug.WriteLine("APPLICATION STARTER: Starting the app in a seperate process");
//Load the config file
AppStartConfig Config;
Config = LoadConfig();
AppExePath = Config.AppExePath;
//If the app has been started by this process before
if (AppProcess != null)
{
//& the app is still running, no need to start the app
if (!AppProcess.HasExited)
return;
}
//Start the app
try
{
ProcessStartInfo p = new ProcessStartInfo (AppExePath);
p.WorkingDirectory = Path.GetDirectoryName(AppExePath);
// Notify the app if we are restarting in case there's something they want to do differently
if(restartApp)
p.Arguments = RestartCommandLineString;
else
p.Arguments = CommandLineString;
AppProcess = Process.Start (p);
Debug.WriteLine("APPLICATION STARTER: Started app: " + AppExePath);
}
catch (Exception e)
{
Debug.WriteLine("APPLICATION STARTER: Failed to start process at: " + AppExePath);
HandleTerminalError(e);
}
}
/*********************************************************************
* LoadConfig()
**********************************************************************/
private static AppStartConfig LoadConfig()
{
AppStartConfig Config;
//Load the config file which knows where the app lives
try
{
//Try app specific config file name
Config = AppStartConfig.Load(CalcConfigFileLocation());
return Config;
}
catch (Exception e)
{
try
{
//Try default config file name
Debug.WriteLine("APPLICATION STARTER: Falling back to try to read appstart.config.");
Config = AppStartConfig.Load(AppDomain.CurrentDomain.BaseDirectory + @"AppStart.Config");
return Config;
}
catch
{
HandleTerminalError(e);
}
}
return null;
}
/*********************************************************************
* GetAppExePath()
**********************************************************************/
private static string CalcConfigFileLocation()
{
//The config file name should be appstart.config if the exe name is appstart.exe
string ConfigFileName;
try
{
ConfigFileName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
ConfigFileName = Path.Combine(ConfigFileName,Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().Location));
ConfigFileName += @".config";
return ConfigFileName;
}
catch (Exception e)
{
Debug.WriteLine("APPLICATION STARTER: Failed to properly calculate config file name");
HandleTerminalError(e);
return null;
}
}
/*********************************************************************
* HandleTerminalError()
* Prints out the terminal exception & shuts down the app
**********************************************************************/
private static void HandleTerminalError(Exception e)
{
Debug.WriteLine("APPLICATION STARTER: Terminal error encountered.");
Debug.WriteLine("APPLICATION STARTER: The following exception was encoutered:");
Debug.WriteLine(e.ToString());
Debug.WriteLine("APPLICATION STARTER: Shutting down");
MessageBox.Show("The auto-update feature of this application has encountered a configuration error.\r\n"
+"Please uninstall and reinstall the application."); Environment.Exit(0);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -