My pluggin is not functioning fully in AutoCAD 2015 SP2. This issue does not exist in previous versions of 2015 (or 2013-1014). I have reproduced the issue on multiple machines. Removing the SP2 update causes my pluggin to function normally again.
Here is the exception and stack trace:
Exception Type: System.Runtime.Serialization.SerializationException
"Unable to find assembly 'Automotion.AutoPrice.Reporting, Version=1.0.0.30, Culture=neutral, PublicKeyToken=null'."
at System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo assemblyInfo, String name)
at System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped record)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
at Automotion.AutoPrice.Serialization.SerializationHelper.DeserializeEstimateDataSet(Byte[] Buffer) in C:\Users\kbrown\Documents\Visual Studio 2010\Projects\AutoPrice ACAD2013\ACAD2013\Automotion.AutoPrice.Serialization\SerializationHelper.vb:line 735
at Automotion.AutoPrice.AutoCAD.ACADEstimateModelAdapter.Fill(EstimateDataSet& DS) in C:\Users\kbrown\Documents\Visual Studio 2010\Projects\AutoPrice ACAD2013\ACAD2013\Automotion.AutoPrice.AutoCAD\ACADEstimateModelAdapter.vb:line 277
Why would such an exception occur in 2015 SP2 but not in previous versions? I am getting exceptions of the same type from other areas of my code base. All of the exceptions seem to indicate an assembly (not always the same one) could not be found and this caused the binary serializer to fail.
Thanks in advance.
Solved! Go to Solution.
Solved by artc2. Go to Solution.
This sounds like the same issue that was recently reported to us. In that case, the serialize code was in a secondary dll (i.e. not the dll loaded into Acad via NETLOAD) and that secondary dll was not located in the same directory as acad.exe. The secondary dll was not being explicitly loaded by the primary .net app dll - it was being implicitly loaded by the .NET runtime when needed by the primary dll. That's a scenario that was never intended to work without help from the primary .NET application in finding the secondary dll. It worked prior to AutoCAD 2015 SP2 because AutoCAD hooks the OnAssemblyResolve event and we had code in that event handler that just happened to find the secondary dll. That code was removed from our OnAssemblyResolve handler in SP2 because it was causing other problems.
If this sounds like the same situation that you have, then you could try hooking the OnAssemblyResolve event in your primary .NET app and have it return your secondary assembly.
The code that we had in our OnAssemblyResolve event that was finding the secondary dll was this:
Assembly^ ExtensionLoader::OnAssemblyResolve(Object^ sender, ResolveEventArgs^ e)
{
....
String^ shortName = (e->Name->Split(','))[0];
....
array<Assembly^>^ loadedAssemblies = AppDomain::CurrentDomain->GetAssemblies();
for each (Assembly^ assembly in loadedAssemblies)
{
String^ name1 = assembly->GetName()->Name;
if (String::Compare(shortName, name1, true) == 0)
return assembly;
}
....
This is managed C++ code. If you do something like the above, you should also check to see that the name is your secondary module and only return the assembly if it is. That way you will avoid the problem that caused us to remove that code.
Your suggestion seems to have resolved the problem.
I subscribed to the event (AppDomain.CurrentDomain.AssemblyResolve) in my implementation of IExtensionApplication.Initialize. I unsubscribe in IExtensionApplication.Terminate. Is there any reason I should subscribe to the event elsewhere?
Here is my event handler code for anyone else who has this issue:
Private Function OnAssemblyResolve(ByVal Sender As Object, ByVal e As ResolveEventArgs) As Assembly Dim shortName As String = e.Name.Split(",")(0) For Each assm As Assembly In AppDomain.CurrentDomain.GetAssemblies() Dim assmName As String = assm.GetName().Name If String.Compare(shortName, assmName, True) = 0 AndAlso String.Compare(assmName, "MyAssemblyNameHere", True) = 0 Then Return assm End If Next Return Nothing End Function
Note you should change "MyAssemblyNameHere" to the name of your assembly.