
//============================================================================================================
// Microsoft Updater Application Block for .NET
//  http://msdn.microsoft.com/library/en-us/dnbda/html/updater.asp
//	
// AppStart.cs
//
// "Shim" for starting applications based on information from a configuration file.
// 
// For more information see the Updater Application Block Implementation Overview. 
// 
//============================================================================================================
// Copyright (C) 2000-2001 Microsoft Corporation
// All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR
// FITNESS FOR A PARTICULAR PURPOSE.
//============================================================================================================


using System;
using System.Collections;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Globalization;
using System.Xml;
using System.Reflection;
using System.IO;
using System.Threading;
using System.Windows.Forms;


namespace Microsoft.ApplicationBlocks.ApplicationUpdater.AppStart
{
	//
	// AppStart Class	
	// This is the main class for appstart.exe
	//
	public sealed class AppStart
	{

		#region Constructors

		static AppStart()
		{			
			//  grab our config instance which we use to read app.config params, figure out
			//  WHERE our target app is and WHAT version
			_config = (AppStartConfiguration)ConfigurationSettings.GetConfig( "appStart" );
		}

		//  no reason to ever "construct" this from outside, meant purely as invisible shim
		private AppStart() {}

		#endregion


		#region Declarations

		private static AppStartConfiguration		_config = null;
		private static string						_exePath = "";
		private static Process						_process;
		private static Mutex						_appStartMutex;
		private static readonly Guid				_mutexGuid = new Guid( new byte[] { 0x5F, 0x4D, 0x69, 0x63, 0x68, 0x61, 0x65, 0x6C, 0x20, 0x53, 0x74, 0x75, 0x61, 0x72, 0x74, 0x5F });

		#endregion 


		/// <summary>
		/// Main entry point to process.  Checks to see if another instance is running already, disallows if so.
		/// </summary>
		/// <param name="args">args are ignored.</param>
		[STAThread]
		static void Main(string[] args) 
		{
			//Check to see if AppStart is already running FOR the particular versioned folder of the target application
			bool isOwned = false;

			_appStartMutex = new Mutex( true,  _config.ExePath + _mutexGuid.ToString(), out isOwned );
	
			if ( !isOwned )
			{
				MessageBox.Show( 
					String.Format( 
					CultureInfo.CurrentCulture, 
					"There is already a copy of the application '{0}' running.  Please close that application before starting a new one.", 
					_config.ExePath ) );

				Environment.Exit( 1 );
			}
			
			StartApp_Process();
		}
				
		///*
		// * StartApp_Process()
		/// 
		public static void StartApp_Process( ) 
		{
			_exePath = Path.Combine( _config.FolderName , _config.ExePath );

			//Start the app
			try 
			{
				ProcessStartInfo p = new ProcessStartInfo (_exePath);
				p.WorkingDirectory = Path.GetDirectoryName(_exePath);
				_process = Process.Start (p);
				Debug.WriteLine("APPLICATION STARTER:  Started app:  " + _exePath);
			} 
			catch (Exception e)
			{
				Debug.WriteLine("APPLICATION STARTER:  Failed to start process at:  " + _exePath);
				HandleTerminalError(e);
			}
		}	

		
		///*
		// * 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( String.Format( CultureInfo.CurrentCulture, "There was an error when trying to start the target application: {0}", e.Message ) );			
			Environment.Exit(0);
		}
	
	}
}
