diff --git a/src/Config/CS_SDK.props b/src/Config/CS_SDK.props
index 75482b9138c..5ad2265ce79 100644
--- a/src/Config/CS_SDK.props
+++ b/src/Config/CS_SDK.props
@@ -7,6 +7,8 @@
net8.0
+
+ libg_231_0_0
16.0
$(DotNet)
512
diff --git a/src/DynamoApplications/StartupUtils.cs b/src/DynamoApplications/StartupUtils.cs
index 78e663ffbfc..370fb77928f 100644
--- a/src/DynamoApplications/StartupUtils.cs
+++ b/src/DynamoApplications/StartupUtils.cs
@@ -157,6 +157,7 @@ public static void PreloadShapeManager(ref string geometryFactoryPath, ref strin
var versions = new[]
{
+ new Version(231,0,0),
new Version(230,0,0),
};
diff --git a/src/DynamoCore/DynamoCore.csproj b/src/DynamoCore/DynamoCore.csproj
index d076b3fd06b..4fbf0f0a017 100644
--- a/src/DynamoCore/DynamoCore.csproj
+++ b/src/DynamoCore/DynamoCore.csproj
@@ -33,6 +33,7 @@
+
@@ -112,15 +113,16 @@
- $(PkgDynamoVisualProgramming_LibG_230_0_0)\tools\libg_locale
+ $(PkgDynamoVisualProgramming_LibG_231_0_0)\tools\libg_locale
-
-
-
-
-
+
+
+
+
+
+
@@ -152,9 +154,10 @@
-
+
+
diff --git a/src/DynamoCoreWpf/DynamoCoreWpf.csproj b/src/DynamoCoreWpf/DynamoCoreWpf.csproj
index b9f35da89f6..d72d02f25da 100644
--- a/src/DynamoCoreWpf/DynamoCoreWpf.csproj
+++ b/src/DynamoCoreWpf/DynamoCoreWpf.csproj
@@ -1,4 +1,4 @@
-
+
true
@@ -186,7 +186,7 @@
-
+
diff --git a/src/DynamoManipulation/DynamoManipulation.csproj b/src/DynamoManipulation/DynamoManipulation.csproj
index 089d799430c..df12326978b 100644
--- a/src/DynamoManipulation/DynamoManipulation.csproj
+++ b/src/DynamoManipulation/DynamoManipulation.csproj
@@ -40,7 +40,7 @@
-
+
diff --git a/src/Libraries/Analysis/Analysis.csproj b/src/Libraries/Analysis/Analysis.csproj
index 19c11770278..dbe43109aa7 100644
--- a/src/Libraries/Analysis/Analysis.csproj
+++ b/src/Libraries/Analysis/Analysis.csproj
@@ -18,7 +18,7 @@
-
+
{7858fa8c-475f-4b8e-b468-1f8200778cf8}
DynamoCore
diff --git a/src/Libraries/CoreNodes/CoreNodes.csproj b/src/Libraries/CoreNodes/CoreNodes.csproj
index 7f9538ad80e..ec1765eedec 100644
--- a/src/Libraries/CoreNodes/CoreNodes.csproj
+++ b/src/Libraries/CoreNodes/CoreNodes.csproj
@@ -19,7 +19,7 @@
-
+
diff --git a/src/Libraries/GeometryColor/GeometryColor.csproj b/src/Libraries/GeometryColor/GeometryColor.csproj
index 27609c43552..d62e7e958e5 100644
--- a/src/Libraries/GeometryColor/GeometryColor.csproj
+++ b/src/Libraries/GeometryColor/GeometryColor.csproj
@@ -14,7 +14,7 @@
MSB3539;CS1591;NUnit2005;NUnit2007;CS0618;CS0612;CS0672
-
+
diff --git a/src/Libraries/GeometryUI/GeometryUI.csproj b/src/Libraries/GeometryUI/GeometryUI.csproj
index 4f5022990c0..74aa3a02d9d 100644
--- a/src/Libraries/GeometryUI/GeometryUI.csproj
+++ b/src/Libraries/GeometryUI/GeometryUI.csproj
@@ -17,7 +17,7 @@
-
+
diff --git a/src/Libraries/GeometryUIWpf/GeometryUIWpf.csproj b/src/Libraries/GeometryUIWpf/GeometryUIWpf.csproj
index fd1afa3f5d4..d2b479be624 100644
--- a/src/Libraries/GeometryUIWpf/GeometryUIWpf.csproj
+++ b/src/Libraries/GeometryUIWpf/GeometryUIWpf.csproj
@@ -21,7 +21,7 @@
-
+
diff --git a/src/Libraries/Tesellation/Tessellation.csproj b/src/Libraries/Tesellation/Tessellation.csproj
index 75fd79244fb..a0bd81d2436 100644
--- a/src/Libraries/Tesellation/Tessellation.csproj
+++ b/src/Libraries/Tesellation/Tessellation.csproj
@@ -14,7 +14,7 @@
MSB3539;CS1591;NUnit2005;NUnit2007;CS0618;CS0612;CS0672
-
+
diff --git a/src/Tools/DynamoInstallDetective/AscSDKWrapper.cs b/src/Tools/DynamoInstallDetective/AscSDKWrapper.cs
new file mode 100644
index 00000000000..71c3301c529
--- /dev/null
+++ b/src/Tools/DynamoInstallDetective/AscSDKWrapper.cs
@@ -0,0 +1,182 @@
+using System;
+using System.IO;
+using Microsoft.Win32;
+
+namespace DynamoInstallDetective
+{
+#if NET6_0_OR_GREATER
+ [System.Runtime.Versioning.SupportedOSPlatform("windows")]
+#endif
+ ///
+ /// Autodesk Shared Components SDK
+ ///
+ /// There is one or more installed shared components packages for each major version.
+ /// Major versions are for example 2026, 2027 and 2028 and corresponds to our global launches.
+ /// Minor versions are for example 1.0.0, 1.1.0, 2.0.0 etc.
+ ///
+ /// These packages are ususally installed in "C:\Program Files\Common Files\Autodesk Shared\Components",
+ /// for example in C:\Program Files\Common Files\Autodesk Shared\Components\2026\1.0.0 for version 1.0.0 of the package used by 2026 products.
+ ///
+ /// There is no guarantee that this localtion is used as it can be overridden at deplyments time. Instead, the registry should be queried
+ /// for the final location.
+ ///
+ /// The registry location "HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\SharedComponents\" contains one key for each major version,
+ /// for example the key 2026 is used for the 2026 package.
+ ///
+ /// Each key will hold two values:
+ /// Version: The current version of the package
+ /// InstallPath: The actual location where the package is installed.
+ ///
+ /// There is usually only one minor version installed for each major version but there are situations when multiple minor versions can be installed.
+ /// One of these cases is when testing beta versions of the shared components. The version used can then be overridden by using an environment variable,
+ /// ACS_VERSION_ that points to the prefered version to use. So to load the 2.0-beta verion of the 2026 components you would
+ /// set ACS_VERSION_2026 to 2.0-beta.
+ ///
+ /// All shared components are currenly installed into one flat directory for each release. Possible future changes include the ability to only install those
+ /// components that actually is needed. This wrapper might need to be updated at that point.
+ ///
+ internal class AscSdkWrapper
+ {
+ public enum ASC_STATUS
+ {
+ SUCCESS = 0,
+ UNABLE_TO_SET_INSTALL_PATH = 4,
+ BAD_ARGS = 5,
+ REG_FAILED = 6,
+ FUNCTION_CALL_FAILED = 7,
+ INITIALIZE_FAILED = 8,
+ ODIS_SDK_INITIALIZE_FAILED = 9,
+ ODIS_SDK_LOCK_FAILED = 10,
+ ODIS_SDK_UNLOCK_FAILED = 11,
+ INCORRECT_REG_PATH = 12,
+ EMPTY_REG_VERSION = 13,
+ FAILED = 100
+ };
+
+ private const string registryKey = @"SOFTWARE\Autodesk\SharedComponents\";
+
+ private readonly string majorRelease;
+ private readonly string version;
+ private bool fetchFromEnv;
+ private string installPath;
+ private string regPath;
+
+ ///
+ /// Allows the basekey to be ovrridden, used by unit tests
+ ///
+ public RegistryKey BaseKey { get; set; } = Registry.LocalMachine;
+
+ private ASC_STATUS ReadASCVersionFromEnv()
+ {
+ ASC_STATUS status = ASC_STATUS.FAILED;
+
+ var minorVersion = Environment.GetEnvironmentVariable(version);
+
+ if(minorVersion != null)
+ {
+ fetchFromEnv = true;
+
+ status = ReadASCInstallPathFromRegistry(majorRelease);
+
+ installPath = Path.Combine(installPath, minorVersion);
+
+ if(status != ASC_STATUS.SUCCESS)
+ {
+ fetchFromEnv = false;
+ }
+ }
+
+ return status;
+ }
+
+ private ASC_STATUS ReadASCInstallPathFromRegistry(string majorRelease)
+ {
+ ASC_STATUS status = ASC_STATUS.REG_FAILED;
+
+ var registryPath = Path.Combine(BaseKey.Name, registryKey, majorRelease);
+ if(string.IsNullOrEmpty(regPath))
+ {
+ regPath = registryPath;
+ }
+
+ const string valueName = @"InstallPath";
+ const string versionName = @"Version";
+
+ string installPath = Registry.GetValue(registryPath, valueName, null) as String;
+ if (installPath != null)
+ {
+ if (!Directory.Exists(installPath))
+ {
+ return ASC_STATUS.INCORRECT_REG_PATH;
+ }
+
+ if (fetchFromEnv)
+ {
+ this.installPath = installPath;
+ status = ASC_STATUS.SUCCESS;
+ }
+ else
+ {
+ string version = Registry.GetValue(registryPath, versionName, null) as String;
+ if (string.IsNullOrEmpty(version))
+ {
+ return ASC_STATUS.EMPTY_REG_VERSION;
+ }
+
+ this.installPath = Path.Combine(installPath, version);
+
+ if (!Directory.Exists(this.installPath))
+ {
+ return ASC_STATUS.INCORRECT_REG_PATH;
+ }
+ status = ASC_STATUS.SUCCESS;
+ }
+ }
+ return status;
+ }
+ ///
+ /// Initialize ASC wrapper
+ ///
+ /// Major ASC release, for example 2026
+ public AscSdkWrapper(string release)
+ {
+ majorRelease = release;
+ version = @"ACS_VERSION_" + majorRelease;
+ }
+
+ ///
+ /// Get the install path for the major release
+ ///
+ /// The install path for the major release if successful
+ /// ASC_STATUS.SUCCESS if path was retrived successfully
+ public ASC_STATUS GetInstalledPath(ref string installedPath)
+ {
+ if(string.IsNullOrEmpty(majorRelease))
+ {
+ return ASC_STATUS.INITIALIZE_FAILED;
+ }
+
+ var status = ReadASCVersionFromEnv() == ASC_STATUS.SUCCESS ? ASC_STATUS.SUCCESS : ReadASCInstallPathFromRegistry(majorRelease);
+ installedPath = installPath;
+
+ return status;
+ }
+
+ ///
+ /// Get the major version of all ASC packages installed on the local machine
+ ///
+ /// An array of major versions, for example ["2026, "2027", "2028"]
+ public static string[] GetMajorVersions()
+ {
+ string[] majorVersions = [];
+ var baseKey = Registry.LocalMachine;
+ var subkey = baseKey.OpenSubKey(@"SOFTWARE\Autodesk\SharedComponents");
+ if(subkey != null)
+ {
+ majorVersions = subkey.GetSubKeyNames();
+ subkey.Close();
+ }
+ return majorVersions;
+ }
+ }
+}
diff --git a/src/Tools/DynamoInstallDetective/ProductLookUp.cs b/src/Tools/DynamoInstallDetective/ProductLookUp.cs
index fb502c03f5e..99dd112748b 100644
--- a/src/Tools/DynamoInstallDetective/ProductLookUp.cs
+++ b/src/Tools/DynamoInstallDetective/ProductLookUp.cs
@@ -348,6 +348,62 @@ public virtual Tuple GetVersionInfoFromFile(string filePath)
}
}
+#if NET6_0_OR_GREATER
+ [SupportedOSPlatform("windows")]
+#endif
+ ///
+ /// Helper class for looking up the install directories for all installed ASC components
+ ///
+ public class InstalledAscLookUp : InstalledProductLookUp
+ {
+ const string asc = @"Autodesk Shared Components";
+
+ ///
+ /// Constructor
+ ///
+ /// File to look for
+ public InstalledAscLookUp(string fileLookup) : base(asc, fileLookup)
+ {
+ }
+
+ ///
+ /// Get all major ASC versions
+ ///
+ ///
+ internal override IEnumerable<(string DisplayName, string ProductKey)> GetProductNameAndCodeList()
+ {
+ var list = AscSdkWrapper.GetMajorVersions().Select(x => (DisplayName: x, ProductKey: string.Empty));
+ return list;
+ }
+
+ ///
+ /// The result is never used but still needs to be overridden
+ ///
+ ///
+ public override IEnumerable GetProductNameList()
+ {
+ var list = new List();
+ return list;
+ }
+
+ ///
+ /// Get the install location for the ASC component
+ ///
+ /// ASC major verion
+ ///
+ public override string GetInstallLocationFromProductName(string name)
+ {
+ AscSdkWrapper asc = new AscSdkWrapper(name);
+ string path = string.Empty;
+ if(asc.GetInstalledPath(ref path) == AscSdkWrapper.ASC_STATUS.SUCCESS)
+ {
+ return path;
+ }
+
+ return null;
+ }
+ }
+
#if NET6_0_OR_GREATER
[SupportedOSPlatform("windows")]
#endif
diff --git a/src/Tools/DynamoInstallDetective/Utilities.cs b/src/Tools/DynamoInstallDetective/Utilities.cs
index a4f5fe3e729..f2f8a36e404 100644
--- a/src/Tools/DynamoInstallDetective/Utilities.cs
+++ b/src/Tools/DynamoInstallDetective/Utilities.cs
@@ -94,6 +94,10 @@ public static IEnumerable FindMultipleProductInstallations(List productS
using (RegUtils.StartCache())
{
var installs = new InstalledProducts();
+
+ // Look for ASM in installed ASC packages
+ installs.LookUpAndInitProducts(new InstalledAscLookUp(fileSearchPattern));
+
// Look up products with ASM installed on user's computer
foreach (var productSearchPattern in productSearchPatterns)
{
diff --git a/src/Tools/DynamoShapeManager/Preloader.cs b/src/Tools/DynamoShapeManager/Preloader.cs
index 3646a01851f..1f980834c49 100644
--- a/src/Tools/DynamoShapeManager/Preloader.cs
+++ b/src/Tools/DynamoShapeManager/Preloader.cs
@@ -58,6 +58,7 @@ public class Preloader
public Preloader(string rootFolder)
: this(rootFolder, new[]
{
+ new Version(231,0,0),
new Version(230,0,0),
})
{
diff --git a/src/Tools/DynamoShapeManager/Utilities.cs b/src/Tools/DynamoShapeManager/Utilities.cs
index 0d458b5d319..dfe07fcc49f 100644
--- a/src/Tools/DynamoShapeManager/Utilities.cs
+++ b/src/Tools/DynamoShapeManager/Utilities.cs
@@ -454,6 +454,8 @@ internal static bool IsASMInstallationComplete(IEnumerable filePaths, in
{
case 230:
return !ASM230DllNames.Except(fileNames).Any();
+ case 231:
+ return true;
default:
// We don't know this version so it's safest to assume it's not complete.
return false;
diff --git a/src/Tools/NodeDocumentationMarkdownGenerator/NodeDocumentationMarkdownGenerator.csproj b/src/Tools/NodeDocumentationMarkdownGenerator/NodeDocumentationMarkdownGenerator.csproj
index fb551db0c7e..bada63b972e 100644
--- a/src/Tools/NodeDocumentationMarkdownGenerator/NodeDocumentationMarkdownGenerator.csproj
+++ b/src/Tools/NodeDocumentationMarkdownGenerator/NodeDocumentationMarkdownGenerator.csproj
@@ -12,6 +12,7 @@
+
diff --git a/test/Libraries/AnalysisTests/AnalysisTests.csproj b/test/Libraries/AnalysisTests/AnalysisTests.csproj
index bca24f6d0c5..57725777cb3 100644
--- a/test/Libraries/AnalysisTests/AnalysisTests.csproj
+++ b/test/Libraries/AnalysisTests/AnalysisTests.csproj
@@ -10,7 +10,7 @@
AnalysisTests
-
+
diff --git a/test/Libraries/DynamoPythonTests/DynamoPythonTests.csproj b/test/Libraries/DynamoPythonTests/DynamoPythonTests.csproj
index a5ccc1139ae..a8f4f323f24 100644
--- a/test/Libraries/DynamoPythonTests/DynamoPythonTests.csproj
+++ b/test/Libraries/DynamoPythonTests/DynamoPythonTests.csproj
@@ -18,7 +18,7 @@
-
+
diff --git a/test/Libraries/DynamoUtilitiesTests/ASCLookUpTests.cs b/test/Libraries/DynamoUtilitiesTests/ASCLookUpTests.cs
new file mode 100644
index 00000000000..acb4f7820a3
--- /dev/null
+++ b/test/Libraries/DynamoUtilitiesTests/ASCLookUpTests.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using DynamoInstallDetective;
+using Microsoft.Win32;
+using Moq;
+
+using NUnit.Framework;
+
+namespace DynamoUtilitiesTests
+{
+ public class ASCLookUpTests
+ {
+ [Test, Category("ASCLookUp"), Category("UnitTests")]
+ public void GetASCInstallDirectoryWorking()
+ {
+ var working = new AscSdkWrapper("WorkingMajorVersion");
+ working.BaseKey = Registry.CurrentUser;
+
+ string installDirectory = string.Empty;
+
+ var ret = working.GetInstalledPath(ref installDirectory);
+
+ Assert.AreEqual(ret, AscSdkWrapper.ASC_STATUS.SUCCESS);
+ Assert.IsNotEmpty(installDirectory);
+ }
+
+ [Test, Category("ASCLookUp"), Category("UnitTests")]
+ public void GetASCInstallDirectoryNonWorking()
+ {
+ var working = new AscSdkWrapper("nonWorkingMajorVersion");
+ working.BaseKey = Registry.CurrentUser;
+
+ string installDirectory = string.Empty;
+
+ var ret = working.GetInstalledPath(ref installDirectory);
+
+ Assert.AreEqual(ret, AscSdkWrapper.ASC_STATUS.INCORRECT_REG_PATH);
+ Assert.IsNotEmpty(installDirectory);
+ }
+
+ [Test, Category("ASCLookUp"), Category("UnitTests")]
+ public void GetASCInstallDirectoryBadVersion()
+ {
+ var working = new AscSdkWrapper("badMajorVersion");
+ working.BaseKey = Registry.CurrentUser;
+
+ string installDirectory = string.Empty;
+
+ var ret = working.GetInstalledPath(ref installDirectory);
+
+ Assert.AreEqual(ret, AscSdkWrapper.ASC_STATUS.REG_FAILED);
+ Assert.IsNotEmpty(installDirectory);
+ }
+
+ [Test, Category("ASCLookUp"), Category("UnitTests")]
+ public void GetASCInstallDirectoryEmptyVersion()
+ {
+ var working = new AscSdkWrapper("");
+ working.BaseKey = Registry.CurrentUser;
+
+ string installDirectory = string.Empty;
+
+ var ret = working.GetInstalledPath(ref installDirectory);
+
+ Assert.AreEqual(ret, AscSdkWrapper.ASC_STATUS.INITIALIZE_FAILED);
+ Assert.IsEmpty(installDirectory);
+ }
+ }
+}
diff --git a/test/Libraries/DynamoUtilitiesTests/Setup.cs b/test/Libraries/DynamoUtilitiesTests/Setup.cs
index 1d56d671c3d..8dcde9300ed 100644
--- a/test/Libraries/DynamoUtilitiesTests/Setup.cs
+++ b/test/Libraries/DynamoUtilitiesTests/Setup.cs
@@ -1,13 +1,16 @@
using System;
using System.IO;
using System.Reflection;
+using System.Security.Principal;
using Dynamo.Utilities;
+using Microsoft.Win32;
using NUnit.Framework;
[SetUpFixture]
public class Setup
{
private AssemblyHelper assemblyHelper;
+ private DirectoryInfo tempDir;
[OneTimeSetUp]
public void RunBeforeAllTests()
@@ -24,6 +27,19 @@ public void RunBeforeAllTests()
assemblyHelper = new AssemblyHelper(moduleRootFolder.FullName, resolutionPaths);
AppDomain.CurrentDomain.AssemblyResolve += assemblyHelper.ResolveAssembly;
+
+ // Setup fake ASC installs
+ tempDir = Directory.CreateTempSubdirectory();
+ var majorVersion = tempDir.CreateSubdirectory(@"WorkingMajorVersion");
+ majorVersion.CreateSubdirectory(@"1.0.0");
+ RegistryKey key = Registry.CurrentUser;
+ var workingMajorVersion = key.CreateSubKey(@"SOFTWARE\Autodesk\SharedComponents\WorkingMajorVersion");
+ workingMajorVersion.SetValue(@"Version", @"1.0.0");
+ workingMajorVersion.SetValue(@"InstallPath", majorVersion.FullName);
+
+ var nonWorkingMajorVersion = key.CreateSubKey(@"SOFTWARE\Autodesk\SharedComponents\nonWorkingMajorVersion");
+ nonWorkingMajorVersion.SetValue(@"Version", @"1.0.0");
+ nonWorkingMajorVersion.SetValue(@"InstallPath", @"BadPath");
}
[OneTimeTearDown]
@@ -31,5 +47,9 @@ public void RunAfterAllTests()
{
AppDomain.CurrentDomain.AssemblyResolve -= assemblyHelper.ResolveAssembly;
assemblyHelper = null;
+ tempDir.Delete(true);
+ RegistryKey key = Registry.CurrentUser;
+ key.DeleteSubKey(@"SOFTWARE\Autodesk\SharedComponents\WorkingMajorVersion");
+ key.DeleteSubKey(@"SOFTWARE\Autodesk\SharedComponents\nonWorkingMajorVersion");
}
}
diff --git a/test/Libraries/GeometryColorTests/GeometryColorTests.csproj b/test/Libraries/GeometryColorTests/GeometryColorTests.csproj
index a15cfe86f63..6d845f07446 100644
--- a/test/Libraries/GeometryColorTests/GeometryColorTests.csproj
+++ b/test/Libraries/GeometryColorTests/GeometryColorTests.csproj
@@ -10,7 +10,7 @@
DisplayTests
-
+
diff --git a/test/Libraries/TestServices/TestServices.csproj b/test/Libraries/TestServices/TestServices.csproj
index 84ccea3d6c4..8064c828ad3 100644
--- a/test/Libraries/TestServices/TestServices.csproj
+++ b/test/Libraries/TestServices/TestServices.csproj
@@ -10,7 +10,7 @@
TestServices
-
+
diff --git a/test/Libraries/WorkflowTests/WorkflowTests.csproj b/test/Libraries/WorkflowTests/WorkflowTests.csproj
index 0db70e3c781..1f75b980bfe 100644
--- a/test/Libraries/WorkflowTests/WorkflowTests.csproj
+++ b/test/Libraries/WorkflowTests/WorkflowTests.csproj
@@ -14,7 +14,7 @@
-
+