Index: Application/Riskeer/src/Application.Riskeer/App.xaml.cs =================================================================== diff -u -rb95e081a1d550f0a651010558cd3b9484dbcf113 -r18039f491c06f9a65491a1fef17d84aa1b1d3f07 --- Application/Riskeer/src/Application.Riskeer/App.xaml.cs (.../App.xaml.cs) (revision b95e081a1d550f0a651010558cd3b9484dbcf113) +++ Application/Riskeer/src/Application.Riskeer/App.xaml.cs (.../App.xaml.cs) (revision 18039f491c06f9a65491a1fef17d84aa1b1d3f07) @@ -199,10 +199,7 @@ fileToOpen = potentialPath; return true; } - catch (ArgumentException) - { - return false; - } + catch (ArgumentException) {} } return false; @@ -236,14 +233,17 @@ try { - if (!AcquireSingleInstancePerUserMutex()) + if (!Debugger.IsAttached) { - MessageBox.Show(CoreCommonGuiResources.App_ShutdownIfNotFirstInstance_Cannot_start_multiple_instances_of_Riskeer_Please_close_the_other_instance_first); - Shutdown(1); - return true; //done here - } + if (!AcquireSingleInstancePerUserMutex()) + { + MessageBox.Show(CoreCommonGuiResources.App_ShutdownIfNotFirstInstance_Cannot_start_multiple_instances_of_Riskeer_Please_close_the_other_instance_first); + Shutdown(1); + return true; //done here + } - hasMutex = true; + hasMutex = true; + } } finally { @@ -281,12 +281,23 @@ private static bool AcquireSingleInstancePerUserMutex() { - bool createdNew; + var createdNew = false; + try + { + //include the user name in the (global) mutex to ensure we limit only the number of instances per + //user, not per system (essential on for example Citrix systems). - // Include the user name in the (global) mutex to ensure we limit only the number of instances per - // user, not per system (essential on for example Citrix systems). - singleInstanceMutex = new Mutex(true, $"Riskeer-single-instance-mutex-{Environment.UserName}", out createdNew); + //include the application name in the mutex to ensure we are allowed to start for example 'Sobek' + //and 'Morphan' side by side. + string applicationName = ConfigurationManager.AppSettings.AllKeys.Contains("applicationName") + ? ConfigurationManager.AppSettings["applicationName"] + : string.Empty; + string mutexName = $"Riskeer-single-instance-mutex-{Environment.UserName}-{applicationName}"; + singleInstanceMutex = new Mutex(true, mutexName, out createdNew); + } + catch (AbandonedMutexException) {} //might throw an abandoned mutex exception if the previous DS instance forcefully exited. + return createdNew; } Index: Core/Common/src/Core.Common.Base/Geometry/Math2D.cs =================================================================== diff -u -r16b0b53af7f16d085e51f880d6d09225be267916 -r18039f491c06f9a65491a1fef17d84aa1b1d3f07 --- Core/Common/src/Core.Common.Base/Geometry/Math2D.cs (.../Math2D.cs) (revision 16b0b53af7f16d085e51f880d6d09225be267916) +++ Core/Common/src/Core.Common.Base/Geometry/Math2D.cs (.../Math2D.cs) (revision 18039f491c06f9a65491a1fef17d84aa1b1d3f07) @@ -470,9 +470,11 @@ : Segment2DIntersectSegment2DResult.CreateNoIntersectResult(); } - return IsPointInCollinearSegment(segment1.FirstPoint, segment2) - ? Segment2DIntersectSegment2DResult.CreateIntersectionResult(segment1.FirstPoint) - : Segment2DIntersectSegment2DResult.CreateNoIntersectResult(); + { + return IsPointInCollinearSegment(segment1.FirstPoint, segment2) + ? Segment2DIntersectSegment2DResult.CreateIntersectionResult(segment1.FirstPoint) + : Segment2DIntersectSegment2DResult.CreateNoIntersectResult(); + } } return IsPointInCollinearSegment(segment2.FirstPoint, segment1) Index: Core/Common/src/Core.Common.Controls.TreeView/TreeViewControl.cs =================================================================== diff -u -r22f739a06f914021000e3167894efa0145da5bed -r18039f491c06f9a65491a1fef17d84aa1b1d3f07 --- Core/Common/src/Core.Common.Controls.TreeView/TreeViewControl.cs (.../TreeViewControl.cs) (revision 22f739a06f914021000e3167894efa0145da5bed) +++ Core/Common/src/Core.Common.Controls.TreeView/TreeViewControl.cs (.../TreeViewControl.cs) (revision 18039f491c06f9a65491a1fef17d84aa1b1d3f07) @@ -93,7 +93,7 @@ public event EventHandler DataDoubleClick; public event EventHandler SelectedDataChanged; - public event EventHandler> DataDeleted; + public event EventHandler> DataDeleted; // TODO; Way to explicit! /// /// Creates a new instance of . Index: Core/Common/src/Core.Common.Gui/Converters/KeyValueExpandableArrayConverter.cs =================================================================== diff -u -r70a85081f14d88ed379599379c0bbb95f1b7489f -r18039f491c06f9a65491a1fef17d84aa1b1d3f07 --- Core/Common/src/Core.Common.Gui/Converters/KeyValueExpandableArrayConverter.cs (.../KeyValueExpandableArrayConverter.cs) (revision 70a85081f14d88ed379599379c0bbb95f1b7489f) +++ Core/Common/src/Core.Common.Gui/Converters/KeyValueExpandableArrayConverter.cs (.../KeyValueExpandableArrayConverter.cs) (revision 18039f491c06f9a65491a1fef17d84aa1b1d3f07) @@ -82,7 +82,7 @@ /// private class ArrayPropertyDescriptor : SimplePropertyDescriptor { - private readonly object propertyValue; + private readonly object value; /// /// Creates a new instance of . @@ -93,7 +93,7 @@ public ArrayPropertyDescriptor(Type elementType, string name, object value) : base(elementType, name, value.GetType()) { - propertyValue = value; + this.value = value; } public override bool IsReadOnly @@ -106,10 +106,10 @@ public override object GetValue(object component) { - return propertyValue; + return value; } - public override void SetValue(object component, object value) + public override void SetValue(object component, object valueToSet) { throw new NotSupportedException(); }