Exemple #1
0
        private static void LaunchFlexBridge(IIPCHost host, string command, string args, Action onNonBlockerCommandComplete,
                                             ref bool changesReceived, ref string projectName)
        {
            string flexbridgeLauncher = FullFieldWorksBridgePath();

            if (MiscUtils.IsUnix)
            {
                flexbridgeLauncher = FwDirectoryFinder.FlexBridgeFolder + "/flexbridge";
            }
            if (!File.Exists(flexbridgeLauncher))
            {
                Console.WriteLine("Warning: Attempting to use non-existent flexbridge launcher {0}", flexbridgeLauncher);
            }

            // Launch the bridge process.
            using (Process.Start(flexbridgeLauncher, args))
            {
            }

            var nonFlexblockers = new HashSet <string>
            {
                ConflictViewer,
                LiftConflictViewer,
                AboutFLExBridge,
                CheckForUpdates
            };

            if (nonFlexblockers.Contains(command))
            {
                // This skips the piping and doesn't pause the Flex UI thread for the
                // two 'view' options and for the 'About Flex Bridge' and 'Check for Updates'.
                // We store the host and a callback so that, when FLExBridge quits, we can kill the host and call the callback.
                _noBlockerHostAndCallback = new Tuple <IIPCHost, Action> (host, onNonBlockerCommandComplete);
            }
            else
            {
                // This uses all the piping and also blocks the Flex UI thread, while Flex Bridge is running.
                using (new WaitCursor())
                {
                    // Pause UI thread until FLEx Bridge terminates:
                    Monitor.Enter(_waitObject);
                    if (_flexBridgeTerminated == false)
                    {
                        Monitor.Wait(_waitObject, -1);
                    }
                    Monitor.Exit(_waitObject);

                    projectName     = _projectName;
                    changesReceived = _receivedChanges;
                }
                KillTheHost(host);
            }
        }
        private bool _runStandAlone;         // debug mode, run with message boxes instead of connection to FLEx.
#endif
        /// <summary>
        /// Initialize the helper, setting up the local service endpoint and opening.
        /// </summary>
        /// <param name="commandLineArgs">The entire FieldWorks project folder path is in the '-p' option, if not 'obtain' operation.
        /// Must include the project folder and project name with "fwdata" extension.
        /// Empty is OK if not send_receive command.</param>
        public bool Init(Dictionary <string, string> commandLineArgs)
        {
#if DEBUG // this command line argument is only for debugging.
            if (commandLineArgs.ContainsKey("-runStandAlone"))
            {
                _runStandAlone = true;
                MessageBox.Show("connection opened");
                return(true);
            }
#else
            if (commandLineArgs.ContainsKey("-runStandAlone"))
            {
                throw new InvalidOperationException("The '-runStandAlone' command line option is not supported in a Release build.");
            }
#endif

            HostOpened = true;

            // The pipeID as set by FLEx to be used in setting the communication channels
            var pipeId = commandLineArgs["-pipeID"];

            _host = IPCHostFactory.Create();
            _host.VerbosityLevel = 1;
            var hostIsInitialized = _host.Initialize <FLExService, IFLExService>("FLExEndpoint" + pipeId, null, null);
            if (!hostIsInitialized)
            {
                HostOpened = false;
                // display messagebox and quit
                MessageBox.Show(CommonResources.kAlreadyRunning, CommonResources.kFLExBridge, MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                return(false);
            }
            //open host ready for business

            _client = IPCClientFactory.Create();
            _client.VerbosityLevel = 1;
            _client.Initialize <IFLExBridgeService>("FLExBridgeEndpoint" + pipeId, FLExService.WaitObject, null);
            if (!_client.RemoteCall("BridgeReady"))
            {
                _client = null;                 //FLEx isn't listening.
            }
            return(true);
        }
		private bool _runStandAlone; // debug mode, run with message boxes instead of connection to FLEx.
#endif
		/// <summary>
		/// Initialize the helper, setting up the local service endpoint and opening.
		/// </summary>
		/// <param name="commandLineArgs">The entire FieldWorks project folder path is in the '-p' option, if not 'obtain' operation.
		/// Must include the project folder and project name with "fwdata" extension.
		/// Empty is OK if not send_receive command.</param>
		public bool Init(Dictionary<string, string> commandLineArgs)
		{
#if DEBUG // this command line argument is only for debugging.
			if (commandLineArgs.ContainsKey("-runStandAlone"))
			{
				_runStandAlone = true;
				MessageBox.Show ("connection opened");
				return true;
			}
#else
			if (commandLineArgs.ContainsKey("-runStandAlone"))
			{
				throw new InvalidOperationException("The '-runStandAlone' command line option is not supported in a Release build.");
			}
#endif

			HostOpened = true;

			// The pipeID as set by FLEx to be used in setting the communication channels
			var pipeId = commandLineArgs["-pipeID"];

			_host = IPCHostFactory.Create();
			_host.VerbosityLevel = 1;
			var hostIsInitialized = _host.Initialize<FLExService, IFLExService>("FLExEndpoint" + pipeId, null, null);
			if (!hostIsInitialized)
			{
				HostOpened = false;
				// display messagebox and quit
				MessageBox.Show(CommonResources.kAlreadyRunning, CommonResources.kFLExBridge, MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
				return false;
			}
			//open host ready for business

			_client = IPCClientFactory.Create();
			_client.VerbosityLevel = 1;
			_client.Initialize<IFLExBridgeService>("FLExBridgeEndpoint" + pipeId, FLExService.WaitObject, null);
			if (!_client.RemoteCall("BridgeReady"))
				_client = null;	//FLEx isn't listening.
			return true;
		}
        private static void KillTheHost(IIPCHost host)
        {
            // Let the service host cleanup happen in another thread so the user can get on with life.
            var letTheHostDie = new Thread(() =>
            {
                try
                {
                    host.Close();
                    var disposableHost = host as IDisposable;
                    if (disposableHost != null)
                    {
                        disposableHost.Dispose();
                    }
                }
                catch (Exception)
                {
                    //we don't care anymore, just die.
                }
            });

            letTheHostDie.Start();
        }
        /// <summary>
        /// Executes in two distinct scenarios.
        ///
        /// 1. If disposing is true, the method has been called directly
        /// or indirectly by a user's code via the Dispose method.
        /// Both managed and unmanaged resources can be disposed.
        ///
        /// 2. If disposing is false, the method has been called by the
        /// runtime from inside the finalizer and you should not reference (access)
        /// other managed objects, as they already have been garbage collected.
        /// Only unmanaged resources can be disposed.
        /// </summary>
        /// <remarks>
        /// If any exceptions are thrown, that is fine.
        /// If the method is being done in a finalizer, it will be ignored.
        /// If it is thrown by client code calling Dispose,
        /// it needs to be handled by fixing the issue.
        /// </remarks>
        private void Dispose(bool disposing)
        {
            if (IsDisposed)
            {
                return;
            }

            if (disposing)
            {
                if (HostOpened)
                {
                    _host.Close();
                    _host      = null;
                    HostOpened = false;
                }
                if (_client != null)
                {
                    _client.Close();
                    _client = null;
                }
            }

            IsDisposed = true;
        }
		static void CleanupHost()
		{
			Console.WriteLine(@"FLExBridgeHelper.CleanupHost()");
			if (_noBlockerHost != null)
			{
				KillTheHost(_noBlockerHost);
				_noBlockerHost = null;
			}
		}
		private static void KillTheHost(IIPCHost host)
		{
			// Let the service host cleanup happen in another thread so the user can get on with life.
			var letTheHostDie = new Thread(() =>
				{
					try
					{
						host.Close();
						((IDisposable)host).Dispose();
					}
					catch(Exception)
					{
						//we don't care anymore, just die.
					}
				});
			letTheHostDie.Start();
		}
		private static void LaunchFlexBridge(IIPCHost host, string command, string args, ref bool changesReceived, ref string projectName)
		{
			// Launch the bridge process.
			using (Process.Start(FullFieldWorksBridgePath(), args))
			{
			}

			var nonFlexblockers = new HashSet<string>
				{
					ConflictViewer,
					LiftConflictViewer,
					AboutFLExBridge,
					CheckForUpdates
				};
			if (nonFlexblockers.Contains(command))
			{
				// This skips the piping and doesn't pause the Flex UI thread for the
				// two 'view' options and for the 'About Flex Bridge' and 'Check for Updates'.
				_noBlockerHost = host; // so we can kill the host when the bridge quits
			}
			else
			{
				// This uses all the piping and also blocks the Flex UI thread, while Flex Bridge is running.
				Cursor.Current = Cursors.WaitCursor;

				// Pause UI thread until FLEx Bridge terminates:
				Monitor.Enter(_waitObject);
				if (_flexBridgeTerminated == false)
					Monitor.Wait(_waitObject, -1);
				Monitor.Exit(_waitObject);

				projectName = _projectName;
				changesReceived = _receivedChanges;
				Cursor.Current = Cursors.Default;
				KillTheHost(host);
			}
		}
		private static void LaunchFlexBridge(IIPCHost host, string command, string args, Action onNonBlockerCommandComplete,
			ref bool changesReceived, ref string projectName)
		{
			// Launch the bridge process.
			using (Process.Start(FullFieldWorksBridgePath(), args))
			{
			}

			var nonFlexblockers = new HashSet<string>
				{
					ConflictViewer,
					LiftConflictViewer,
					AboutFLExBridge,
					CheckForUpdates
				};
			if (nonFlexblockers.Contains(command))
			{
				// This skips the piping and doesn't pause the Flex UI thread for the
				// two 'view' options and for the 'About Flex Bridge' and 'Check for Updates'.
				// We store the host and a callback so that, when FLExBridge quits, we can kill the host and call the callback.
				_noBlockerHostAndCallback = new Tuple<IIPCHost, Action> (host, onNonBlockerCommandComplete);
			}
			else
			{
				// This uses all the piping and also blocks the Flex UI thread, while Flex Bridge is running.
				using (new WaitCursor())
				{
					// Pause UI thread until FLEx Bridge terminates:
					Monitor.Enter(_waitObject);
					if (_flexBridgeTerminated == false)
						Monitor.Wait(_waitObject, -1);
					Monitor.Exit(_waitObject);

					projectName = _projectName;
					changesReceived = _receivedChanges;
				}
				KillTheHost(host);
			}
		}
		/// <summary>
		/// Executes in two distinct scenarios.
		///
		/// 1. If disposing is true, the method has been called directly
		/// or indirectly by a user's code via the Dispose method.
		/// Both managed and unmanaged resources can be disposed.
		///
		/// 2. If disposing is false, the method has been called by the
		/// runtime from inside the finalizer and you should not reference (access)
		/// other managed objects, as they already have been garbage collected.
		/// Only unmanaged resources can be disposed.
		/// </summary>
		/// <remarks>
		/// If any exceptions are thrown, that is fine.
		/// If the method is being done in a finalizer, it will be ignored.
		/// If it is thrown by client code calling Dispose,
		/// it needs to be handled by fixing the issue.
		/// </remarks>
		private void Dispose(bool disposing)
		{
			if (IsDisposed)
				return;

			if (disposing)
			{
				if (HostOpened)
				{
					_host.Close();
					_host = null;
					HostOpened = false;
				}
				if (_client != null)
				{
					_client.Close();
					_client = null;
				}
			}

			IsDisposed = true;
		}