Skip to content

Commit 2d8e3f1

Browse files
committed
fix #13
- Add CopyLocalLockFileAssemblies to allow lock assembly can copy to output folder - Add load context to match with .net 8
1 parent b2ea00b commit 2d8e3f1

File tree

4 files changed

+124
-1
lines changed

4 files changed

+124
-1
lines changed

CadAddinManager/CadAddinManager.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
<CADTrimVersion>25</CADTrimVersion>
4444
<TargetFramework>net8.0-windows</TargetFramework>
4545
<DefineConstants>$(DefineConstants);A25</DefineConstants>
46+
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
4647
</PropertyGroup>
4748

4849
<PropertyGroup>
@@ -132,7 +133,7 @@
132133
<PackageReference Include="Chuongmep.Acad.Api.AdWindows" Version="$(CADVersion).*">
133134
<ExcludeAssets>runtime </ExcludeAssets>
134135
</PackageReference>
135-
<PackageReference Include="Mono.Cecil" Version="0.11.4" />
136+
<PackageReference Include="Mono.Cecil" Version="0.11.4"/>
136137
</ItemGroup>
137138
<PropertyGroup>
138139
<StartAction>Program</StartAction>

CadAddinManager/Command/AddinManagerBase.cs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using CadAddinManager.Model;
99
using CadAddinManager.View;
1010
using CadAddinManager.ViewModel;
11+
using RevitAddinManager.Model;
1112
using Application = Autodesk.AutoCAD.ApplicationServices.Core.Application;
1213
using Exception = System.Exception;
1314
using MessageBox = System.Windows.MessageBox;
@@ -39,7 +40,74 @@ public string ActiveTempFolder
3940
}
4041

4142

43+
#if A25
4244
public void RunActiveCommand()
45+
{
46+
AssemLoader assemLoader = new AssemLoader();
47+
var filePath = _activeCmd.FilePath;
48+
if (!File.Exists(filePath))
49+
{
50+
MessageBox.Show("File not found: " + filePath, DefaultSetting.AppName, MessageBoxButton.OK,
51+
MessageBoxImage.Error);
52+
return;
53+
}
54+
var alc = new AssemblyLoadContext(filePath);
55+
Stream stream = null;
56+
try
57+
{
58+
59+
60+
stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
61+
Assembly assembly = alc.LoadFromStream(stream);
62+
//var assembly = assemLoader.LoadAddinsToTempFolder(filePath, false);
63+
WeakReference alcWeakRef = new WeakReference(alc, trackResurrection: true);
64+
Type[] types = assembly.GetTypes();
65+
foreach (Type type in types)
66+
{
67+
List<MethodInfo> methodInfos = type.GetMethods().ToList();
68+
foreach (MethodInfo methodInfo in methodInfos)
69+
{
70+
CommandMethodAttribute commandAtt = (CommandMethodAttribute)methodInfo
71+
.GetCustomAttributes(typeof(CommandMethodAttribute), false)
72+
.FirstOrDefault();
73+
string fullName = string.Join(".", methodInfo.DeclaringType.Name, methodInfo.Name);
74+
if (commandAtt != null && fullName == Instance.ActiveCmdItem.FullClassName)
75+
{
76+
Invoke(methodInfo);
77+
alc.Unload();
78+
}
79+
}
80+
}
81+
int counter = 0;
82+
for (counter = 0; alcWeakRef.IsAlive && (counter < 10); counter++)
83+
{
84+
alc = null;
85+
GC.Collect();
86+
GC.WaitForPendingFinalizers();
87+
}
88+
stream.Close();
89+
}
90+
catch (Exception e)
91+
{
92+
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(e.ToString());
93+
alc?.Unload();
94+
WeakReference alcWeakRef = new WeakReference(alc, trackResurrection: true);
95+
for (int counter = 0; alcWeakRef.IsAlive && (counter < 10); counter++)
96+
{
97+
alc = null;
98+
GC.Collect();
99+
GC.WaitForPendingFinalizers();
100+
}
101+
stream?.Close();
102+
}
103+
// finally
104+
// {
105+
// assemLoader.UnhookAssemblyResolve();
106+
// assemLoader.CopyGeneratedFilesBack();
107+
// }
108+
}
109+
#else
110+
public void RunActiveCommand()
43111
{
44112
AssemLoader assemLoader = new AssemLoader();
45113
var filePath = _activeCmd.FilePath;
@@ -85,6 +153,8 @@ public void RunActiveCommand()
85153
assemLoader.CopyGeneratedFilesBack();
86154
}
87155
}
156+
#endif
157+
88158

89159
void Invoke(MethodInfo methodInfo)
90160
{
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#if A25
2+
using System.IO;
3+
using System.Reflection;
4+
using System.Runtime.Loader;
5+
6+
namespace RevitAddinManager.Model;
7+
8+
class AssemblyLoadContext : System.Runtime.Loader.AssemblyLoadContext
9+
{
10+
public AssemblyLoadContext() : base(isCollectible: true)
11+
{
12+
}
13+
private AssemblyDependencyResolver _resolver;
14+
15+
public AssemblyLoadContext(string pluginPath): base(isCollectible: true)
16+
{
17+
_resolver = new AssemblyDependencyResolver(pluginPath);
18+
}
19+
20+
protected override Assembly Load(AssemblyName assemblyName)
21+
{
22+
string assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
23+
if (assemblyPath != null)
24+
{
25+
if(assemblyPath.Contains("mgd"))
26+
{
27+
return null;
28+
}
29+
var stream = new FileStream(assemblyPath, FileMode.Open, FileAccess.Read);
30+
return LoadFromStream(stream);
31+
}
32+
33+
return null;
34+
}
35+
36+
protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
37+
{
38+
string libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName);
39+
if (libraryPath != null)
40+
{
41+
return LoadUnmanagedDllFromPath(libraryPath);
42+
}
43+
44+
return IntPtr.Zero;
45+
}
46+
47+
}
48+
#endif

CadAddinManager/Properties/launchSettings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
"Cad2024": {
1212
"commandName": "Executable",
1313
"executablePath": "C:\\Program Files\\Autodesk\\AutoCAD 2024\\acad.exe"
14+
},
15+
"Cad2025": {
16+
"commandName": "Executable",
17+
"executablePath": "C:\\Program Files\\Autodesk\\AutoCAD 2025\\acad.exe"
1418
}
1519
}
1620
}

0 commit comments

Comments
 (0)