diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7eadfab..6590fd7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+## [1.4.1] / 2025-09-18
+### Features
+- Create `Revit.DesignApplication` with `DesignApplication` to load correct assembly version in the bundle. (#7)
+### Updates
+- Use `DesignApplication` to load correct assembly version in the bundle.
+- Add `ApplicationInitialized` event to test.
+
## [1.4.0] / 2025-08-27
### Features
- Support Bundle multiple versions of Revit using `DesignAutomationLoadVersion`. (#7)
@@ -40,6 +47,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- First Release
[vNext]: ../../compare/1.0.0...HEAD
+[1.4.1]: ../../compare/1.4.0...1.4.1
[1.4.0]: ../../compare/1.3.1...1.4.0
[1.3.1]: ../../compare/1.3.0...1.3.1
[1.3.0]: ../../compare/1.2.0...1.3.0
diff --git a/DesignAutomationConsole/Bundle/RevitAddin.DA.Tester.bundle.zip b/DesignAutomationConsole/Bundle/RevitAddin.DA.Tester.bundle.zip
index aaf4471..049c058 100644
Binary files a/DesignAutomationConsole/Bundle/RevitAddin.DA.Tester.bundle.zip and b/DesignAutomationConsole/Bundle/RevitAddin.DA.Tester.bundle.zip differ
diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 0000000..a5caae5
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,5 @@
+
+
+ 1.4.1
+
+
\ No newline at end of file
diff --git a/Revit.DesignApplication/DesignApplication.cs b/Revit.DesignApplication/DesignApplication.cs
new file mode 100644
index 0000000..a91b5ab
--- /dev/null
+++ b/Revit.DesignApplication/DesignApplication.cs
@@ -0,0 +1,74 @@
+using Autodesk.Revit.ApplicationServices;
+using Autodesk.Revit.DB;
+using DesignAutomationFramework;
+using System;
+
+namespace Revit.DesignApplication
+{
+ public abstract class DesignApplication : IExternalDBApplication, IDesignAutomation
+ {
+ public ControlledApplication Application { get; private set; }
+ public abstract void OnStartup();
+ public abstract void OnShutdown();
+ public abstract bool Execute(Application application, string filePath, Document document);
+
+ private IExternalDBApplication designApplication;
+ public ExternalDBApplicationResult OnStartup(ControlledApplication application)
+ {
+ this.Application = application;
+
+ designApplication = DesignApplicationLoader.LoadVersion(this);
+
+ if (designApplication is IExternalDBApplication)
+ {
+ return designApplication.OnStartup(application);
+ }
+
+ Console.WriteLine("----------------------------------------");
+ Console.WriteLine($"FullName: \t{this.GetType().Assembly.FullName}");
+ Console.WriteLine($"AddInName: \t{this.Application.ActiveAddInId?.GetAddInName()}");
+ Console.WriteLine("----------------------------------------");
+
+ OnStartup();
+ DesignAutomationBridge.DesignAutomationReadyEvent += DesignAutomationReadyEvent;
+
+ return ExternalDBApplicationResult.Succeeded;
+ }
+
+ public ExternalDBApplicationResult OnShutdown(ControlledApplication application)
+ {
+ this.Application = application;
+
+ if (designApplication is IExternalDBApplication)
+ {
+ try
+ {
+ return designApplication.OnShutdown(application);
+ }
+ finally
+ {
+ DesignApplicationLoader.Dispose();
+ }
+ }
+
+ OnShutdown();
+ DesignAutomationBridge.DesignAutomationReadyEvent -= DesignAutomationReadyEvent;
+
+ return ExternalDBApplicationResult.Succeeded;
+ }
+
+
+ private void DesignAutomationReadyEvent(object sender, DesignAutomationReadyEventArgs e)
+ {
+ DesignAutomationBridge.DesignAutomationReadyEvent -= DesignAutomationReadyEvent;
+
+ var data = e.DesignAutomationData;
+
+ Console.WriteLine("--------------------------------------------------");
+ Console.WriteLine($"RevitApp: {data.RevitApp} \tFilePath: {data.FilePath} \tRevitDoc: {data.RevitDoc} \tAddInName:{data.RevitApp.ActiveAddInId?.GetAddInName()}");
+ Console.WriteLine("--------------------------------------------------");
+
+ e.Succeeded = Execute(data.RevitApp, data.FilePath, data.RevitDoc);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Revit.DesignApplication/DesignApplicationLoader.cs b/Revit.DesignApplication/DesignApplicationLoader.cs
new file mode 100644
index 0000000..b9e1ebc
--- /dev/null
+++ b/Revit.DesignApplication/DesignApplicationLoader.cs
@@ -0,0 +1,87 @@
+using Autodesk.Revit.DB;
+using System;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.Versioning;
+
+namespace Revit.DesignApplication
+{
+ internal static class DesignApplicationLoader
+ {
+ private static Assembly loadAssembly;
+ public static IExternalDBApplication LoadVersion(T designApplication) where T : DesignApplication
+ {
+ var type = designApplication.GetType();
+
+ var similar = AppDomain.CurrentDomain.GetAssemblies().Where(e => e.FullName == type.Assembly.FullName);
+ if (similar.Count() >= 2)
+ {
+ return null;
+ }
+
+ var location = type.Assembly.Location;
+ var revitAssemblyReference = type.Assembly.GetReferencedAssemblies().FirstOrDefault(e => e.Name.Equals("RevitAPI"));
+ var revitAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(e => e.GetName().Name.Equals("RevitAPI"));
+
+ var revitReferenceVersion = revitAssemblyReference.Version.Major + 2000;
+ var revitVersion = revitAssembly.GetName().Version.Major + 2000;
+
+ Console.WriteLine("--------------------------------------------------");
+ Console.WriteLine($"DesignApplicationLoader: \t{revitVersion} -> {revitReferenceVersion}");
+
+ for (int version = revitVersion; version > revitReferenceVersion; version--)
+ {
+ var directory = Path.GetDirectoryName(location);
+ var directoryVersionRevit = Path.Combine(directory, "..", version.ToString());
+ var fileName = Path.Combine(directoryVersionRevit, Path.GetFileName(location));
+
+ //Console.WriteLine($"DesignApplicationLoader Try: \t{version}");
+
+ if (File.Exists(fileName))
+ {
+ fileName = new FileInfo(fileName).FullName;
+ Console.WriteLine($"DesignApplicationLoader File Exists: \t{fileName}");
+ Console.WriteLine($"DesignApplicationLoader Version: \t{version}");
+ Console.WriteLine($"DesignApplicationLoader LoadFile: \t{Path.GetFileName(fileName)}");
+ AppDomain.CurrentDomain.AssemblyResolve += LoadAssemblyResolve;
+ loadAssembly = Assembly.LoadFile(fileName);
+ break;
+ }
+ }
+
+ Console.WriteLine("----------------------------------------");
+
+ if (loadAssembly is not null)
+ {
+ var loadType = loadAssembly.GetType(type.FullName);
+
+ Console.WriteLine($"DesignApplicationLoader Type: {loadType}");
+ Console.WriteLine($"DesignApplicationLoader FrameworkName: \t{loadType.Assembly.GetCustomAttribute()?.FrameworkName}");
+ Console.WriteLine("----------------------------------------");
+
+ return Activator.CreateInstance(loadType) as IExternalDBApplication;
+ }
+
+ return null;
+ }
+
+ private static Assembly LoadAssemblyResolve(object sender, ResolveEventArgs args)
+ {
+ var assemblyName = new AssemblyName(args.Name);
+ var assemblyPath = Path.Combine(Path.GetDirectoryName(loadAssembly.Location), assemblyName.Name + ".dll");
+ if (File.Exists(assemblyPath))
+ {
+ var folderName = Path.GetFileName(Path.GetDirectoryName(assemblyPath));
+ Console.WriteLine($"AssemblyResolve LoadFile: {folderName}\\{assemblyName.Name + ".dll"}");
+ return Assembly.LoadFile(assemblyPath);
+ }
+ return null;
+ }
+
+ public static void Dispose()
+ {
+ AppDomain.CurrentDomain.AssemblyResolve -= LoadAssemblyResolve;
+ }
+ }
+}
\ No newline at end of file
diff --git a/RevitAddin.DA.Tester/Revit/IDesignAutomation.cs b/Revit.DesignApplication/IDesignAutomation.cs
similarity index 84%
rename from RevitAddin.DA.Tester/Revit/IDesignAutomation.cs
rename to Revit.DesignApplication/IDesignAutomation.cs
index cfb523a..e8df580 100644
--- a/RevitAddin.DA.Tester/Revit/IDesignAutomation.cs
+++ b/Revit.DesignApplication/IDesignAutomation.cs
@@ -1,7 +1,7 @@
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
-namespace RevitAddin.DA.Tester.Revit
+namespace Revit.DesignApplication
{
public interface IDesignAutomation
{
diff --git a/Revit.DesignApplication/Revit.DesignApplication.csproj b/Revit.DesignApplication/Revit.DesignApplication.csproj
new file mode 100644
index 0000000..c860d9c
--- /dev/null
+++ b/Revit.DesignApplication/Revit.DesignApplication.csproj
@@ -0,0 +1,66 @@
+
+
+
+ Library
+ latest
+
+
+
+
+ net47;net48;net8.0-windows
+ true
+ None
+
+
+
+
+ 2017
+
+
+
+
+ 2019
+
+
+
+
+ 2021
+
+
+
+
+ 2025
+
+
+
+
+
+
+ true
+ true
+ false
+
+
+
+
+ true
+ bin\Release\$(RevitVersion)
+ REVIT$(RevitVersion)
+ MSB3052
+ None
+
+
+
+
+ true
+ bin\Debug\
+ DEBUG;TRACE;REVIT$(RevitVersion)
+ Full
+
+
+
+
+
+
+
+
diff --git a/RevitAddin.DA.Tester.sln b/RevitAddin.DA.Tester.sln
index 2e956d8..81427e3 100644
--- a/RevitAddin.DA.Tester.sln
+++ b/RevitAddin.DA.Tester.sln
@@ -10,12 +10,15 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution", "Solution", "{64A2F0FA-4270-45D5-B9DB-3561832ADA42}"
ProjectSection(SolutionItems) = preProject
CHANGELOG.md = CHANGELOG.md
+ Directory.Build.props = Directory.Build.props
LICENSE = LICENSE
README.md = README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DesignAutomationConsole", "DesignAutomationConsole\DesignAutomationConsole.csproj", "{7F41BE81-4EFB-4FAC-8563-B5EDAEA9F44B}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Revit.DesignApplication", "Revit.DesignApplication\Revit.DesignApplication.csproj", "{0966B1C7-6ECE-44D0-A71B-7C26EB598BFF}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -32,6 +35,10 @@ Global
{7F41BE81-4EFB-4FAC-8563-B5EDAEA9F44B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7F41BE81-4EFB-4FAC-8563-B5EDAEA9F44B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7F41BE81-4EFB-4FAC-8563-B5EDAEA9F44B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0966B1C7-6ECE-44D0-A71B-7C26EB598BFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0966B1C7-6ECE-44D0-A71B-7C26EB598BFF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0966B1C7-6ECE-44D0-A71B-7C26EB598BFF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0966B1C7-6ECE-44D0-A71B-7C26EB598BFF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/RevitAddin.DA.Tester/Revit/App.cs b/RevitAddin.DA.Tester/Revit/App.cs
index e1bf6f9..cf6c552 100644
--- a/RevitAddin.DA.Tester/Revit/App.cs
+++ b/RevitAddin.DA.Tester/Revit/App.cs
@@ -1,31 +1,39 @@
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
+using Revit.DesignApplication;
using RevitAddin.DA.Tester.Services;
using System;
namespace RevitAddin.DA.Tester.Revit
{
- public class App : IExternalDBApplication
+ public class App : DesignApplication
{
- IDisposable designAutomation;
- public ExternalDBApplicationResult OnStartup(ControlledApplication application)
+ public static string AddInName { get; set; } = "none";
+ public override void OnStartup()
{
Console.WriteLine("----------------------------------------");
Console.WriteLine($"FullName: \t{this.GetType().Assembly.FullName}");
Console.WriteLine("----------------------------------------");
Console.WriteLine($"Location: {this.GetType().Assembly.Location}");
Console.WriteLine("----------------------------------------");
- Console.WriteLine($"AddInName: \t{application.ActiveAddInId?.GetAddInName()}");
+ Console.WriteLine($"AddInName: \t{Application.ActiveAddInId?.GetAddInName()}");
Console.WriteLine("----------------------------------------");
+ Application.ApplicationInitialized += Application_ApplicationInitialized;
+ }
- designAutomation = new DesignAutomationLoadVersion();
- return ExternalDBApplicationResult.Succeeded;
+ private void Application_ApplicationInitialized(object sender, Autodesk.Revit.DB.Events.ApplicationInitializedEventArgs e)
+ {
+ var application = (Application)sender;
+ AddInName = application.ActiveAddInId?.GetAddInName();
}
- public ExternalDBApplicationResult OnShutdown(ControlledApplication application)
+ public override void OnShutdown()
+ {
+
+ }
+ public override bool Execute(Application application, string filePath, Document document)
{
- designAutomation?.Dispose();
- return ExternalDBApplicationResult.Succeeded;
+ return new DesignAutomationController().Execute(application, filePath, document);
}
}
}
\ No newline at end of file
diff --git a/RevitAddin.DA.Tester/Revit/DesignAutomation.cs b/RevitAddin.DA.Tester/Revit/DesignAutomation.cs
deleted file mode 100644
index 34f6473..0000000
--- a/RevitAddin.DA.Tester/Revit/DesignAutomation.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-using DesignAutomationFramework;
-using System;
-using System.Linq;
-
-namespace RevitAddin.DA.Tester.Revit
-{
- public class DesignAutomation : DesignAutomation where T : IDesignAutomation
- {
- public DesignAutomation() : base(Activator.CreateInstance(typeof(T)))
- {
-
- }
- public DesignAutomation(T instance) : base(instance)
- {
-
- }
- }
-
- public class DesignAutomation : IDisposable
- {
- private readonly object instance;
-
- public DesignAutomation(Type type)
- {
- this.instance = Activator.CreateInstance(type);
- Initialize();
- }
-
- public DesignAutomation(object instance)
- {
- this.instance = instance;
- Initialize();
- }
-
- public virtual void Initialize()
- {
- Console.WriteLine($"{nameof(DesignAutomation)} Initialize: \t{instance}");
- DesignAutomationBridge.DesignAutomationReadyEvent += DesignAutomationReadyEvent;
- }
-
- public void Dispose()
- {
- Console.WriteLine($"{nameof(DesignAutomation)} Dispose: \t{instance}");
- DesignAutomationBridge.DesignAutomationReadyEvent -= DesignAutomationReadyEvent;
- }
-
- private void DesignAutomationReadyEvent(object sender, DesignAutomationReadyEventArgs e)
- {
- DesignAutomationBridge.DesignAutomationReadyEvent -= DesignAutomationReadyEvent;
-
- var data = e.DesignAutomationData;
-
- Console.WriteLine("--------------------------------------------------");
- Console.WriteLine($"RevitApp: {data.RevitApp} FilePath: {data.FilePath} RevitDoc: {data.RevitDoc}");
- Console.WriteLine("--------------------------------------------------");
-
- try
- {
- var method = instance.GetType().GetMethods()
- .Where(e => e.Name.Equals(nameof(IDesignAutomation.Execute)))
- .FirstOrDefault(e => e.GetParameters().Count() == 3);
-
- Console.WriteLine($"Invoke: {method}");
-
- var result = method.Invoke(instance, new object[] { data.RevitApp, data.FilePath, data.RevitDoc });
-
- if (result is bool resultBool)
- e.Succeeded = resultBool;
- }
- catch (Exception ex)
- {
- Console.WriteLine($"{nameof(DesignAutomation)} Invoke Exception: \t{ex.Message}");
- throw;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/RevitAddin.DA.Tester/Revit/DesignAutomationLoadVersion.cs b/RevitAddin.DA.Tester/Revit/DesignAutomationLoadVersion.cs
deleted file mode 100644
index 1d68b7d..0000000
--- a/RevitAddin.DA.Tester/Revit/DesignAutomationLoadVersion.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-using System;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.Versioning;
-
-namespace RevitAddin.DA.Tester.Revit
-{
- public class DesignAutomationLoadVersion : DesignAutomationLoadVersion where T : IDesignAutomation
- {
- public DesignAutomationLoadVersion() : base(typeof(T))
- {
-
- }
- }
-
- public class DesignAutomationLoadVersion : IDisposable
- {
- readonly IDisposable designAutomation;
- readonly Assembly loadAssembly;
-
- public DesignAutomationLoadVersion(Type type)
- {
- var location = type.Assembly.Location;
- var revitAssemblyReference = type.Assembly.GetReferencedAssemblies().FirstOrDefault(e => e.Name.Equals("RevitAPI"));
- var revitAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(e => e.GetName().Name.Equals("RevitAPI"));
-
- var revitReferenceVersion = revitAssemblyReference.Version.Major + 2000;
- var revitVersion = revitAssembly.GetName().Version.Major + 2000;
-
- Console.WriteLine($"DesignAutomationLoadVersion: \t{revitVersion} -> {revitReferenceVersion}");
-
- for (int version = revitVersion; version > revitReferenceVersion; version--)
- {
- var directory = System.IO.Path.GetDirectoryName(location);
- var directoryVersionRevit = System.IO.Path.Combine(directory, "..", version.ToString());
- var fileName = System.IO.Path.Combine(directoryVersionRevit, System.IO.Path.GetFileName(location));
-
- Console.WriteLine($"DesignAutomationLoadVersion Try: \t{version}");
-
- if (File.Exists(fileName))
- {
- fileName = new FileInfo(fileName).FullName;
- Console.WriteLine($"DesignAutomationLoadVersion File Exists: \t{fileName}");
- Console.WriteLine($"DesignAutomationLoadVersion Version: \t{version}");
- Console.WriteLine($"DesignAutomationLoadVersion LoadFile: \t{Path.GetFileName(fileName)}");
- AppDomain.CurrentDomain.AssemblyResolve += LoadAssemblyResolve;
- loadAssembly = Assembly.LoadFile(fileName);
- type = loadAssembly.GetType(type.FullName);
- break;
- }
- }
-
- Console.WriteLine("----------------------------------------");
- Console.WriteLine($"DesignAutomationLoadVersion Type: {type}");
- Console.WriteLine($"DesignAutomationLoadVersion FrameworkName: \t{type.Assembly.GetCustomAttribute()?.FrameworkName}");
- designAutomation = new DesignAutomation(type);
- }
-
- private Assembly LoadAssemblyResolve(object sender, ResolveEventArgs args)
- {
- var assemblyName = new AssemblyName(args.Name);
- var assemblyPath = Path.Combine(Path.GetDirectoryName(loadAssembly.Location), assemblyName.Name + ".dll");
- if (File.Exists(assemblyPath))
- {
- var folderName = Path.GetFileName(Path.GetDirectoryName(assemblyPath));
- Console.WriteLine($"AssemblyResolve LoadFile: {folderName}\\{assemblyName.Name + ".dll"}");
- return Assembly.LoadFile(assemblyPath);
- }
- return null;
- }
-
- public void Dispose()
- {
- designAutomation?.Dispose();
- AppDomain.CurrentDomain.AssemblyResolve -= LoadAssemblyResolve;
- }
- }
-}
\ No newline at end of file
diff --git a/RevitAddin.DA.Tester/RevitAddin.DA.Tester.csproj b/RevitAddin.DA.Tester/RevitAddin.DA.Tester.csproj
index 9c0a625..291ea40 100644
--- a/RevitAddin.DA.Tester/RevitAddin.DA.Tester.csproj
+++ b/RevitAddin.DA.Tester/RevitAddin.DA.Tester.csproj
@@ -75,7 +75,6 @@
RevitAddin.DA.Tester
- 1.4.0
{7C324916-9F8D-43B0-B226-DA67D2504393}
@@ -132,6 +131,10 @@
+
+
+
+
True
diff --git a/RevitAddin.DA.Tester/Services/DesignAutomationController.cs b/RevitAddin.DA.Tester/Services/DesignAutomationController.cs
index b05bf10..cb66a9c 100644
--- a/RevitAddin.DA.Tester/Services/DesignAutomationController.cs
+++ b/RevitAddin.DA.Tester/Services/DesignAutomationController.cs
@@ -9,7 +9,7 @@
namespace RevitAddin.DA.Tester.Services
{
- public class DesignAutomationController : IDesignAutomation
+ public class DesignAutomationController
{
public bool Execute(Application application, string filePath = null, Document document = null)
{
@@ -39,6 +39,7 @@ public bool Execute(Application application, string filePath = null, Document do
}
Console.WriteLine($"UI:\t{UI.IsValid()}");
+ Console.WriteLine($"App.AddInName:\t{App.AddInName}");
Console.WriteLine("----------------------------------------");
Console.WriteLine($"Shape:\t{typeof(ricaun.Revit.DB.Shape.Colors).Assembly}");
Console.WriteLine($"Shape Location:\t{typeof(ricaun.Revit.DB.Shape.Colors).Assembly.Location}");