diff --git a/src/DynamoCoreWpf/DynamoCoreWpf.csproj b/src/DynamoCoreWpf/DynamoCoreWpf.csproj
index b6ec89e35bf..1d7eb20da7b 100644
--- a/src/DynamoCoreWpf/DynamoCoreWpf.csproj
+++ b/src/DynamoCoreWpf/DynamoCoreWpf.csproj
@@ -569,6 +569,8 @@
Resources.resx
+
+
diff --git a/src/DynamoCoreWpf/PublicAPI.Unshipped.txt b/src/DynamoCoreWpf/PublicAPI.Unshipped.txt
index 7ad7160276a..7ba7618bd5e 100644
--- a/src/DynamoCoreWpf/PublicAPI.Unshipped.txt
+++ b/src/DynamoCoreWpf/PublicAPI.Unshipped.txt
@@ -1753,6 +1753,7 @@ Dynamo.UI.Views.SplashScreen.OnRequestDynamicSplashScreen() -> void
Dynamo.UI.Views.SplashScreen.OnRequestStaticSplashScreen() -> void
Dynamo.UI.Views.SplashScreen.RequestLaunchDynamo -> System.Action
Dynamo.UI.Views.SplashScreen.SplashScreen(bool enableSignInButton = true) -> void
+Dynamo.UI.Views.SplashScreen.SplashScreen(Dynamo.Wpf.UI.SplashScreenStartupContext context, bool enableSignInButton = true) -> void
Dynamo.UI.Views.SplashScreen.totalLoadingTime -> long
Dynamo.Utilities.MouseClickManager
Dynamo.Utilities.MouseClickManager.Click -> System.Windows.Input.MouseButtonEventHandler
@@ -3818,12 +3819,21 @@ Dynamo.Wpf.UI.GuidedTour.UpdateLibraryInteractionsEventHandler
Dynamo.Wpf.UI.GuidedTour.UpdatePopupLocationEventHandler
Dynamo.Wpf.UI.GuidedTour.Welcome
Dynamo.Wpf.UI.GuidedTour.Welcome.Welcome(Dynamo.Wpf.UI.GuidedTour.HostControlInfo host, double width, double height) -> void
+Dynamo.Wpf.UI.HostStartup
+static Dynamo.Wpf.UI.HostStartup.Current.get -> Dynamo.Wpf.UI.SplashScreenStartupContext
+static Dynamo.Wpf.UI.HostStartup.TryInitialize(Dynamo.Wpf.UI.SplashScreenStartupContext context) -> bool
+static Dynamo.Wpf.UI.HostStartup.Reset() -> void
+static Dynamo.Wpf.UI.HostStartup.GetUserDirectory() -> string
Dynamo.Wpf.UI.MouseBehaviour
Dynamo.Wpf.UI.MouseBehaviour.MouseBehaviour() -> void
Dynamo.Wpf.UI.MouseBehaviour.MouseX.get -> double
Dynamo.Wpf.UI.MouseBehaviour.MouseX.set -> void
Dynamo.Wpf.UI.MouseBehaviour.MouseY.get -> double
Dynamo.Wpf.UI.MouseBehaviour.MouseY.set -> void
+Dynamo.Wpf.UI.SplashScreenStartupContext
+Dynamo.Wpf.UI.SplashScreenStartupContext.SplashScreenStartupContext(Dynamo.Models.HostAnalyticsInfo? hostInfo, string userDataFolder) -> void
+Dynamo.Wpf.UI.SplashScreenStartupContext.HostInfo.get -> Dynamo.Models.HostAnalyticsInfo?
+Dynamo.Wpf.UI.SplashScreenStartupContext.UserDataFolder.get -> string
Dynamo.Wpf.UI.ToastManager
Dynamo.Wpf.UI.ToastManager.CloseRealTimeInfoWindow() -> void
Dynamo.Wpf.UI.ToastManager.CreateRealTimeInfoWindow(string content, bool stayOpen = false, string headerText = "", string hyperlinkText = "", System.Uri hyperlinkUri = null, System.Uri fileLinkUri = null) -> void
diff --git a/src/DynamoCoreWpf/UI/HostStartup.cs b/src/DynamoCoreWpf/UI/HostStartup.cs
new file mode 100644
index 00000000000..d32f5841df4
--- /dev/null
+++ b/src/DynamoCoreWpf/UI/HostStartup.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Threading;
+using Dynamo.Configuration;
+using Dynamo.Utilities;
+
+namespace Dynamo.Wpf.UI
+{
+ ///
+ /// Provides static methods and properties for initializing and managing the host startup context during application
+ /// launch.
+ ///
+ /// is intended for use during the application's splash screen or early
+ /// startup phase, before other core services are available. It allows initialization of a shared startup context
+ /// and provides access to user-specific directories based on the current host environment.
+ public static class HostStartup
+ {
+ private static int _initialized;
+ public static SplashScreenStartupContext? Current { get; private set; }
+
+ ///
+ /// Initialize the HostStartup with the provided context.
+ ///
+ ///
+ ///
+ public static bool TryInitialize(SplashScreenStartupContext context)
+ {
+ if (context == null) return false;
+ if (Interlocked.CompareExchange(ref _initialized, 1, 0) != 0) return false;
+ Current = context;
+ return true;
+ }
+
+ ///
+ /// Resets the static state of the class to its initial, uninitialized condition.
+ ///
+ /// Call this method to clear any existing state and reinitialize the class as if it had
+ /// not been used. This is typically used for testing scenarios or to force reinitialization. This method is
+ /// not thread-safe; ensure that no other threads are accessing the class while calling .
+ public static void Reset()
+ {
+ Current = null;
+ Interlocked.Exchange(ref _initialized, 0);
+ }
+
+ ///
+ /// Gets the path to the user-specific directory for the current application version.
+ ///
+ /// The returned directory path is versioned based on the application's major and minor
+ /// version numbers. If user-specific host information is available, the path is constructed using the host's
+ /// user data folder; otherwise, it defaults to a standard location under the user's application data
+ /// folder.
+ /// A string containing the full path to the user directory for the current application version. The directory
+ /// may not exist and may need to be created by the caller.
+ public static string GetUserDirectory()
+ {
+ // we need to use userDataFolder and hostAnalyticsInfo just in SplashScreen because PathManager/PathResolver are not created yet when SplashScreen is launched from a host
+ if (Current != null && !string.IsNullOrEmpty(Current.UserDataFolder) && Current.HostInfo != null)
+ {
+ var version = Current.HostInfo.Value.HostVersion;
+
+ return Path.Combine(Current.UserDataFolder,$"{version.Major}.{version.Minor}");
+ }
+ else
+ {
+ var version = AssemblyHelper.GetDynamoVersion();
+
+ var folder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
+ return Path.Combine(Path.Combine(folder, Configurations.DynamoAsString, "Dynamo Core"), $"{version.Major}.{version.Minor}");
+ }
+
+ }
+ }
+}
diff --git a/src/DynamoCoreWpf/UI/SplashScreenStartupContext.cs b/src/DynamoCoreWpf/UI/SplashScreenStartupContext.cs
new file mode 100644
index 00000000000..03a5ae4ceaf
--- /dev/null
+++ b/src/DynamoCoreWpf/UI/SplashScreenStartupContext.cs
@@ -0,0 +1,38 @@
+using Dynamo.Models;
+
+namespace Dynamo.Wpf.UI
+{
+ ///
+ /// Provides contextual information for initializing a splash screen during application startup, including host
+ /// analytics data and the user data folder path.
+ ///
+ /// This context is typically used to supply startup-related information to components that
+ /// display or manage a splash screen. It encapsulates optional host analytics details and the location of the
+ /// user-specific data directory.
+ public sealed class SplashScreenStartupContext
+ {
+ ///
+ /// Initializes a new instance of the class with the specified host
+ /// analytics information and user data folder path.
+ ///
+ /// Use this constructor to provide context information required during the splash screen
+ /// startup process, such as analytics data and the location for user-specific files.
+ /// The analytics information for the host application, or if not available.
+ /// The path to the user data folder. If , an empty string is used.
+ public SplashScreenStartupContext(HostAnalyticsInfo ?hostInfo, string userDataFolder)
+ {
+ HostInfo = hostInfo;
+ UserDataFolder = userDataFolder ?? string.Empty;
+ }
+
+ ///
+ /// Gets information about the host environment for analytics purposes.
+ ///
+ public HostAnalyticsInfo? HostInfo { get; }
+
+ ///
+ /// Gets the path to the user data folder.
+ ///
+ public string UserDataFolder { get; }
+ }
+}
diff --git a/src/DynamoCoreWpf/Views/HomePage/HomePage.xaml.cs b/src/DynamoCoreWpf/Views/HomePage/HomePage.xaml.cs
index 3c04457ab1c..c49bee0f4bf 100644
--- a/src/DynamoCoreWpf/Views/HomePage/HomePage.xaml.cs
+++ b/src/DynamoCoreWpf/Views/HomePage/HomePage.xaml.cs
@@ -15,6 +15,7 @@
using Dynamo.Models;
using Dynamo.UI.Controls;
using Dynamo.Utilities;
+using Dynamo.Wpf.UI;
using Dynamo.Wpf.UI.GuidedTour;
using Dynamo.Wpf.Utilities;
using DynamoUtilities;
@@ -137,11 +138,7 @@ private void DynamoViewModel_PropertyChanged(object sender, System.ComponentMode
///
private static string GetUserDirectory()
{
- var version = AssemblyHelper.GetDynamoVersion();
-
- var folder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
- return Path.Combine(Path.Combine(folder, "Dynamo", "Dynamo Core"),
- String.Format("{0}.{1}", version.Major, version.Minor));
+ return HostStartup.GetUserDirectory();
}
private async void UserControl_Loaded(object sender, System.Windows.RoutedEventArgs e)
diff --git a/src/DynamoCoreWpf/Views/PackageManager/Components/PackageManagerWizard/PackageManagerWizard.xaml.cs b/src/DynamoCoreWpf/Views/PackageManager/Components/PackageManagerWizard/PackageManagerWizard.xaml.cs
index d1bfe5fd012..70e7664e2b1 100644
--- a/src/DynamoCoreWpf/Views/PackageManager/Components/PackageManagerWizard/PackageManagerWizard.xaml.cs
+++ b/src/DynamoCoreWpf/Views/PackageManager/Components/PackageManagerWizard/PackageManagerWizard.xaml.cs
@@ -1,29 +1,30 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
+using System.Text.Json;
+using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
+using Autodesk.DesignScript.Runtime;
+using Dynamo.Models;
+using Dynamo.PackageManager;
+using Dynamo.PackageManager.UI;
using Dynamo.Utilities;
+using Dynamo.Wpf.UI;
using Dynamo.Wpf.Utilities;
using DynamoUtilities;
+using Greg.Requests;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.Wpf;
-using Autodesk.DesignScript.Runtime;
-using System.Text.Json;
-using System.Text.Json.Serialization;
-using Dynamo.PackageManager;
-using Dynamo.PackageManager.UI;
using Newtonsoft.Json;
-using JsonSerializer = System.Text.Json.JsonSerializer;
-using Greg.Requests;
using Newtonsoft.Json.Linq;
-using Dynamo.Models;
-using System.Globalization;
+using JsonSerializer = System.Text.Json.JsonSerializer;
namespace Dynamo.UI.Views
{
@@ -1007,11 +1008,7 @@ internal bool ProcessUri(string uri)
///
private static string GetUserDirectory()
{
- var version = AssemblyHelper.GetDynamoVersion();
-
- var folder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
- return Path.Combine(Path.Combine(folder, "Dynamo", "Dynamo Core"),
- String.Format("{0}.{1}", version.Major, version.Minor));
+ return HostStartup.GetUserDirectory();
}
///
diff --git a/src/DynamoCoreWpf/Views/SplashScreen/SplashScreen.xaml.cs b/src/DynamoCoreWpf/Views/SplashScreen/SplashScreen.xaml.cs
index 7b1b076fdcb..9f1bc59042f 100644
--- a/src/DynamoCoreWpf/Views/SplashScreen/SplashScreen.xaml.cs
+++ b/src/DynamoCoreWpf/Views/SplashScreen/SplashScreen.xaml.cs
@@ -10,11 +10,13 @@
using Dynamo.Configuration;
using Dynamo.Controls;
using Dynamo.Core;
+using Dynamo.Interfaces;
using Dynamo.Logging;
using Dynamo.Models;
using Dynamo.UI.Prompts;
using Dynamo.Utilities;
using Dynamo.ViewModels;
+using Dynamo.Wpf.UI;
using Dynamo.Wpf.Utilities;
using DynamoUtilities;
using Greg.AuthProviders;
@@ -150,6 +152,8 @@ public void OnRequestStaticSplashScreen()
StaticSplashScreenReady?.Invoke();
}
+ internal SplashScreenStartupContext StartupContext { get; }
+
///
/// Stores the value that indicates if the SignIn Button will be enabled(default) or not
///
@@ -182,6 +186,17 @@ public SplashScreen(bool enableSignInButton = true)
currentCloseMode = CloseMode.ByOther;
}
+ ///
+ /// Overloaded Splash Screen Constructor to receive SplashScreenStartupContext information
+ ///
+ ///
+ ///
+ public SplashScreen(SplashScreenStartupContext context, bool enableSignInButton = true)
+ :this(enableSignInButton)
+ {
+ StartupContext = context;
+ }
+
protected override void OnClosing(CancelEventArgs e)
{
// If we have multiple OnClosing events (ex Clicking the close button multiple times)
@@ -342,11 +357,8 @@ private void DynamoModel_RequestUpdateLoadBarStatus(SplashScreenLoadEventArgs ar
///
private string GetUserDirectory()
{
- var version = AssemblyHelper.GetDynamoVersion();
-
- var folder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
- return Path.Combine(Path.Combine(folder, Configurations.DynamoAsString, "Dynamo Core"),
- String.Format("{0}.{1}", version.Major, version.Minor));
+ return HostStartup.GetUserDirectory();
+
}
protected override async void OnContentRendered(EventArgs e)