Example #1
0
		int Run (MonoDevelopOptions options)
		{
			LoggingService.LogInfo ("Starting {0} {1}", BrandingService.ApplicationName, IdeVersionInfo.MonoDevelopVersion);
			LoggingService.LogInfo ("Running on {0}", IdeVersionInfo.GetRuntimeInfo ());

			//ensure native libs initialized before we hit anything that p/invokes
			Platform.Initialize ();

			LoggingService.LogInfo ("Operating System: {0}", SystemInformation.GetOperatingSystemDescription ());

			IdeApp.Customizer = options.IdeCustomizer ?? new IdeCustomizer ();
			IdeApp.Customizer.Initialize ();

			Counters.Initialization.BeginTiming ();

			if (options.PerfLog) {
				string logFile = Path.Combine (Environment.CurrentDirectory, "monodevelop.perf-log");
				LoggingService.LogInfo ("Logging instrumentation service data to file: " + logFile);
				InstrumentationService.StartAutoSave (logFile, 1000);
			}

			Counters.Initialization.Trace ("Initializing GTK");
			if (Platform.IsWindows && !CheckWindowsGtk ())
				return 1;
			SetupExceptionManager ();
			
			try {
				GLibLogging.Enabled = true;
			} catch (Exception ex) {
				LoggingService.LogError ("Error initialising GLib logging.", ex);
			}

			SetupTheme ();

			var args = options.RemainingArgs.ToArray ();
			Gtk.Application.Init (BrandingService.ApplicationName, ref args);

			LoggingService.LogInfo ("Using GTK+ {0}", IdeVersionInfo.GetGtkVersion ());

			// XWT initialization
			FilePath p = typeof(IdeStartup).Assembly.Location;
			Assembly.LoadFrom (p.ParentDirectory.Combine ("Xwt.Gtk.dll"));
			Xwt.Application.InitializeAsGuest (Xwt.ToolkitType.Gtk);
			Xwt.Toolkit.CurrentEngine.RegisterBackend<IExtendedTitleBarWindowBackend,GtkExtendedTitleBarWindowBackend> ();
			Xwt.Toolkit.CurrentEngine.RegisterBackend<IExtendedTitleBarDialogBackend,GtkExtendedTitleBarDialogBackend> ();

			//default to Windows IME on Windows
			if (Platform.IsWindows && Mono.TextEditor.GtkWorkarounds.GtkMinorVersion >= 16) {
				var settings = Gtk.Settings.Default;
				var val = Mono.TextEditor.GtkWorkarounds.GetProperty (settings, "gtk-im-module");
				if (string.IsNullOrEmpty (val.Val as string))
					Mono.TextEditor.GtkWorkarounds.SetProperty (settings, "gtk-im-module", new GLib.Value ("ime"));
			}
			
			InternalLog.Initialize ();
			string socket_filename = null;
			EndPoint ep = null;
			
			DispatchService.Initialize ();

			// Set a synchronization context for the main gtk thread
			SynchronizationContext.SetSynchronizationContext (new GtkSynchronizationContext ());
			Runtime.MainSynchronizationContext = SynchronizationContext.Current;
			
			AddinManager.AddinLoadError += OnAddinError;
			
			var startupInfo = new StartupInfo (args);
			
			// If a combine was specified, force --newwindow.
			
			if (!options.NewWindow && startupInfo.HasFiles) {
				Counters.Initialization.Trace ("Pre-Initializing Runtime to load files in existing window");
				Runtime.Initialize (true);
				foreach (var file in startupInfo.RequestedFileList) {
					if (MonoDevelop.Projects.Services.ProjectService.IsWorkspaceItemFile (file.FileName)) {
						options.NewWindow = true;
						break;
					}
				}
			}
			
			Counters.Initialization.Trace ("Initializing Runtime");
			Runtime.Initialize (true);

			IdeApp.Customizer.OnCoreInitialized ();

			Counters.Initialization.Trace ("Initializing theme");

			DefaultTheme = Gtk.Settings.Default.ThemeName;
			string theme = IdeApp.Preferences.UserInterfaceTheme;
			if (string.IsNullOrEmpty (theme))
				theme = DefaultTheme;
			ValidateGtkTheme (ref theme);
			if (theme != DefaultTheme)
				Gtk.Settings.Default.ThemeName = theme;
			
			IProgressMonitor monitor = new MonoDevelop.Core.ProgressMonitoring.ConsoleProgressMonitor ();
			
			monitor.BeginTask (GettextCatalog.GetString ("Starting {0}", BrandingService.ApplicationName), 2);

			//make sure that the platform service is initialised so that the Mac platform can subscribe to open-document events
			Counters.Initialization.Trace ("Initializing Platform Service");
			DesktopService.Initialize ();
			
			monitor.Step (1);

			if (options.IpcTcp) {
				listen_socket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
				ep = new IPEndPoint (IPAddress.Loopback, ipcBasePort + HashSdbmBounded (Environment.UserName));
			} else {
				socket_filename = "/tmp/md-" + Environment.GetEnvironmentVariable ("USER") + "-socket";
				listen_socket = new Socket (AddressFamily.Unix, SocketType.Stream, ProtocolType.IP);
				ep = new UnixEndPoint (socket_filename);
			}
				
			// If not opening a combine, connect to existing monodevelop and pass filename(s) and exit
			if (!options.NewWindow && startupInfo.HasFiles) {
				try {
					StringBuilder builder = new StringBuilder ();
					foreach (var file in startupInfo.RequestedFileList) {
						builder.AppendFormat ("{0};{1};{2}\n", file.FileName, file.Line, file.Column);
					}
					listen_socket.Connect (ep);
					listen_socket.Send (Encoding.UTF8.GetBytes (builder.ToString ()));
					return 0;
				} catch {
					// Reset the socket
					if (null != socket_filename && File.Exists (socket_filename))
						File.Delete (socket_filename);
				}
			}
			
			Counters.Initialization.Trace ("Checking System");
			string version = Assembly.GetEntryAssembly ().GetName ().Version.Major + "." + Assembly.GetEntryAssembly ().GetName ().Version.Minor;
			
			if (Assembly.GetEntryAssembly ().GetName ().Version.Build != 0)
				version += "." + Assembly.GetEntryAssembly ().GetName ().Version.Build;
			if (Assembly.GetEntryAssembly ().GetName ().Version.Revision != 0)
				version += "." + Assembly.GetEntryAssembly ().GetName ().Version.Revision;

			CheckFileWatcher ();
			
			Exception error = null;
			int reportedFailures = 0;

			try {
				Counters.Initialization.Trace ("Loading Icons");
				//force initialisation before the workbench so that it can register stock icons for GTK before they get requested
				ImageService.Initialize ();
				
				if (errorsList.Count > 0) {
					using (AddinLoadErrorDialog dlg = new AddinLoadErrorDialog ((AddinError[]) errorsList.ToArray (typeof(AddinError)), false)) {
						if (!dlg.Run ())
							return 1;
					}
					reportedFailures = errorsList.Count;
				}

				if (!CheckSCPlugin ())
					return 1;

				// no alternative for Application.ThreadException?
				// Application.ThreadException += new ThreadExceptionEventHandler(ShowErrorBox);

				Counters.Initialization.Trace ("Initializing IdeApp");
				IdeApp.Initialize (monitor);

				// Load requested files
				Counters.Initialization.Trace ("Opening Files");

				// load previous combine
				if (IdeApp.Preferences.LoadPrevSolutionOnStartup && !startupInfo.HasSolutionFile && !IdeApp.Workspace.WorkspaceItemIsOpening && !IdeApp.Workspace.IsOpen) {
					var proj = DesktopService.RecentFiles.GetProjects ().FirstOrDefault ();
					if (proj != null)
						IdeApp.Workspace.OpenWorkspaceItem (proj.FileName).WaitForCompleted ();
				}

				IdeApp.OpenFiles (startupInfo.RequestedFileList);
				
				monitor.Step (1);
			
			} catch (Exception e) {
				error = e;
			} finally {
				monitor.Dispose ();
			}
			
			if (error != null) {
				string message = BrandingService.BrandApplicationName (GettextCatalog.GetString ("MonoDevelop failed to start"));
				MessageService.ShowFatalError (message, null, error);
				return 1;
			}

			if (errorsList.Count > reportedFailures) {
				using (AddinLoadErrorDialog dlg = new AddinLoadErrorDialog ((AddinError[]) errorsList.ToArray (typeof(AddinError)), true))
					dlg.Run ();
			}
			
			errorsList = null;
			
			// FIXME: we should probably track the last 'selected' one
			// and do this more cleanly
			try {
				listen_socket.Bind (ep);
				listen_socket.Listen (5);
				listen_socket.BeginAccept (new AsyncCallback (ListenCallback), listen_socket);
			} catch {
				// Socket already in use
			}
			
			initialized = true;
			MessageService.RootWindow = IdeApp.Workbench.RootWindow;
			Thread.CurrentThread.Name = "GUI Thread";
			Counters.Initialization.Trace ("Running IdeApp");
			Counters.Initialization.EndTiming ();
				
			AddinManager.AddExtensionNodeHandler("/MonoDevelop/Ide/InitCompleteHandlers", OnExtensionChanged);
			StartLockupTracker ();
			IdeApp.Run ();

			IdeApp.Customizer.OnIdeShutdown ();
			
			// unloading services
			if (null != socket_filename)
				File.Delete (socket_filename);
			lockupCheckRunning = false;
			Runtime.Shutdown ();

			IdeApp.Customizer.OnCoreShutdown ();

			InstrumentationService.Stop ();
			AddinManager.AddinLoadError -= OnAddinError;
			
			return 0;
		}
Example #2
0
		public static MonoDevelopOptions Parse (string[] args)
		{
			var opt = new MonoDevelopOptions ();
			var optSet = opt.GetOptionSet ();
			
			try {
				opt.RemainingArgs = optSet.Parse (args);
			} catch (Mono.Options.OptionException ex) {
				opt.Error = ex.ToString ();
			}
			
			if (opt.Error != null) {
				Console.WriteLine ("ERROR: {0}", opt.Error);
				Console.WriteLine ("Pass --help for usage information.");
			}
			
			if (opt.ShowHelp) {
				Console.WriteLine (BrandingService.ApplicationName + " " + BuildInfo.VersionLabel);
				Console.WriteLine ("Options:");
				optSet.WriteOptionDescriptions (Console.Out);
				const string openFileText = "      file.ext;line;column";
				Console.Write (openFileText);
				Console.Write (new string (' ', 29 - openFileText.Length));
				Console.WriteLine ("Opens a file at specified integer line and column");
			}
			
			return opt;
		}
Example #3
0
		public static MonoDevelopOptions Parse (string[] args)
		{
			var opt = new MonoDevelopOptions ();
			var optSet = opt.GetOptionSet ();
			
			try {
				opt.RemainingArgs = optSet.Parse (args);
			} catch (Mono.Options.OptionException ex) {
				opt.Error = ex.ToString ();
			}
			
			if (opt.Error != null) {
				Console.WriteLine ("ERROR: {0}", opt.Error);
				Console.WriteLine ("Pass --help for usage information.");
			}
			
			if (opt.ShowHelp) {
				Console.WriteLine (BrandingService.ApplicationName + " " + BuildInfo.VersionLabel);
				Console.WriteLine ("Options:");
				optSet.WriteOptionDescriptions (Console.Out);
			}
			
			return opt;
		}
Example #4
0
		int Run (MonoDevelopOptions options)
		{
			Counters.Initialization.BeginTiming ();
			
			if (options.PerfLog) {
				string logFile = Path.Combine (Environment.CurrentDirectory, "monodevelop.perf-log");
				LoggingService.LogInfo ("Logging instrumentation service data to file: " + logFile);
				InstrumentationService.StartAutoSave (logFile, 1000);
			}
			
			Counters.Initialization.Trace ("Initializing GTK");
			SetupExceptionManager ();
			
			try {
				MonoDevelop.Ide.Gui.GLibLogging.Enabled = true;
			} catch (Exception ex) {
				LoggingService.LogError ("Error initialising GLib logging.", ex);
			}

			SetupTheme ();

			var args = options.RemainingArgs.ToArray ();
			Gtk.Application.Init (BrandingService.ApplicationName, ref args);

			FilePath p = typeof(IdeStartup).Assembly.Location;
			Assembly.LoadFrom (p.ParentDirectory.Combine ("Xwt.Gtk.dll"));
			Xwt.Application.Initialize (Xwt.ToolkitType.Gtk);
			Xwt.Engine.Toolkit.ExitUserCode (null);

			//default to Windows IME on Windows
			if (Platform.IsWindows && Mono.TextEditor.GtkWorkarounds.GtkMinorVersion >= 16) {
				var settings = Gtk.Settings.Default;
				var val = Mono.TextEditor.GtkWorkarounds.GetProperty (settings, "gtk-im-module");
				if (string.IsNullOrEmpty (val.Val as string))
					Mono.TextEditor.GtkWorkarounds.SetProperty (settings, "gtk-im-module", new GLib.Value ("ime"));
			}
			
			InternalLog.Initialize ();
			string socket_filename = null;
			EndPoint ep = null;
			
			DispatchService.Initialize ();
			
			// Set a synchronization context for the main gtk thread
			SynchronizationContext.SetSynchronizationContext (new GtkSynchronizationContext ());
			
			AddinManager.AddinLoadError += OnAddinError;
			
			var startupInfo = new StartupInfo (args);
			
			// If a combine was specified, force --newwindow.
			
			if (!options.NewWindow && startupInfo.HasFiles) {
				Counters.Initialization.Trace ("Pre-Initializing Runtime to load files in existing window");
				Runtime.Initialize (true);
				foreach (var file in startupInfo.RequestedFileList) {
					if (MonoDevelop.Projects.Services.ProjectService.IsWorkspaceItemFile (file.FileName)) {
						options.NewWindow = true;
						break;
					}
				}
			}
			
			Counters.Initialization.Trace ("Initializing Runtime");
			Runtime.Initialize (true);

			Counters.Initialization.Trace ("Initializing theme and splash window");

			DefaultTheme = Gtk.Settings.Default.ThemeName;
			if (!string.IsNullOrEmpty (IdeApp.Preferences.UserInterfaceTheme)) {
				string theme;
				if (!ValidateGtkTheme (IdeApp.Preferences.UserInterfaceTheme, out theme))
					return 1;
				Gtk.Settings.Default.ThemeName = theme;
			}
			
			//don't show the splash screen on the Mac, so instead we get the expected "Dock bounce" effect
			//this also enables the Mac platform service to subscribe to open document events before the GUI loop starts.
			if (Platform.IsMac)
				options.NoSplash = true;
			
			IProgressMonitor monitor;
			
			if (options.NoSplash) {
				monitor = new MonoDevelop.Core.ProgressMonitoring.ConsoleProgressMonitor ();
			} else {
				monitor = SplashScreenForm.SplashScreen;
				SplashScreenForm.SplashScreen.ShowAll ();
			}
			
			monitor.BeginTask (GettextCatalog.GetString ("Starting {0}", BrandingService.ApplicationName), 2);

			//make sure that the platform service is initialised so that the Mac platform can subscribe to open-document events
			Counters.Initialization.Trace ("Initializing Platform Service");
			DesktopService.Initialize ();
			
			monitor.Step (1);

			if (options.IpcTcp) {
				listen_socket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
				ep = new IPEndPoint (IPAddress.Loopback, ipcBasePort + HashSdbmBounded (Environment.UserName));
			} else {
				socket_filename = "/tmp/md-" + Environment.GetEnvironmentVariable ("USER") + "-socket";
				listen_socket = new Socket (AddressFamily.Unix, SocketType.Stream, ProtocolType.IP);
				ep = new UnixEndPoint (socket_filename);
			}
				
			// If not opening a combine, connect to existing monodevelop and pass filename(s) and exit
			if (!options.NewWindow && startupInfo.HasFiles) {
				try {
					StringBuilder builder = new StringBuilder ();
					foreach (var file in startupInfo.RequestedFileList) {
						builder.AppendFormat ("{0};{1};{2}\n", file.FileName, file.Line, file.Column);
					}
					listen_socket.Connect (ep);
					listen_socket.Send (Encoding.UTF8.GetBytes (builder.ToString ()));
					return 0;
				} catch {
					// Reset the socket
					if (null != socket_filename && File.Exists (socket_filename))
						File.Delete (socket_filename);
				}
			}
			
			Counters.Initialization.Trace ("Checking System");
			string version = Assembly.GetEntryAssembly ().GetName ().Version.Major + "." + Assembly.GetEntryAssembly ().GetName ().Version.Minor;
			
			if (Assembly.GetEntryAssembly ().GetName ().Version.Build != 0)
				version += "." + Assembly.GetEntryAssembly ().GetName ().Version.Build;
			if (Assembly.GetEntryAssembly ().GetName ().Version.Revision != 0)
				version += "." + Assembly.GetEntryAssembly ().GetName ().Version.Revision;
			
			// System checks
			if (!CheckBug77135 ())
				return 1;
			
			CheckFileWatcher ();
			
			Exception error = null;
			int reportedFailures = 0;
			
			try {
				Counters.Initialization.Trace ("Loading Icons");
				//force initialisation before the workbench so that it can register stock icons for GTK before they get requested
				ImageService.Initialize ();
				
				if (errorsList.Count > 0) {
					if (monitor is SplashScreenForm)
						SplashScreenForm.SplashScreen.Hide ();
					AddinLoadErrorDialog dlg = new AddinLoadErrorDialog ((AddinError[]) errorsList.ToArray (typeof(AddinError)), false);
					if (!dlg.Run ())
						return 1;
					if (monitor is SplashScreenForm)
						SplashScreenForm.SplashScreen.Show ();
					reportedFailures = errorsList.Count;
				}
				
				// no alternative for Application.ThreadException?
				// Application.ThreadException += new ThreadExceptionEventHandler(ShowErrorBox);

				Counters.Initialization.Trace ("Initializing IdeApp");
				IdeApp.Initialize (monitor);
				
				// Load requested files
				Counters.Initialization.Trace ("Opening Files");
				IdeApp.OpenFiles (startupInfo.RequestedFileList);
				
				monitor.Step (1);
			
			} catch (Exception e) {
				error = e;
			} finally {
				monitor.Dispose ();
			}
			
			if (error != null) {
				LoggingService.LogFatalError (null, error);
				MessageService.ShowException (error,
				                              BrandingService.BrandApplicationName (GettextCatalog.GetString ("MonoDevelop failed to start. The following error has been reported: ") + error.Message));
				return 1;
			}

			if (errorsList.Count > reportedFailures) {
				AddinLoadErrorDialog dlg = new AddinLoadErrorDialog ((AddinError[]) errorsList.ToArray (typeof(AddinError)), true);
				dlg.Run ();
			}
			
			errorsList = null;
			
			// FIXME: we should probably track the last 'selected' one
			// and do this more cleanly
			try {
				listen_socket.Bind (ep);
				listen_socket.Listen (5);
				listen_socket.BeginAccept (new AsyncCallback (ListenCallback), listen_socket);
			} catch {
				// Socket already in use
			}
			
			initialized = true;
			MessageService.RootWindow = IdeApp.Workbench.RootWindow;
			Thread.CurrentThread.Name = "GUI Thread";
			Counters.Initialization.Trace ("Running IdeApp");
			Counters.Initialization.EndTiming ();
				
			AddinManager.AddExtensionNodeHandler("/MonoDevelop/Ide/InitCompleteHandlers", OnExtensionChanged);
			
			IdeApp.Run ();
			
			// unloading services
			if (null != socket_filename)
				File.Delete (socket_filename);
			
			Runtime.Shutdown ();
			InstrumentationService.Stop ();
			
			return 0;
		}
Example #5
0
		public int Run (string[] args)
		{
			Counters.Initialization.BeginTiming ();
			
			var options = new MonoDevelopOptions ();
			var optionsSet = new Mono.Options.OptionSet () {
				{ "nologo", "Do not display splash screen.", s => options.NoLogo = true },
				{ "ipc-tcp", "Use the Tcp channel for inter-process comunication.", s => options.IpcTcp = true },
				{ "newwindow", "Do not open in an existing instance of MonoDevelop", s => options.NewWindow = true },
				{ "h|?|help", "Show help", s => options.ShowHelp = true },
				{ "clog", "Log internal counter data", s => options.LogCounters = true },
				{ "clog-interval=", "Interval between counter logs (in miliseconds)", s => options.LogCountersInterval = int.Parse (s) },
			};
			var remainingArgs = optionsSet.Parse (args);
			if (options.ShowHelp) {
				Console.WriteLine ("MonoDevelop IDE " + MonoDevelop.Ide.BuildVariables.PackageVersionLabel);
				Console.WriteLine ("Options:");
				optionsSet.WriteOptionDescriptions (Console.Out);
				return 0;
			}
			
			if (options.LogCounters) {
				string logFile = Path.Combine (Environment.CurrentDirectory, "monodevelop.clog");
				LoggingService.LogInfo ("Logging instrumentation service data to file: " + logFile);
				InstrumentationService.StartAutoSave (logFile, 1000);
			}
			
			Counters.Initialization.Trace ("Initializing GTK");
			SetupExceptionManager ();
			
			try {
				MonoDevelop.Ide.Gui.GLibLogging.Enabled = true;
			} catch (Exception ex) {
				LoggingService.LogError ("Error initialising GLib logging.", ex);
			}
			
			//OSXFIXME
			Gtk.Application.Init ("monodevelop", ref args);
			InternalLog.Initialize ();
			string socket_filename = null;
			EndPoint ep = null;
			
			DispatchService.Initialize ();
			
			// Set a synchronization context for the main gtk thread
			SynchronizationContext.SetSynchronizationContext (new GtkSynchronizationContext ());
			
			AddinManager.AddinLoadError += OnAddinError;
			
			var startupInfo = new StartupInfo (remainingArgs);
			
			// If a combine was specified, force --newwindow.
			
			if(!options.NewWindow && startupInfo.HasFiles) {
				Counters.Initialization.Trace ("Pre-Initializing Runtime to load files in existing window");
				Runtime.Initialize (true);
				foreach (var file in startupInfo.RequestedFileList) {
					if (MonoDevelop.Projects.Services.ProjectService.IsWorkspaceItemFile (file.FileName)) {
						options.NewWindow = true;
						break;
					}
				}
			}
			
			DefaultTheme = Gtk.Settings.Default.ThemeName;
			if (!string.IsNullOrEmpty (IdeApp.Preferences.UserInterfaceTheme))
				Gtk.Settings.Default.ThemeName = IdeApp.Preferences.UserInterfaceTheme;
			
			//don't show the splash screen on the Mac, so instead we get the expected "Dock bounce" effect
			//this also enables the Mac platform service to subscribe to open document events before the GUI loop starts.
			if (PropertyService.IsMac)
				options.NoLogo = true;
			
			IProgressMonitor monitor;
			
			if (options.NoLogo) {
				monitor = new MonoDevelop.Core.ProgressMonitoring.ConsoleProgressMonitor ();
			} else {
				monitor = SplashScreenForm.SplashScreen;
				SplashScreenForm.SplashScreen.ShowAll ();
			}
			
			Counters.Initialization.Trace ("Initializing Runtime");
			monitor.BeginTask (GettextCatalog.GetString ("Starting MonoDevelop"), 2);
			monitor.Step (1);
			Runtime.Initialize (true);
			
			//make sure that the platform service is initialised so that the Mac platform can subscribe to open-document events
			Counters.Initialization.Trace ("Initializing Platform Service");
			DesktopService.Initialize ();
			monitor.Step (1);
			monitor.EndTask ();
			
			monitor.Step (1);

			if (options.IpcTcp) {
				listen_socket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
				ep = new IPEndPoint (IPAddress.Loopback, ipcBasePort + HashSDBMBounded (Environment.UserName));
			} else {
				socket_filename = "/tmp/md-" + Environment.GetEnvironmentVariable ("USER") + "-socket";
				listen_socket = new Socket (AddressFamily.Unix, SocketType.Stream, ProtocolType.IP);
				ep = new UnixEndPoint (socket_filename);
			}
				
			// If not opening a combine, connect to existing monodevelop and pass filename(s) and exit
			if (!options.NewWindow && startupInfo.HasFiles) {
				try {
					StringBuilder builder = new StringBuilder ();
					foreach (var file in startupInfo.RequestedFileList) {
						builder.AppendFormat ("{0};{1};{2}\n", file.FileName, file.Line, file.Column);
					}
					listen_socket.Connect (ep);
					listen_socket.Send (Encoding.UTF8.GetBytes (builder.ToString ()));
					return 0;
				} catch {
					// Reset the socket
					if (null != socket_filename && File.Exists (socket_filename))
						File.Delete (socket_filename);
				}
			}
			
			Counters.Initialization.Trace ("Checking System");
			string version = Assembly.GetEntryAssembly ().GetName ().Version.Major + "." + Assembly.GetEntryAssembly ().GetName ().Version.Minor;
			
			if (Assembly.GetEntryAssembly ().GetName ().Version.Build != 0)
				version += "." + Assembly.GetEntryAssembly ().GetName ().Version.Build;
			if (Assembly.GetEntryAssembly ().GetName ().Version.Revision != 0)
				version += "." + Assembly.GetEntryAssembly ().GetName ().Version.Revision;
			
			// System checks
			if (!CheckBug77135 ())
				return 1;
			
			if (!CheckQtCurve ())
				return 1;

			CheckFileWatcher ();
			
			Exception error = null;
			int reportedFailures = 0;
			
			try {
				Counters.Initialization.Trace ("Loading Icons");
				//force initialisation before the workbench so that it can register stock icons for GTK before they get requested
				ImageService.Initialize ();
				
				if (errorsList.Count > 0) {
					if (monitor is SplashScreenForm)
						SplashScreenForm.SplashScreen.Hide ();
					AddinLoadErrorDialog dlg = new AddinLoadErrorDialog ((AddinError[]) errorsList.ToArray (typeof(AddinError)), false);
					if (!dlg.Run ())
						return 1;
					if (monitor is SplashScreenForm)
						SplashScreenForm.SplashScreen.Show ();
					reportedFailures = errorsList.Count;
				}
				
				// no alternative for Application.ThreadException?
				// Application.ThreadException += new ThreadExceptionEventHandler(ShowErrorBox);

				Counters.Initialization.Trace ("Initializing IdeApp");
				IdeApp.Initialize (monitor);
				
				// Load requested files
				Counters.Initialization.Trace ("Opening Files");
				IdeApp.OpenFiles (startupInfo.RequestedFileList);
				
				monitor.Step (1);
			
			} catch (Exception e) {
				error = e;
			} finally {
				monitor.Dispose ();
			}
			
			if (error != null) {
				MessageService.ShowException (error,
				                              GettextCatalog.GetString ("MonoDevelop failed to start. The following error has been reported: ") + error.Message);
				return 1;
			}

			if (errorsList.Count > reportedFailures) {
				AddinLoadErrorDialog dlg = new AddinLoadErrorDialog ((AddinError[]) errorsList.ToArray (typeof(AddinError)), true);
				dlg.Run ();
			}
			
			errorsList = null;
			
			// FIXME: we should probably track the last 'selected' one
			// and do this more cleanly
			try {
				listen_socket.Bind (ep);
				listen_socket.Listen (5);
				listen_socket.BeginAccept (new AsyncCallback (ListenCallback), listen_socket);
			} catch {
				// Socket already in use
			}
			
			initialized = true;
			MessageService.RootWindow = IdeApp.Workbench.RootWindow;
			Thread.CurrentThread.Name = "GUI Thread";
			Counters.Initialization.Trace ("Running IdeApp");
			Counters.Initialization.EndTiming ();
				
			AddinManager.AddExtensionNodeHandler("/MonoDevelop/Ide/InitCompleteHandlers", OnExtensionChanged);
				
			IdeApp.Run ();
			
			// unloading services
			if (null != socket_filename)
				File.Delete (socket_filename);
			
			Runtime.Shutdown ();
			InstrumentationService.Stop ();
			
			System.Environment.Exit (0);
			return 0;
		}
Example #6
0
        public static int Main(string[] args, IdeCustomizer customizer = null)
        {
            var options = MonoDevelopOptions.Parse(args);

            if (options.ShowHelp || options.Error != null)
            {
                return(options.Error != null? -1 : 0);
            }

            LoggingService.Initialize(options.RedirectOutput);

            if (customizer == null)
            {
                customizer = LoadBrandingCustomizer();
            }
            options.IdeCustomizer = customizer;

            int ret = -1;

            try {
                var exename = Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().Location);
                if (!Platform.IsMac && !Platform.IsWindows)
                {
                    exename = exename.ToLower();
                }
                Runtime.SetProcessName(exename);
                var app = new IdeStartup();
                ret = app.Run(options);
            } catch (Exception ex) {
                LoggingService.LogFatalError(
                    string.Format(
                        "{0} failed to start. Some of the assemblies required to run {0} (for example gtk-sharp)" +
                        "may not be properly installed in the GAC.",
                        BrandingService.ApplicationName
                        ), ex);

                if (Platform.IsWindows)
                {
                    string url     = "http://monodevelop.com/Download";
                    string caption = "Fatal Error";
                    string message =
                        "{0} failed to start. Some of the assemblies required to run {0} (for example GTK#) " +
                        "may not be properly installed in the GAC.\n\r\n\r" +
                        "Please click OK to open the download page, where " +
                        "you can download the necessary dependencies for {0} to run.";

                    if (DisplayWindowsOkCancelMessage(
                            string.Format(message, BrandingService.ApplicationName, url), caption)
                        )
                    {
                        Process.Start(url);
                    }
                }
            } finally {
                Runtime.Shutdown();
            }

            LoggingService.Shutdown();

            return(ret);
        }
Example #7
0
        int Run(MonoDevelopOptions options)
        {
            CompositionManager.ConfigureUninitializedMefHandling(throwException: true);

            LoggingService.LogInfo("Starting {0} {1}", BrandingService.ApplicationLongName, IdeVersionInfo.MonoDevelopVersion);
            LoggingService.LogInfo("Build Information{0}{1}", Environment.NewLine, SystemInformation.GetBuildInformation());
            LoggingService.LogInfo("Running on {0}", RuntimeVersionInfo.GetRuntimeInfo());

            //ensure native libs initialized before we hit anything that p/invokes
            Platform.Initialize();
            IdeStartupTracker.StartupTracker.MarkSection("PlatformInitialization");

            GettextCatalog.Initialize();
            IdeStartupTracker.StartupTracker.MarkSection("GettextInitialization");

            LoggingService.LogInfo("Operating System: {0}", SystemInformation.GetOperatingSystemDescription());

            // The assembly resolver for MSBuild 15 assemblies needs to be defined early on.
            // Whilst Runtime.Initialize loads the MSBuild 15 assemblies from Mono this seems
            // to be too late to prevent the MEF composition and the static registrar from
            // failing to load the MonoDevelop.Ide assembly which now uses MSBuild 15 assemblies.
            ResolveMSBuildAssemblies();

            Counters.InitializationTracker = Counters.Initialization.BeginTiming();

            if (options.PerfLog)
            {
                string logFile = Path.Combine(Environment.CurrentDirectory, "monodevelop.perf-log");
                LoggingService.LogInfo("Logging instrumentation service data to file: " + logFile);
                InstrumentationService.StartAutoSave(logFile, 1000);
            }

            Counters.InitializationTracker.Trace("Initializing GTK");
            if (Platform.IsWindows && !CheckWindowsGtk())
            {
                return(1);
            }
            SetupExceptionManager();

            // explicit GLib type system initialization for GLib < 2.36 before any other type system access
            GLib.GType.Init();

            var args = options.RemainingArgs.ToArray();

            IdeTheme.InitializeGtk(BrandingService.ApplicationName, ref args);

            startupInfo = new StartupInfo(options, args);
            if (startupInfo.HasFiles)
            {
                // If files are present, consider started from the commandline as being the same as file manager.
                // On macOS, we need to wait until the DidFinishLaunching notification to find out we were launched from the Finder
                IdeApp.LaunchReason = IdeApp.LaunchType.LaunchedFromFileManager;
            }
            else if (!Platform.IsMac)
            {
                IdeApp.LaunchReason = IdeApp.LaunchType.Normal;
            }

            IdeApp.Customizer = options.IdeCustomizer ?? new IdeCustomizer();
            try {
                IdeApp.Customizer.Initialize(startupInfo);
            } catch (UnauthorizedAccessException ua) {
                LoggingService.LogError("Unauthorized access: " + ua.Message);
                return(1);
            }

            try {
                GLibLogging.Enabled = true;
            } catch (Exception ex) {
                LoggingService.LogError("Error initialising GLib logging.", ex);
            }

            IdeStartupTracker.StartupTracker.MarkSection("GtkInitialization");
            LoggingService.LogInfo("Using GTK+ {0}", IdeVersionInfo.GetGtkVersion());

            // XWT initialization
            FilePath p = typeof(IdeStartup).Assembly.Location;

            Runtime.LoadAssemblyFrom(p.ParentDirectory.Combine("Xwt.Gtk.dll"));
            Xwt.Application.InitializeAsGuest(Xwt.ToolkitType.Gtk);
            Xwt.Toolkit.CurrentEngine.RegisterBackend <IExtendedTitleBarWindowBackend, GtkExtendedTitleBarWindowBackend> ();
            Xwt.Toolkit.CurrentEngine.RegisterBackend <IExtendedTitleBarDialogBackend, GtkExtendedTitleBarDialogBackend> ();
            IdeTheme.SetupXwtTheme();

            IdeStartupTracker.StartupTracker.MarkSection("XwtInitialization");

            //default to Windows IME on Windows
            if (Platform.IsWindows && GtkWorkarounds.GtkMinorVersion >= 16)
            {
                var settings = Gtk.Settings.Default;
                var val      = GtkWorkarounds.GetProperty(settings, "gtk-im-module");
                if (string.IsNullOrEmpty(val.Val as string))
                {
                    GtkWorkarounds.SetProperty(settings, "gtk-im-module", new GLib.Value("ime"));
                }
            }

            DispatchService.Initialize();

            // Set a synchronization context for the main gtk thread
            SynchronizationContext.SetSynchronizationContext(DispatchService.SynchronizationContext);
            Runtime.MainSynchronizationContext = SynchronizationContext.Current;

            IdeStartupTracker.StartupTracker.MarkSection("DispatchInitialization");

            // Initialize Roslyn's synchronization context
            RoslynServices.RoslynService.Initialize();

            IdeStartupTracker.StartupTracker.MarkSection("RoslynInitialization");

            AddinManager.AddinLoadError += OnAddinError;

            Counters.InitializationTracker.Trace("Initializing Runtime");
            Runtime.Initialize(true);

            // Register services used by the IDE

            RegisterServices();

            // If a combine was specified, force --newwindow.

            if (!options.NewWindow && startupInfo.HasFiles)
            {
                foreach (var file in startupInfo.RequestedFileList)
                {
                    if (MonoDevelop.Projects.Services.ProjectService.IsWorkspaceItemFile(file.FileName))
                    {
                        options.NewWindow = true;
                        break;
                    }
                }
            }

            instanceConnection = new IdeInstanceConnection(options.IpcTcp);

            // If not opening a combine, connect to existing monodevelop and pass filename(s) and exit
            if (!options.NewWindow && startupInfo.HasFiles && instanceConnection.TryConnect(startupInfo))
            {
                return(0);
            }

            IdeStartupTracker.StartupTracker.MarkSection("RuntimeInitialization");

            bool restartRequested = PropertyService.Get("MonoDevelop.Core.RestartRequested", false);

            startupInfo.Restarted = restartRequested;
            PropertyService.Set("MonoDevelop.Core.RestartRequested", false);

            Counters.InitializationTracker.Trace("Initializing theme");

            IdeTheme.SetupGtkTheme();

            IdeApp.Customizer.OnCoreInitialized();

            IdeStartupTracker.StartupTracker.MarkSection("ThemeInitialized");

            IdeApp.IsRunning = true;

            Xwt.Application.TranslationCatalog = new XwtTranslationCatalog();

            // Load the main menu before running the main loop
            var commandService = Runtime.GetService <CommandManager> ().Result;
            var desktopService = Runtime.GetService <DesktopService> ().Result;

            desktopService.SetGlobalMenu(commandService, DefaultWorkbench.MainMenuPath, DefaultWorkbench.AppMenuPath);

            // Run the main loop
            Gtk.Application.Invoke((s, e) => {
                MainLoop(options, startupInfo).Ignore();
            });
            Gtk.Application.Run();

            IdeApp.IsRunning = false;

            IdeApp.Customizer.OnIdeShutdown();

            instanceConnection.Dispose();

            lockupCheckRunning = false;
            Runtime.Shutdown();

            IdeApp.Customizer.OnCoreShutdown();

            InstrumentationService.Stop();

            MonoDevelop.Components.GtkWorkarounds.Terminate();

            return(0);
        }
Example #8
0
        async Task <int> MainLoop(MonoDevelopOptions options, StartupInfo startupInfo)
        {
            ProgressMonitor monitor = new MonoDevelop.Core.ProgressMonitoring.ConsoleProgressMonitor();

            monitor.BeginTask(GettextCatalog.GetString("Starting {0}", BrandingService.ApplicationName), 2);

            //make sure that the platform service is initialised so that the Mac platform can subscribe to open-document events
            Counters.InitializationTracker.Trace("Initializing Platform Service");

            var desktopService = await Runtime.GetService <DesktopService> ();

            var commandService = await Runtime.GetService <CommandManager> ();

            // load the global menu for the welcome window to avoid unresponsive menus on Mac
            desktopService.SetGlobalMenu(commandService, DefaultWorkbench.MainMenuPath, DefaultWorkbench.AppMenuPath);

            IdeStartupTracker.StartupTracker.MarkSection("PlatformInitialization");

            monitor.Step(1);

            Counters.InitializationTracker.Trace("Checking System");

            CheckFileWatcher();

            IdeStartupTracker.StartupTracker.MarkSection("FileWatcherInitialization");

            Exception error            = null;
            int       reportedFailures = 0;

            try {
                Counters.InitializationTracker.Trace("Loading Icons");
                //force initialisation before the workbench so that it can register stock icons for GTK before they get requested
                ImageService.Initialize();

                IdeStartupTracker.StartupTracker.MarkSection("ImageInitialization");

                // If we display an error dialog before the main workbench window on OS X then a second application menu is created
                // which is then replaced with a second empty Apple menu.
                // XBC #33699
                Counters.InitializationTracker.Trace("Initializing IdeApp");

                hideWelcomePage = options.NoStartWindow || startupInfo.HasFiles || IdeApp.Preferences.StartupBehaviour.Value != OnStartupBehaviour.ShowStartWindow;
                await IdeApp.Initialize(monitor, hideWelcomePage);

                IdeStartupTracker.StartupTracker.MarkSection("AppInitialization");

                if (errorsList.Count > 0)
                {
                    using (AddinLoadErrorDialog dlg = new AddinLoadErrorDialog(errorsList.ToArray(), false)) {
                        if (!dlg.Run())
                        {
                            return(1);
                        }
                    }
                    reportedFailures = errorsList.Count;
                }

                if (!CheckSCPlugin())
                {
                    return(1);
                }

                // Load requested files
                Counters.InitializationTracker.Trace("Opening Files");

                // load previous combine
                RecentFile openedProject = null;
                if (IdeApp.Preferences.StartupBehaviour.Value == OnStartupBehaviour.LoadPreviousSolution && !startupInfo.HasSolutionFile && !IdeApp.Workspace.WorkspaceItemIsOpening && !IdeApp.Workspace.IsOpen)
                {
                    openedProject = IdeServices.DesktopService.RecentFiles.MostRecentlyUsedProject;
                    if (openedProject != null)
                    {
                        var metadata = GetOpenWorkspaceOnStartupMetadata();
                        IdeApp.Workspace.OpenWorkspaceItem(openedProject.FileName, true, true, metadata).ContinueWith(t => IdeApp.OpenFilesAsync(startupInfo.RequestedFileList, metadata), TaskScheduler.FromCurrentSynchronizationContext()).Ignore();
                        startupInfo.OpenedRecentProject = true;
                    }
                }
                if (openedProject == null)
                {
                    IdeApp.OpenFilesAsync(startupInfo.RequestedFileList, GetOpenWorkspaceOnStartupMetadata()).Ignore();
                    startupInfo.OpenedFiles = startupInfo.HasFiles;
                }

                monitor.Step(1);
            } catch (Exception e) {
                error = e;
            } finally {
                monitor.Dispose();
            }

            if (error != null)
            {
                string message = BrandingService.BrandApplicationName(GettextCatalog.GetString("MonoDevelop failed to start"));
                message = message + "\n\n" + error.Message;
                MessageService.ShowFatalError(message, null, error);

                return(1);
            }

            if (errorsList.Count > reportedFailures)
            {
                using (AddinLoadErrorDialog dlg = new AddinLoadErrorDialog(errorsList.ToArray(), true))
                    dlg.Run();
            }

            errorsList = null;
            AddinManager.AddinLoadError -= OnAddinError;

            IdeStartupTracker.StartupTracker.MarkSection("BasicInitializationCompleted");

            instanceConnection.FileOpenRequested += (sender, a) => {
                foreach (var e in a)
                {
                    OpenFile(e.FileName);
                }
            };

            instanceConnection.StartListening();

            IdeStartupTracker.StartupTracker.MarkSection("SocketInitialization");

            initialized = true;
            MessageService.RootWindow    = IdeApp.Workbench.RootWindow;
            Xwt.MessageDialog.RootWindow = Xwt.Toolkit.CurrentEngine.WrapWindow(IdeApp.Workbench.RootWindow);

            IdeStartupTracker.StartupTracker.MarkSection("WindowOpened");

            Thread.CurrentThread.Name = "GUI Thread";
            Counters.InitializationTracker.Trace("Running IdeApp");
            Counters.InitializationTracker.End();
            Counters.InitializationTracker = new NullTimeTracker();

            AddinManager.AddExtensionNodeHandler("/MonoDevelop/Ide/InitCompleteHandlers", OnExtensionChanged);
            StartLockupTracker();

            // This call is important so the current event loop is run before we run the main loop.
            // On Mac, the OpenDocuments event gets handled here, so we need to get the timeout
            // it queues before the OnIdle event so we can start opening a solution before
            // we show the main window.
            await Task.Yield();

            IdeStartupTracker.StartupTracker.MarkSection("PumpEventLoop");
            IdeStartupTracker.StartupTracker.Stop(startupInfo);

            GLib.Idle.Add(OnIdle);

            return(0);
        }
Example #9
0
        int Run(MonoDevelopOptions options)
        {
            LoggingService.LogInfo("Starting {0} {1}", BrandingService.ApplicationLongName, IdeVersionInfo.MonoDevelopVersion);
            LoggingService.LogInfo("Running on {0}", IdeVersionInfo.GetRuntimeInfo());

            //ensure native libs initialized before we hit anything that p/invokes
            Platform.Initialize();

            LoggingService.LogInfo("Operating System: {0}", SystemInformation.GetOperatingSystemDescription());

            Counters.Initialization.BeginTiming();

            if (options.PerfLog)
            {
                string logFile = Path.Combine(Environment.CurrentDirectory, "monodevelop.perf-log");
                LoggingService.LogInfo("Logging instrumentation service data to file: " + logFile);
                InstrumentationService.StartAutoSave(logFile, 1000);
            }

            Counters.Initialization.Trace("Initializing GTK");
            if (Platform.IsWindows && !CheckWindowsGtk())
            {
                return(1);
            }
            SetupExceptionManager();

            IdeApp.Customizer = options.IdeCustomizer ?? new IdeCustomizer();
            try {
                IdeApp.Customizer.Initialize();
            } catch (UnauthorizedAccessException ua) {
                LoggingService.LogError("Unauthorized access: " + ua.Message);
                return(1);
            }

            try {
                GLibLogging.Enabled = true;
            } catch (Exception ex) {
                LoggingService.LogError("Error initialising GLib logging.", ex);
            }

            var args = options.RemainingArgs.ToArray();

            IdeTheme.InitializeGtk(BrandingService.ApplicationName, ref args);

            LoggingService.LogInfo("Using GTK+ {0}", IdeVersionInfo.GetGtkVersion());

            // XWT initialization
            FilePath p = typeof(IdeStartup).Assembly.Location;

            Platform.AssemblyLoad(p.ParentDirectory.Combine("Xwt.Gtk.dll"));
            Xwt.Application.InitializeAsGuest(Xwt.ToolkitType.Gtk);
            Xwt.Toolkit.CurrentEngine.RegisterBackend <IExtendedTitleBarWindowBackend, GtkExtendedTitleBarWindowBackend> ();
            Xwt.Toolkit.CurrentEngine.RegisterBackend <IExtendedTitleBarDialogBackend, GtkExtendedTitleBarDialogBackend> ();
            IdeTheme.SetupXwtTheme();

            //default to Windows IME on Windows
            if (Platform.IsWindows && GtkWorkarounds.GtkMinorVersion >= 16)
            {
                var settings = Gtk.Settings.Default;
                var val      = GtkWorkarounds.GetProperty(settings, "gtk-im-module");
                if (string.IsNullOrEmpty(val.Val as string))
                {
                    GtkWorkarounds.SetProperty(settings, "gtk-im-module", new GLib.Value("ime"));
                }
            }

            string   socket_filename = null;
            EndPoint ep = null;

            DispatchService.Initialize();

            // Set a synchronization context for the main gtk thread
            SynchronizationContext.SetSynchronizationContext(DispatchService.SynchronizationContext);
            Runtime.MainSynchronizationContext = SynchronizationContext.Current;

            AddinManager.AddinLoadError += OnAddinError;

            var startupInfo = new StartupInfo(args);

            // If a combine was specified, force --newwindow.

            if (!options.NewWindow && startupInfo.HasFiles)
            {
                Counters.Initialization.Trace("Pre-Initializing Runtime to load files in existing window");
                Runtime.Initialize(true);
                foreach (var file in startupInfo.RequestedFileList)
                {
                    if (MonoDevelop.Projects.Services.ProjectService.IsWorkspaceItemFile(file.FileName))
                    {
                        options.NewWindow = true;
                        break;
                    }
                }
            }

            Counters.Initialization.Trace("Initializing Runtime");
            Runtime.Initialize(true);

            IdeApp.Customizer.OnCoreInitialized();

            Counters.Initialization.Trace("Initializing theme");

            IdeTheme.SetupGtkTheme();

            ProgressMonitor monitor = new MonoDevelop.Core.ProgressMonitoring.ConsoleProgressMonitor();

            monitor.BeginTask(GettextCatalog.GetString("Starting {0}", BrandingService.ApplicationName), 2);

            //make sure that the platform service is initialised so that the Mac platform can subscribe to open-document events
            Counters.Initialization.Trace("Initializing Platform Service");
            DesktopService.Initialize();

            monitor.Step(1);

            if (options.IpcTcp)
            {
                listen_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                ep            = new IPEndPoint(IPAddress.Loopback, ipcBasePort + HashSdbmBounded(Environment.UserName));
            }
            else
            {
                socket_filename = "/tmp/md-" + Environment.GetEnvironmentVariable("USER") + "-socket";
                listen_socket   = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP);
                ep = new UnixEndPoint(socket_filename);
            }

            // If not opening a combine, connect to existing monodevelop and pass filename(s) and exit
            if (!options.NewWindow && startupInfo.HasFiles)
            {
                try {
                    StringBuilder builder = new StringBuilder();
                    foreach (var file in startupInfo.RequestedFileList)
                    {
                        builder.AppendFormat("{0};{1};{2}\n", file.FileName, file.Line, file.Column);
                    }
                    listen_socket.Connect(ep);
                    listen_socket.Send(Encoding.UTF8.GetBytes(builder.ToString()));
                    return(0);
                } catch {
                    // Reset the socket
                    if (null != socket_filename && File.Exists(socket_filename))
                    {
                        File.Delete(socket_filename);
                    }
                }
            }

            Counters.Initialization.Trace("Checking System");

            CheckFileWatcher();

            Exception error            = null;
            int       reportedFailures = 0;

            try {
                Counters.Initialization.Trace("Loading Icons");
                //force initialisation before the workbench so that it can register stock icons for GTK before they get requested
                ImageService.Initialize();
                LocalizationService.Initialize();

                // If we display an error dialog before the main workbench window on OS X then a second application menu is created
                // which is then replaced with a second empty Apple menu.
                // XBC #33699
                Counters.Initialization.Trace("Initializing IdeApp");
                IdeApp.Initialize(monitor);

                if (errorsList.Count > 0)
                {
                    using (AddinLoadErrorDialog dlg = new AddinLoadErrorDialog((AddinError[])errorsList.ToArray(typeof(AddinError)), false)) {
                        if (!dlg.Run())
                        {
                            return(1);
                        }
                    }
                    reportedFailures = errorsList.Count;
                }

                if (!CheckSCPlugin())
                {
                    return(1);
                }

                // Load requested files
                Counters.Initialization.Trace("Opening Files");

                // load previous combine
                RecentFile openedProject = null;
                if (IdeApp.Preferences.LoadPrevSolutionOnStartup && !startupInfo.HasSolutionFile && !IdeApp.Workspace.WorkspaceItemIsOpening && !IdeApp.Workspace.IsOpen)
                {
                    openedProject = DesktopService.RecentFiles.GetProjects().FirstOrDefault();
                    if (openedProject != null)
                    {
                        IdeApp.Workspace.OpenWorkspaceItem(openedProject.FileName).ContinueWith(t => IdeApp.OpenFiles(startupInfo.RequestedFileList), TaskScheduler.FromCurrentSynchronizationContext());
                    }
                }
                if (openedProject == null)
                {
                    IdeApp.OpenFiles(startupInfo.RequestedFileList);
                }

                monitor.Step(1);
            } catch (Exception e) {
                error = e;
            } finally {
                monitor.Dispose();
            }

            if (error != null)
            {
                string message = BrandingService.BrandApplicationName(GettextCatalog.GetString("MonoDevelop failed to start"));
                MessageService.ShowFatalError(message, null, error);
                return(1);
            }

            if (errorsList.Count > reportedFailures)
            {
                using (AddinLoadErrorDialog dlg = new AddinLoadErrorDialog((AddinError[])errorsList.ToArray(typeof(AddinError)), true))
                    dlg.Run();
            }

            errorsList = null;
            AddinManager.AddinLoadError -= OnAddinError;

            // FIXME: we should probably track the last 'selected' one
            // and do this more cleanly
            try {
                listen_socket.Bind(ep);
                listen_socket.Listen(5);
                listen_socket.BeginAccept(new AsyncCallback(ListenCallback), listen_socket);
            } catch {
                // Socket already in use
            }

            initialized = true;
            MessageService.RootWindow    = IdeApp.Workbench.RootWindow;
            Xwt.MessageDialog.RootWindow = Xwt.Toolkit.CurrentEngine.WrapWindow(IdeApp.Workbench.RootWindow);
            Thread.CurrentThread.Name    = "GUI Thread";
            Counters.Initialization.Trace("Running IdeApp");
            Counters.Initialization.EndTiming();

            AddinManager.AddExtensionNodeHandler("/MonoDevelop/Ide/InitCompleteHandlers", OnExtensionChanged);
            StartLockupTracker();
            IdeApp.Run();

            IdeApp.Customizer.OnIdeShutdown();

            // unloading services
            if (null != socket_filename)
            {
                File.Delete(socket_filename);
            }
            lockupCheckRunning = false;
            Runtime.Shutdown();

            IdeApp.Customizer.OnCoreShutdown();

            InstrumentationService.Stop();

            MonoDevelop.Components.GtkWorkarounds.Terminate();

            return(0);
        }
Example #10
0
		int Run (MonoDevelopOptions options)
		{
			LoggingService.LogInfo ("Starting {0} {1}", BrandingService.ApplicationLongName, IdeVersionInfo.MonoDevelopVersion);
			LoggingService.LogInfo ("Build Information{0}{1}", Environment.NewLine, SystemInformation.GetBuildInformation ());
			LoggingService.LogInfo ("Running on {0}", RuntimeVersionInfo.GetRuntimeInfo ());

			//ensure native libs initialized before we hit anything that p/invokes
			Platform.Initialize ();
			sectionTimings ["PlatformInitialization"] = startupSectionTimer.ElapsedMilliseconds;
			startupSectionTimer.Restart ();

			GettextCatalog.Initialize ();
			sectionTimings ["GettextInitialization"] = startupSectionTimer.ElapsedMilliseconds;
			startupSectionTimer.Restart ();

			LoggingService.LogInfo ("Operating System: {0}", SystemInformation.GetOperatingSystemDescription ());

			if (!Platform.IsWindows) {
				// The assembly resolver for MSBuild 15 assemblies needs to be defined early on.
				// Whilst Runtime.Initialize loads the MSBuild 15 assemblies from Mono this seems
				// to be too late to prevent the MEF composition and the static registrar from
				// failing to load the MonoDevelop.Ide assembly which now uses MSBuild 15 assemblies.
				ResolveMSBuildAssemblies ();
			}

			Counters.Initialization.BeginTiming ();

			if (options.PerfLog) {
				string logFile = Path.Combine (Environment.CurrentDirectory, "monodevelop.perf-log");
				LoggingService.LogInfo ("Logging instrumentation service data to file: " + logFile);
				InstrumentationService.StartAutoSave (logFile, 1000);
			}

			Counters.Initialization.Trace ("Initializing GTK");
			if (Platform.IsWindows && !CheckWindowsGtk ())
				return 1;
			SetupExceptionManager ();

			// explicit GLib type system initialization for GLib < 2.36 before any other type system access
			GLib.GType.Init ();

			IdeApp.Customizer = options.IdeCustomizer ?? new IdeCustomizer ();
			try {
				IdeApp.Customizer.Initialize ();
			} catch (UnauthorizedAccessException ua) {
				LoggingService.LogError ("Unauthorized access: " + ua.Message);
				return 1;
			}

			try {
				GLibLogging.Enabled = true;
			} catch (Exception ex) {
				LoggingService.LogError ("Error initialising GLib logging.", ex);
			}

			var args = options.RemainingArgs.ToArray ();
			IdeTheme.InitializeGtk (BrandingService.ApplicationName, ref args);

			sectionTimings["GtkInitialization"] = startupSectionTimer.ElapsedMilliseconds;
			startupSectionTimer.Restart ();
			LoggingService.LogInfo ("Using GTK+ {0}", IdeVersionInfo.GetGtkVersion ());

			// XWT initialization
			FilePath p = typeof(IdeStartup).Assembly.Location;
			Runtime.LoadAssemblyFrom (p.ParentDirectory.Combine("Xwt.Gtk.dll"));
			Xwt.Application.InitializeAsGuest (Xwt.ToolkitType.Gtk);
			Xwt.Toolkit.CurrentEngine.RegisterBackend<IExtendedTitleBarWindowBackend,GtkExtendedTitleBarWindowBackend> ();
			Xwt.Toolkit.CurrentEngine.RegisterBackend<IExtendedTitleBarDialogBackend,GtkExtendedTitleBarDialogBackend> ();
			IdeTheme.SetupXwtTheme ();

			sectionTimings["XwtInitialization"] = startupSectionTimer.ElapsedMilliseconds;
			startupSectionTimer.Restart ();

			//default to Windows IME on Windows
			if (Platform.IsWindows && GtkWorkarounds.GtkMinorVersion >= 16) {
				var settings = Gtk.Settings.Default;
				var val = GtkWorkarounds.GetProperty (settings, "gtk-im-module");
				if (string.IsNullOrEmpty (val.Val as string))
					GtkWorkarounds.SetProperty (settings, "gtk-im-module", new GLib.Value ("ime"));
			}
			
			string socket_filename = null;
			EndPoint ep = null;
			
			DispatchService.Initialize ();

			// Set a synchronization context for the main gtk thread
			SynchronizationContext.SetSynchronizationContext (DispatchService.SynchronizationContext);
			Runtime.MainSynchronizationContext = SynchronizationContext.Current;

			sectionTimings["DispatchInitialization"] = startupSectionTimer.ElapsedMilliseconds;
			startupSectionTimer.Restart ();

			// Initialize Roslyn's synchronization context
			RoslynServices.RoslynService.Initialize ();

			sectionTimings["RoslynInitialization"] = startupSectionTimer.ElapsedMilliseconds;
			startupSectionTimer.Restart ();

			AddinManager.AddinLoadError += OnAddinError;

			var startupInfo = new StartupInfo (args);

			// If a combine was specified, force --newwindow.

			if (!options.NewWindow && startupInfo.HasFiles) {
				Counters.Initialization.Trace ("Pre-Initializing Runtime to load files in existing window");
				Runtime.Initialize (true);
				foreach (var file in startupInfo.RequestedFileList) {
					if (MonoDevelop.Projects.Services.ProjectService.IsWorkspaceItemFile (file.FileName)) {
						options.NewWindow = true;
						break;
					}
				}
			}
			
			Counters.Initialization.Trace ("Initializing Runtime");
			Runtime.Initialize (true);

			sectionTimings ["RuntimeInitialization"] = startupSectionTimer.ElapsedMilliseconds;
			startupSectionTimer.Restart ();

			bool restartRequested = PropertyService.Get ("MonoDevelop.Core.RestartRequested", false);
			startupInfo.Restarted = restartRequested;
			PropertyService.Set ("MonoDevelop.Core.RestartRequested", false);

			IdeApp.Customizer.OnCoreInitialized ();

			Counters.Initialization.Trace ("Initializing theme");

			IdeTheme.SetupGtkTheme ();

			sectionTimings["ThemeInitialized"] = startupSectionTimer.ElapsedMilliseconds;
			startupSectionTimer.Restart ();

			ProgressMonitor monitor = new MonoDevelop.Core.ProgressMonitoring.ConsoleProgressMonitor ();
			
			monitor.BeginTask (GettextCatalog.GetString ("Starting {0}", BrandingService.ApplicationName), 2);

			//make sure that the platform service is initialised so that the Mac platform can subscribe to open-document events
			Counters.Initialization.Trace ("Initializing Platform Service");
			DesktopService.Initialize ();

			sectionTimings["PlatformInitialization"] = startupSectionTimer.ElapsedMilliseconds;
			startupSectionTimer.Restart ();

			monitor.Step (1);

			if (options.IpcTcp) {
				listen_socket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
				ep = new IPEndPoint (IPAddress.Loopback, ipcBasePort + HashSdbmBounded (Environment.UserName));
			} else {
				socket_filename = "/tmp/md-" + Environment.GetEnvironmentVariable ("USER") + "-socket";
				listen_socket = new Socket (AddressFamily.Unix, SocketType.Stream, ProtocolType.IP);
				ep = new UnixEndPoint (socket_filename);
			}
				
			// If not opening a combine, connect to existing monodevelop and pass filename(s) and exit
			if (!options.NewWindow && startupInfo.HasFiles) {
				try {
					StringBuilder builder = new StringBuilder ();
					foreach (var file in startupInfo.RequestedFileList) {
						builder.AppendFormat ("{0};{1};{2}\n", file.FileName, file.Line, file.Column);
					}
					listen_socket.Connect (ep);
					listen_socket.Send (Encoding.UTF8.GetBytes (builder.ToString ()));
					return 0;
				} catch {
					// Reset the socket
					if (null != socket_filename && File.Exists (socket_filename))
						File.Delete (socket_filename);
				}
			}
			
			Counters.Initialization.Trace ("Checking System");

			CheckFileWatcher ();

			sectionTimings["FileWatcherInitialization"] = startupSectionTimer.ElapsedMilliseconds;
			startupSectionTimer.Restart ();

			Exception error = null;
			int reportedFailures = 0;

			try {
				Counters.Initialization.Trace ("Loading Icons");
				//force initialisation before the workbench so that it can register stock icons for GTK before they get requested
				ImageService.Initialize ();

				sectionTimings ["ImageInitialization"] = startupSectionTimer.ElapsedMilliseconds;
				startupSectionTimer.Restart ();

				// If we display an error dialog before the main workbench window on OS X then a second application menu is created
				// which is then replaced with a second empty Apple menu.
				// XBC #33699
				Counters.Initialization.Trace ("Initializing IdeApp");

				hideWelcomePage = startupInfo.HasFiles;
				IdeApp.Initialize (monitor, hideWelcomePage);
				sectionTimings ["AppInitialization"] = startupSectionTimer.ElapsedMilliseconds;
				startupSectionTimer.Restart ();

				if (errorsList.Count > 0) {
					using (AddinLoadErrorDialog dlg = new AddinLoadErrorDialog (errorsList.ToArray (), false)) {
						if (!dlg.Run ())
							return 1;
					}
					reportedFailures = errorsList.Count;
				}

				if (!CheckSCPlugin ())
					return 1;

				// Load requested files
				Counters.Initialization.Trace ("Opening Files");

				// load previous combine
				RecentFile openedProject = null;
				if (IdeApp.Preferences.LoadPrevSolutionOnStartup && !startupInfo.HasSolutionFile && !IdeApp.Workspace.WorkspaceItemIsOpening && !IdeApp.Workspace.IsOpen) {
					openedProject = DesktopService.RecentFiles.MostRecentlyUsedProject;
					if (openedProject != null) {
						var metadata = GetOpenWorkspaceOnStartupMetadata ();
						IdeApp.Workspace.OpenWorkspaceItem (openedProject.FileName, true, true, metadata).ContinueWith (t => IdeApp.OpenFiles (startupInfo.RequestedFileList, metadata), TaskScheduler.FromCurrentSynchronizationContext ());
						startupInfo.OpenedRecentProject = true;
					}
				}
				if (openedProject == null) {
					IdeApp.OpenFiles (startupInfo.RequestedFileList, GetOpenWorkspaceOnStartupMetadata ());
					startupInfo.OpenedFiles = startupInfo.HasFiles;
				}
				
				monitor.Step (1);
			
			} catch (Exception e) {
				error = e;
			} finally {
				monitor.Dispose ();
			}
			
			if (error != null) {
				string message = BrandingService.BrandApplicationName (GettextCatalog.GetString ("MonoDevelop failed to start"));
				message = message + "\n\n" + error.Message;
				MessageService.ShowFatalError (message, null, error);

				return 1;
			}

			if (errorsList.Count > reportedFailures) {
				using (AddinLoadErrorDialog dlg = new AddinLoadErrorDialog (errorsList.ToArray (), true))
					dlg.Run ();
			}
			
			errorsList = null;
			AddinManager.AddinLoadError -= OnAddinError;

			sectionTimings["BasicInitializationCompleted"] = startupSectionTimer.ElapsedMilliseconds;
			startupSectionTimer.Restart ();

			// FIXME: we should probably track the last 'selected' one
			// and do this more cleanly
			try {
				listen_socket.Bind (ep);
				listen_socket.Listen (5);
				listen_socket.BeginAccept (new AsyncCallback (ListenCallback), listen_socket);
			} catch {
				// Socket already in use
			}

			sectionTimings["SocketInitialization"] = startupSectionTimer.ElapsedMilliseconds;
			startupSectionTimer.Restart ();

			initialized = true;
			MessageService.RootWindow = IdeApp.Workbench.RootWindow;
			Xwt.MessageDialog.RootWindow = Xwt.Toolkit.CurrentEngine.WrapWindow (IdeApp.Workbench.RootWindow);

			sectionTimings["WindowOpened"] = startupSectionTimer.ElapsedMilliseconds;
			startupSectionTimer.Restart ();

			Thread.CurrentThread.Name = "GUI Thread";
			Counters.Initialization.Trace ("Running IdeApp");
			Counters.Initialization.EndTiming ();
				
			AddinManager.AddExtensionNodeHandler("/MonoDevelop/Ide/InitCompleteHandlers", OnExtensionChanged);
			StartLockupTracker ();

			// This call is important so the current event loop is run before we run the main loop.
			// On Mac, the OpenDocuments event gets handled here, so we need to get the timeout
			// it queues before the OnIdle event so we can start opening a solution before
			// we show the main window.
			DispatchService.RunPendingEvents ();

			sectionTimings ["PumpEventLoop"] = startupSectionTimer.ElapsedMilliseconds;
			startupTimer.Stop ();
			startupSectionTimer.Stop ();

			// Need to start this timer because we don't know yet if we've been asked to open a solution from the file manager.
			timeToCodeTimer.Start ();
			ttcMetadata = new TimeToCodeMetadata {
				StartupTime = startupTimer.ElapsedMilliseconds
			};

			// Start this timer to limit the time to decide if the app was opened by a file manager
			IdeApp.StartFMOpenTimer (FMOpenTimerExpired);
			IdeApp.Workspace.FirstWorkspaceItemOpened += CompleteSolutionTimeToCode;
			IdeApp.Workbench.DocumentOpened += CompleteFileTimeToCode;

			CreateStartupMetadata (startupInfo, sectionTimings);

			GLib.Idle.Add (OnIdle);
			IdeApp.Run ();

			IdeApp.Customizer.OnIdeShutdown ();
			
			// unloading services
			if (null != socket_filename)
				File.Delete (socket_filename);
			lockupCheckRunning = false;
			Runtime.Shutdown ();

			IdeApp.Customizer.OnCoreShutdown ();

			InstrumentationService.Stop ();

			MonoDevelop.Components.GtkWorkarounds.Terminate ();
			
			return 0;
		}