diff --git a/src/DynamoApplications/StartupUtils.cs b/src/DynamoApplications/StartupUtils.cs index ffcd88c9c9a..1dea5b0a117 100644 --- a/src/DynamoApplications/StartupUtils.cs +++ b/src/DynamoApplications/StartupUtils.cs @@ -20,6 +20,12 @@ namespace Dynamo.Applications { public class StartupUtils { + //TODO internal? + /// + /// Raised when loading of the ASM binaries fails. A failure message is passed as a parameter. + /// + public static event Action ASMPreloadFailure; + internal class SandboxLookUp : DynamoLookUp { public override IEnumerable GetDynamoInstallLocations() @@ -178,7 +184,14 @@ public static DynamoModel MakeModel(bool CLImode) { var geometryFactoryPath = string.Empty; var preloaderLocation = string.Empty; - PreloadShapeManager(ref geometryFactoryPath, ref preloaderLocation); + try + { + PreloadShapeManager(ref geometryFactoryPath, ref preloaderLocation); + } + catch(Exception e) + { + ASMPreloadFailure?.Invoke(e.Message); + } var config = new DynamoModel.DefaultStartConfiguration() { diff --git a/src/DynamoSandbox/DynamoCoreSetup.cs b/src/DynamoSandbox/DynamoCoreSetup.cs index f342df57be5..2a89806a9fa 100644 --- a/src/DynamoSandbox/DynamoCoreSetup.cs +++ b/src/DynamoSandbox/DynamoCoreSetup.cs @@ -10,6 +10,8 @@ using Dynamo.Models; using Dynamo.ViewModels; using Dynamo.Wpf.ViewModels.Watch3D; +using System.Linq; +using Dynamo.DynamoSandbox.Properties; namespace DynamoSandbox { @@ -19,6 +21,7 @@ class DynamoCoreSetup private DynamoViewModel viewModel = null; private string commandFilePath; private Stopwatch startupTimer = Stopwatch.StartNew(); + private const string sandboxWikiPage = @"https://github.com/DynamoDS/Dynamo/wiki/How-to-Utilize-Dynamo-Builds"; [DllImport("msvcrt.dll")] public static extern int _putenv(string env); @@ -36,9 +39,8 @@ public void RunApplication(Application app) try { DynamoModel.RequestMigrationStatusDialog += MigrationStatusDialogRequested; - var model = Dynamo.Applications.StartupUtils.MakeModel(false); - + Dynamo.Applications.StartupUtils.ASMPreloadFailure += ASMPreloadFailureHandler; viewModel = DynamoViewModel.Start( new DynamoViewModel.StartConfiguration() { @@ -58,6 +60,7 @@ public void RunApplication(Application app) app.Run(view); DynamoModel.RequestMigrationStatusDialog -= MigrationStatusDialogRequested; + Dynamo.Applications.StartupUtils.ASMPreloadFailure -= ASMPreloadFailureHandler; } @@ -85,9 +88,26 @@ public void RunApplication(Application app) // Give user a chance to save (but does not allow cancellation) viewModel.Exit(allowCancel: false); } + else + { + //show a message dialog box with the exception so the user + //can effectively report the issue. + var shortStackTrace = String.Join(Environment.NewLine,e.StackTrace.Split(Environment.NewLine.ToCharArray()).Take(10)); + + var result = MessageBox.Show($"{Resources.SandboxCrashMessage} {Environment.NewLine} {e.Message}" + + $" {Environment.NewLine} {e.InnerException?.Message} {Environment.NewLine} {shortStackTrace} {Environment.NewLine} " + + Environment.NewLine + string.Format(Resources.SandboxBuildsPageDialogMessage, sandboxWikiPage), + + "DynamoSandbox", + MessageBoxButton.YesNo,MessageBoxImage.Error); + + if(result == MessageBoxResult.Yes) + { + System.Diagnostics.Process.Start(sandboxWikiPage); + } + } } - catch - { + catch { } Debug.WriteLine(e.Message); @@ -95,6 +115,11 @@ public void RunApplication(Application app) } } + private void ASMPreloadFailureHandler(string failureMessage) + { + MessageBox.Show(failureMessage, "DynamoSandbox", MessageBoxButton.OK, MessageBoxImage.Warning); + } + void OnDynamoViewLoaded(object sender, RoutedEventArgs e) { CloseMigrationWindow(); diff --git a/src/DynamoSandbox/Properties/Resources.Designer.cs b/src/DynamoSandbox/Properties/Resources.Designer.cs index 518ea7d85b8..8b51295f285 100644 --- a/src/DynamoSandbox/Properties/Resources.Designer.cs +++ b/src/DynamoSandbox/Properties/Resources.Designer.cs @@ -8,10 +8,10 @@ // //------------------------------------------------------------------------------ -namespace Dynamo.DynamoSandbox.Properties -{ - - +namespace Dynamo.DynamoSandbox.Properties { + using System; + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -60,6 +60,24 @@ internal Resources() { } } + /// + /// Looks up a localized string similar to Goto the Dynamo builds wiki site({0}) for more information.. + /// + internal static string SandboxBuildsPageDialogMessage { + get { + return ResourceManager.GetString("SandboxBuildsPageDialogMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Could not start DynamoSandbox, unhandled exception.. + /// + internal static string SandboxCrashMessage { + get { + return ResourceManager.GetString("SandboxCrashMessage", resourceCulture); + } + } + /// /// Looks up a localized string similar to Migrating Settings .... /// diff --git a/src/DynamoSandbox/Properties/Resources.en-US.resx b/src/DynamoSandbox/Properties/Resources.en-US.resx index cbe1c8587df..128a8cd7da8 100644 --- a/src/DynamoSandbox/Properties/Resources.en-US.resx +++ b/src/DynamoSandbox/Properties/Resources.en-US.resx @@ -117,6 +117,13 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Goto the Dynamo builds wiki site({0}) for more information. + message directing user to wiki page + + + Could not start DynamoSandbox, unhandled exception. + Migrating Settings ... Settings migration dialog message prompt diff --git a/src/DynamoSandbox/Properties/Resources.resx b/src/DynamoSandbox/Properties/Resources.resx index cbe1c8587df..128a8cd7da8 100644 --- a/src/DynamoSandbox/Properties/Resources.resx +++ b/src/DynamoSandbox/Properties/Resources.resx @@ -117,6 +117,13 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Goto the Dynamo builds wiki site({0}) for more information. + message directing user to wiki page + + + Could not start DynamoSandbox, unhandled exception. + Migrating Settings ... Settings migration dialog message prompt diff --git a/src/Tools/DynamoShapeManager/Utilities.cs b/src/Tools/DynamoShapeManager/Utilities.cs index d10733ce465..d6cff713508 100644 --- a/src/Tools/DynamoShapeManager/Utilities.cs +++ b/src/Tools/DynamoShapeManager/Utilities.cs @@ -29,7 +29,7 @@ public static class Utilities /// /// The mask to filter ASM binary /// - public static readonly string ASMFileMask = "ASMAHL*.dll"; + public static readonly string ASMFileMask = "ASMAHL*A.dll"; #endregion @@ -147,6 +147,7 @@ public static Version GetInstalledAsmVersion2(IEnumerable versions, ref getASMInstallsFunc = getASMInstallsFunc ?? GetAsmInstallations; var installations = getASMInstallsFunc(rootFolder); + // first find the exact match or the lowest matching within same major version foreach (var version in versions) { @@ -286,11 +287,11 @@ public static void PreloadAsmFromPath(string preloaderLocation, string asmLocati if (string.IsNullOrEmpty(preloaderLocationToLoad)) { - throw new ArgumentException("Invalid LibG preloader location for ASM at " + asmLocation); + throw new ArgumentException($"Invalid LibG preloader location {preloaderLocation} for ASM at {asmLocation}"); } if (string.IsNullOrEmpty(asmLocation) || !Directory.Exists(asmLocation)) { - throw new ArgumentException("Invalid ASM location " + asmLocation); + throw new ArgumentException($"Invalid ASM location { asmLocation }"); } var preloaderPath = Path.Combine(preloaderLocationToLoad, PreloaderAssembly); @@ -308,10 +309,18 @@ public static void PreloadAsmFromPath(string preloaderLocation, string asmLocati throw new MissingMethodException( string.Format("Method '{0}' not found", PreloaderMethodName)); } - - var methodParams = new object[] { asmLocation }; - preloadMethod.Invoke(null, methodParams); - + try + { + var methodParams = new object[] { asmLocation }; + preloadMethod.Invoke(null, methodParams); + } + catch + { + //log for clients like CLI. + var message = $"Could not load geometry library binaries from : {asmLocation}"; + Console.WriteLine(message); + throw new Exception(message); + } Debug.WriteLine("Successfully loaded ASM binaries"); } @@ -401,7 +410,7 @@ public static string GetGeometryFactoryPath2(string rootFolder, Version version) //lookup libG with a fallback to older versions which share the major version number. var libGFolder = Utilities.GetLibGPreloaderLocation(version, rootFolder); - + if (!Directory.Exists(libGFolder)) { // LibG_version folder must be valid. @@ -418,8 +427,8 @@ public static string GetGeometryFactoryPath2(string rootFolder, Version version) return assemblyPath; } - - + + private static IEnumerable GetAsmInstallations(string rootFolder) { var assemblyPath = Path.Combine(Path.Combine(rootFolder, "DynamoInstallDetective.dll")); @@ -441,7 +450,19 @@ private static IEnumerable GetAsmInstallations(string rootFolder) var methodParams = new object[] { ProductsWithASM, ASMFileMask }; - return installationsMethod.Invoke(null, methodParams) as IEnumerable; + var installs = installationsMethod.Invoke(null, methodParams) as IEnumerable; + + //filter install locations missing tbb and tbbmalloc.dll + return installs.Cast>>().Where(install => + { + var files = Directory.EnumerateFiles(install.Key, "tbb*.dll").Select(x=>System.IO.Path.GetFileName(x)); + if (files.Contains("tbb.dll") && files.Contains("tbbmalloc.dll")) + { + return true; + } + return false; + + }); } } } diff --git a/test/DynamoCoreTests/libGPreloaderTests.cs b/test/DynamoCoreTests/libGPreloaderTests.cs index 30292b98caa..28201393edb 100644 --- a/test/DynamoCoreTests/libGPreloaderTests.cs +++ b/test/DynamoCoreTests/libGPreloaderTests.cs @@ -312,9 +312,13 @@ public void GetInstalledASMVersions2_FindsVersionedLibGFolders_WithRootFolderFal //create some var libG22440path = System.IO.Directory.CreateDirectory(Path.Combine(rootFolder, "LibG_224_4_0")); - File.WriteAllText(Path.Combine(libG22440path.FullName, "ASMAHL.dll"), "someText"); + File.WriteAllText(Path.Combine(libG22440path.FullName, "ASMAHL224A.dll"), "someText"); + File.WriteAllText(Path.Combine(libG22440path.FullName, "tbb.dll"), "someText"); + File.WriteAllText(Path.Combine(libG22440path.FullName, "tbbmalloc.dll"), "someText"); var libG22401path = System.IO.Directory.CreateDirectory(Path.Combine(rootFolder, "LibG_224_0_1")); - File.WriteAllText(Path.Combine(libG22401path.FullName, "ASMAHL.dll"), "someText"); + File.WriteAllText(Path.Combine(libG22401path.FullName, "ASMAHL224A.dll"), "someText"); + File.WriteAllText(Path.Combine(libG22401path.FullName, "tbb.dll"), "someText"); + File.WriteAllText(Path.Combine(libG22401path.FullName, "tbbmalloc.dll"), "someText"); var foundVersion = DynamoShapeManager.Utilities.GetInstalledAsmVersion2(