.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SerializationException Only Affecting AutoCAD 2015 SP2

3 REPLIES 3
SOLVED
Reply
Message 1 of 4
kbrown
921 Views, 3 Replies

SerializationException Only Affecting AutoCAD 2015 SP2

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.

3 REPLIES 3
Message 2 of 4
artc2
in reply to: kbrown

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.

Message 3 of 4
kbrown
in reply to: artc2

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.

 

Message 4 of 4
artc2
in reply to: kbrown

Unfortunately, I don't know enough to be able to answer your question.  Hopefully someone else can.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost