Skip to content

Commit

Permalink
Create Revit.DesignApplication
Browse files Browse the repository at this point in the history
  • Loading branch information
ricaun committed Sep 18, 2024
1 parent 5894834 commit 2b0c820
Show file tree
Hide file tree
Showing 12 changed files with 257 additions and 169 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ 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 version of Revit.
### Updates
- Use `DesignApplication` to load correct version of Revit.

## [1.4.0] / 2025-08-27
### Features
- Support Bundle multiple versions of Revit using `DesignAutomationLoadVersion`. (#7)
Expand Down Expand Up @@ -40,6 +46,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
Expand Down
Binary file modified DesignAutomationConsole/Bundle/RevitAddin.DA.Tester.bundle.zip
Binary file not shown.
74 changes: 74 additions & 0 deletions Revit.DesignApplication/DesignApplication.cs
Original file line number Diff line number Diff line change
@@ -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} \nAddInName:{data.RevitApp.ActiveAddInId?.GetAddInName()}");
Console.WriteLine("--------------------------------------------------");

e.Succeeded = Execute(data.RevitApp, data.FilePath, data.RevitDoc);
}
}
}
87 changes: 87 additions & 0 deletions Revit.DesignApplication/DesignApplicationLoader.cs
Original file line number Diff line number Diff line change
@@ -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>(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<TargetFrameworkAttribute>()?.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;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;

namespace RevitAddin.DA.Tester.Revit
namespace Revit.DesignApplication
{
public interface IDesignAutomation
{
Expand Down
66 changes: 66 additions & 0 deletions Revit.DesignApplication/Revit.DesignApplication.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<!-- RevitVersion -->
<PropertyGroup>
<TargetFrameworks>net47;net48;net8.0-windows</TargetFrameworks>
<AppendTargetFrameworkToOutputPath>true</AppendTargetFrameworkToOutputPath>
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
</PropertyGroup>
<Choose>
<When Condition="$(TargetFramework.StartsWith('net46'))">
<PropertyGroup>
<RevitVersion>2017</RevitVersion>
</PropertyGroup>
</When>
<When Condition="$(TargetFramework.StartsWith('net47'))">
<PropertyGroup>
<RevitVersion>2019</RevitVersion>
</PropertyGroup>
</When>
<When Condition="$(TargetFramework.StartsWith('net48'))">
<PropertyGroup>
<RevitVersion>2021</RevitVersion>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<RevitVersion>2025</RevitVersion>
</PropertyGroup>
</Otherwise>
</Choose>

<!-- Net Core -->
<PropertyGroup Condition="!$(TargetFramework.StartsWith('net4'))">
<EnableDynamicLoading>true</EnableDynamicLoading>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<GenerateDependencyFile>false</GenerateDependencyFile>
</PropertyGroup>

<!-- Release -->
<PropertyGroup Condition="!$(Configuration.Contains('Debug'))">
<Optimize>true</Optimize>
<OutputPath>bin\Release\$(RevitVersion)</OutputPath>
<DefineConstants>REVIT$(RevitVersion)</DefineConstants>
<NoWarn>MSB3052</NoWarn>
<DebugType>None</DebugType>
</PropertyGroup>

<!-- Debug -->
<PropertyGroup Condition="$(Configuration.Contains('Debug'))">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;REVIT$(RevitVersion)</DefineConstants>
<DebugType>Full</DebugType>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Autodesk.Forge.DesignAutomation.Revit" Version="$(RevitVersion).*" IncludeAssets="build; compile" PrivateAssets="All" />
<PackageReference Include="Revit_All_Main_Versions_API_x64" Version="$(RevitVersion).*" IncludeAssets="build; compile" PrivateAssets="All" />
</ItemGroup>

</Project>
6 changes: 6 additions & 0 deletions RevitAddin.DA.Tester.sln
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution", "Solution", "{64
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
Expand All @@ -32,6 +34,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
Expand Down
20 changes: 10 additions & 10 deletions RevitAddin.DA.Tester/Revit/App.cs
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
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 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("----------------------------------------");

designAutomation = new DesignAutomationLoadVersion<DesignAutomationController>();
return ExternalDBApplicationResult.Succeeded;
}

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);
}
}
}
Loading

0 comments on commit 2b0c820

Please sign in to comment.