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; }