Skip to content

Commit

Permalink
Merge pull request #54 from chuongmep/r25_unload_ass
Browse files Browse the repository at this point in the history
Feat : R25 Support Unload Assembly
  • Loading branch information
chuongmep authored May 12, 2024
2 parents 74dc4e8 + c74f329 commit 2d8366b
Show file tree
Hide file tree
Showing 12 changed files with 213 additions and 14 deletions.
10 changes: 10 additions & 0 deletions AddInManager.sln
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test", "Test\Test.csproj",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RevitElementBipChecker", "RevitElementBipChecker\RevitElementBipChecker.csproj", "{21460D85-C4AD-49D5-963F-CF13C4AE99EB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test2", "Test2\Test2.csproj", "{DA609427-F086-4C79-A5FA-202DBB5DE48D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug R22|Any CPU = Debug R22|Any CPU
Debug R23|Any CPU = Debug R23|Any CPU
Debug R24|Any CPU = Debug R24|Any CPU
Debug R25|Any CPU = Debug R25|Any CPU
Installer|Any CPU = Installer|Any CPU
Release R19|Any CPU = Release R19|Any CPU
Release R20|Any CPU = Release R20|Any CPU
Expand Down Expand Up @@ -55,6 +58,8 @@ Global
{C872CDA2-93F5-4681-BD2F-207EACF83D2E}.Release R24|Any CPU.Build.0 = Release R24|Any CPU
{C872CDA2-93F5-4681-BD2F-207EACF83D2E}.Release R25|Any CPU.ActiveCfg = Release R25|Any CPU
{C872CDA2-93F5-4681-BD2F-207EACF83D2E}.Release R25|Any CPU.Build.0 = Release R25|Any CPU
{C872CDA2-93F5-4681-BD2F-207EACF83D2E}.Debug R25|Any CPU.ActiveCfg = Debug R25|Any CPU
{C872CDA2-93F5-4681-BD2F-207EACF83D2E}.Debug R25|Any CPU.Build.0 = Debug R25|Any CPU
{E3C87D34-638C-47A0-A73A-D967B119458D}.Debug R22|Any CPU.ActiveCfg = Debug|Any CPU
{E3C87D34-638C-47A0-A73A-D967B119458D}.Debug R23|Any CPU.ActiveCfg = Debug|Any CPU
{E3C87D34-638C-47A0-A73A-D967B119458D}.Debug R24|Any CPU.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -90,6 +95,9 @@ Global
{1661572C-EF3A-4DD6-83BD-CB4239CE8CDD}.Release R23|Any CPU.ActiveCfg = Release R23|Any CPU
{1661572C-EF3A-4DD6-83BD-CB4239CE8CDD}.Release R24|Any CPU.ActiveCfg = Release R24|Any CPU
{1661572C-EF3A-4DD6-83BD-CB4239CE8CDD}.Release R25|Any CPU.ActiveCfg = Release R25|Any CPU
{1661572C-EF3A-4DD6-83BD-CB4239CE8CDD}.Release R25|Any CPU.Build.0 = Release R25|Any CPU
{1661572C-EF3A-4DD6-83BD-CB4239CE8CDD}.Debug R25|Any CPU.ActiveCfg = Release R25|Any CPU
{1661572C-EF3A-4DD6-83BD-CB4239CE8CDD}.Debug R25|Any CPU.Build.0 = Release R25|Any CPU
{21460D85-C4AD-49D5-963F-CF13C4AE99EB}.Debug R22|Any CPU.ActiveCfg = Debug R22|Any CPU
{21460D85-C4AD-49D5-963F-CF13C4AE99EB}.Debug R22|Any CPU.Build.0 = Debug R22|Any CPU
{21460D85-C4AD-49D5-963F-CF13C4AE99EB}.Installer|Any CPU.ActiveCfg = Debug R22|Any CPU
Expand All @@ -112,6 +120,8 @@ Global
{21460D85-C4AD-49D5-963F-CF13C4AE99EB}.Release R24|Any CPU.Build.0 = Release R24|Any CPU
{21460D85-C4AD-49D5-963F-CF13C4AE99EB}.Release R25|Any CPU.ActiveCfg = Release R25|Any CPU
{21460D85-C4AD-49D5-963F-CF13C4AE99EB}.Release R25|Any CPU.Build.0 = Release R25|Any CPU
{21460D85-C4AD-49D5-963F-CF13C4AE99EB}.Debug R25|Any CPU.ActiveCfg = Release R25|Any CPU
{21460D85-C4AD-49D5-963F-CF13C4AE99EB}.Debug R25|Any CPU.Build.0 = Release R25|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
59 changes: 58 additions & 1 deletion AddInManager/Command/AddinManagerBase.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
using System.IO;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using RevitAddinManager.Model;
using RevitAddinManager.ViewModel;
using System.Windows;
using static RevitAddinManager.App;

#if R25
using AssemblyLoadContext = RevitAddinManager.Model.AssemblyLoadContext;
using System.Runtime.Loader;
#endif

namespace RevitAddinManager.Command;

public sealed class AddinManagerBase
Expand All @@ -16,7 +23,12 @@ public Result ExecuteCommand(ExternalCommandData data, ref string message, Eleme
var vm = new AddInManagerViewModel(data, ref message, elements);
if (_activeCmd != null && faceless)
{
#if R19 || R20 || R21 || R22 || R23 || R24
return RunActiveCommand(vm, data, ref message, elements);
#else
return RunActiveCommand(data, ref message, elements);
#endif

}
FrmAddInManager = new View.FrmAddInManager(vm);
FrmAddInManager.SetRevitAsWindowOwner();
Expand Down Expand Up @@ -75,6 +87,51 @@ public Result RunActiveCommand(AddInManagerViewModel vm, ExternalCommandData dat
return result;
}

#if R25
public Result RunActiveCommand(ExternalCommandData data, ref string message, ElementSet elements)
{
var filePath = _activeCmd.FilePath;
if (!File.Exists(filePath))
{
MessageBox.Show("File not found: " + filePath,DefaultSetting.AppName, MessageBoxButton.OK, MessageBoxImage.Error);
return 0;
}
Result result = Result.Failed;
var alc = new AssemblyLoadContext(filePath);
try
{
var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
Assembly assembly = alc.LoadFromStream(stream);
object instance = assembly.CreateInstance(_activeCmdItem.FullClassName);
WeakReference alcWeakRef = new WeakReference(alc, trackResurrection: true);
if (instance is IExternalCommand externalCommand)
{
_activeEc = externalCommand;
result = _activeEc.Execute(data, ref message, elements);
alc.Unload();
}
int counter = 0;
for (counter = 0; alcWeakRef.IsAlive && (counter < 10); counter++)
{
alc = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
stream.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
result = Result.Failed;
}
finally
{
alc = null;
}
return result;
}
#endif

public static AddinManagerBase Instance
{
get
Expand Down
48 changes: 48 additions & 0 deletions AddInManager/Model/AssemblyLoadContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#if R25
using System.IO;
using System.Reflection;
using System.Runtime.Loader;

namespace RevitAddinManager.Model;

class AssemblyLoadContext : System.Runtime.Loader.AssemblyLoadContext
{
public AssemblyLoadContext() : base(isCollectible: true)
{
}
private AssemblyDependencyResolver _resolver;

public AssemblyLoadContext(string pluginPath): base(isCollectible: true)
{
_resolver = new AssemblyDependencyResolver(pluginPath);
}

protected override Assembly Load(AssemblyName assemblyName)
{
string assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
if (assemblyPath != null)
{
if(assemblyPath.Contains("RevitAPI"))
{
return null;
}
var stream = new FileStream(assemblyPath, FileMode.Open, FileAccess.Read);
return LoadFromStream(stream);
}

return null;
}

protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
{
string libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName);
if (libraryPath != null)
{
return LoadUnmanagedDllFromPath(libraryPath);
}

return IntPtr.Zero;
}

}
#endif
4 changes: 4 additions & 0 deletions AddInManager/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
"commandName": "Executable",
"executablePath": "C:\\Program Files\\Autodesk\\Revit 2024\\Revit.exe"
} ,
"Revit2025": {
"commandName": "Executable",
"executablePath": "C:\\Program Files\\Autodesk\\Revit 2025\\Revit.exe"
} ,
"RevitPreview": {
"commandName": "Executable",
"executablePath": "C:\\Program Files\\Autodesk\\Revit Preview Release\\Revit.exe"
Expand Down
9 changes: 7 additions & 2 deletions AddInManager/RevitAddinManager.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<PlatformTarget>x64</PlatformTarget>
<ImplicitUsings>true</ImplicitUsings>
<UseWindowsForms>false</UseWindowsForms>
<Configurations>Debug R22;Debug R23;Debug R24</Configurations>
<Configurations>Debug R22;Debug R23;Debug R24;Debug R25</Configurations>
<Configurations>$(Configurations);Release R25;Release R19;Release R20;Release R21;Release R22;Release R23;Release R24</Configurations>
</PropertyGroup>
<PropertyGroup Condition="$(Configuration.Contains('Debug'))">
Expand Down Expand Up @@ -52,6 +52,7 @@
<RevitVersion>2025</RevitVersion>
<DefineConstants>$(DefineConstants);R25</DefineConstants>
<TargetFramework>net8.0-windows</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading>
</PropertyGroup>
<PropertyGroup>
<Version>$(RevitVersion)</Version>
Expand Down Expand Up @@ -129,7 +130,11 @@
<ItemGroup>
<ProjectReference Include="..\RevitElementBipChecker\RevitElementBipChecker.csproj" />
</ItemGroup>

<PropertyGroup>
<StartAction>Program</StartAction>
<StartProgram>C:\Program Files\Autodesk\Revit $(RevitVersion)\Revit.exe</StartProgram>
<StartArguments>/language ENG</StartArguments>
</PropertyGroup>
<Target Name="CopyFiles" AfterTargets="CoreBuild">
<ItemGroup>
<RootItem Include="$(ProjectDir)*.addin" />
Expand Down
4 changes: 4 additions & 0 deletions AddInManager/ViewModel/AddInManagerViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,11 @@ public void ExecuteAddinCommandClick()
private void Execute()
{
string message = Message;
#if R19 || R20 || R21 || R22 || R23 || R24
MAddinManagerBase.RunActiveCommand(this, ExternalCommandData, ref message, Elements);
#else
MAddinManagerBase.RunActiveCommand(ExternalCommandData, ref message, Elements);
#endif
}

private void OpenLcAssemblyCommandClick()
Expand Down
8 changes: 7 additions & 1 deletion Test/Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
<LangVersion>latest</LangVersion>
<IsPackable>false</IsPackable>
<PlatformTarget>x64</PlatformTarget>
<Configurations>Debug R21;Debug R22;Debug R23;Debug R24;</Configurations>
<UseWpf>true</UseWpf>
<Configurations>Debug R21;Debug R22;Debug R23;Debug R24;Debug R25;</Configurations>
<Configurations>$(Configurations)Release R25;Release R19;Release R20;Release R21;Release R22;Release R23;Release R24</Configurations>
</PropertyGroup>
<PropertyGroup Condition="$(Configuration.Contains('R19'))">
Expand Down Expand Up @@ -35,6 +36,8 @@
</PropertyGroup>
<PropertyGroup Condition="$(Configuration.Contains('R25'))">
<RevitVersion>2025</RevitVersion>
<TargetFramework>net8.0-windows</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading>
<DefineConstants>$(DefineConstants);R25</DefineConstants>
</PropertyGroup>
<PropertyGroup>
Expand All @@ -54,5 +57,8 @@
<ItemGroup>
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Test2\Test2.csproj" />
</ItemGroup>

</Project>
6 changes: 1 addition & 5 deletions Test/TestCommand.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Interop;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
Expand Down Expand Up @@ -166,7 +162,7 @@ public Result Execute(ExternalCommandData commandData, ref string message, Eleme
Debug.WriteLine($"Add: This is a add");
Debug.WriteLine($"Modify: This is a modify");
Debug.WriteLine($"Delete: This is a delete");
TraceListenerCollection traceListenerCollection = Debug.Listeners;
TraceListenerCollection traceListenerCollection = Trace.Listeners;
return Result.Succeeded;
}
}
Expand Down
11 changes: 7 additions & 4 deletions Test/TestEvaCommand.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System.Windows;
using System;
using System.Windows;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Test2;

namespace Test;

Expand All @@ -10,9 +12,10 @@ public class TestEvaCommand : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{

UIApplication uiApplication = commandData.Application;
MessageBox.Show(uiApplication.Application.Username);
MessageBox.Show("TestEvaCommand");
// string? value = DependLib.ShowDialogFolder();
// Console.WriteLine(value);
// MessageBox.Show(value.ToString());
return Result.Succeeded;
}
}
24 changes: 24 additions & 0 deletions Test2/DependLib.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace Test2
{
public static class DependLib
{
public static double Plus()
{
return 2 + 10;
}

public static string? ShowDialogFolder()
{
//ookii-dialogs-wpf
var dialog = new Ookii.Dialogs.Wpf.VistaFolderBrowserDialog();
dialog.Description = "Select a folder";
dialog.UseDescriptionForTitle = true;
dialog.ShowNewFolderButton = true;
if (dialog.ShowDialog() == true)
{
return dialog.SelectedPath;
}
return null;
}
}
}
39 changes: 39 additions & 0 deletions Test2/Test2.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net48</TargetFramework>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<PlatformTarget>x64</PlatformTarget>
<UseWpf>true</UseWpf>
</PropertyGroup>
<PropertyGroup Condition="$(Configuration.Contains('Debug'))">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<DefineConstants>$(DefineConstants);DEBUG</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$(Configuration.Contains('Release'))">
<Optimize>true</Optimize>
<DebugType>none</DebugType>
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants>
</PropertyGroup>
<PropertyGroup>
<Version>$(RevitVersion)</Version>
<EnableDynamicLoading>true</EnableDynamicLoading>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<Description>A Project Support for developer in revit </Description>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.7" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.7" />
<PackageReference Include="coverlet.collector" Version="3.1.0" />
<PackageReference Include="Chuongmep.Revit.Api.RevitAPI" Version="$(RevitVersion).*" />
<PackageReference Include="Chuongmep.Revit.Api.RevitAPIUI" Version="$(RevitVersion).*" />
<PackageReference Include="Ookii.Dialogs.Wpf" Version="5.0.1" />
</ItemGroup>
<ItemGroup>
<Reference Include="PresentationFramework" />
</ItemGroup>

</Project>
5 changes: 4 additions & 1 deletion build/Build.csproj.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ANONYMOUSMETHOD_ON_SINGLE_LINE/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=4a98fdf6_002D7d98_002D4f5a_002Dafeb_002Dea44ad98c70c/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=f9fce829_002De6f4_002D4cb2_002D80f1_002D5497c44f51df/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
Expand All @@ -25,4 +27,5 @@
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

0 comments on commit 2d8366b

Please sign in to comment.