Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VS won't open control since dll update

I've look in many places including google and SO but I didn't find any relevant answer.

I've made a few changes in my app recently, including updating ZedGraph dll (from 5.1.4.26270 to 5.1.6.405) and since, VS won't open my controls throwing this error:

Could not load file or assembly 'ZedGraph, Version=5.1.4.26270, Culture=neutral, PublicKeyToken=...' or one of its dependencies. The system cannot find the file specified.

Which point to the old version. I've look everywhere, I don't find any trace of this old version.

It also throw this error:

The variable 'lineGraphControl1' is either undeclared or was never assigned.

Whereas I call the constructor:

this.lineGraphControl1 = new Sakura.UI.Graphing.LineGraphControl();

I've try to:

  • Reboot
  • Clean and Rebluid
  • Start VS in admin mode
  • Remove the reference and re-add it

Without success.

How can I erase trace of the old ZedGraph lib and how can I fix this error?

Edit

Here's the changes between the old version and the new (old first)

<Reference Include="ZedGraph, Version=5.1.4.26270, Culture=neutral, PublicKeyToken=02a83cbd123fcd60, processorArchitecture=MSIL">
  <SpecificVersion>False</SpecificVersion>
  <HintPath>..\..\Lib\ZedGraph.dll</HintPath>
</Reference>

<Reference Include="ZedGraph, Version=5.1.6.405, Culture=neutral, PublicKeyToken=02a83cbd123fcd60, processorArchitecture=MSIL">
  <SpecificVersion>False</SpecificVersion>
  <HintPath>..\..\Lib\ZedGraph.dll</HintPath>
</Reference>

Edit 2

After clearing the cache of VS and rebooting the computer, the error message changed:

at System.ComponentModel.Design.Serialization.CodeDomDesignerLoader.EnsureDocument(IDesignerSerializationManager manager)
at System.ComponentModel.Design.Serialization.CodeDomDesignerLoader.PerformLoad(IDesignerSerializationManager manager)
at Microsoft.VisualStudio.Design.Serialization.CodeDom.VSCodeDomDesignerLoader.PerformLoad(IDesignerSerializationManager serializationManager)
at Microsoft.VisualStudio.Design.Serialization.CodeDom.VSCodeDomDesignerLoader.DeferredLoadHandler.Microsoft.VisualStudio.TextManager.Interop.IVsTextBufferDataEvents.OnLoadCompleted(Int32 fReload) 

I am lost.

Edit 3

I've search through the whole disk for the string 5.1.4.26270 and the only place found are not in the project.


csproj snippet :

<Reference Include="ZedGraph, Version=5.1.6.405, Culture=neutral, PublicKeyToken=02a83cbd123fcd60, processorArchitecture=MSIL">
  <SpecificVersion>False</SpecificVersion>
  <HintPath>..\..\Lib\ZedGraph.dll</HintPath>
</Reference>

Edit 4:

(After Hans Passant anwser)

Here's the LineGraphControl declaration:

public class LineGraphControl : GraphControl<Sakura.Graphing.LineGraph>

The LineGraph (which use ZedGraph objects)

public class LineGraph : Graph, ISerializable

The Graph:

[XmlInclude(typeof(StackedGraph))]
[XmlInclude(typeof(LineGraph))]
[XmlInclude(typeof(BubbleGraph))]
[XmlInclude(typeof(BatchGraph))]
[Serializable]
public abstract class Graph : ISerializable

Unfortunately the ZedGraph lib is to deeply linked to the software to change it to another one.

I won't rollback the changes because I've adapt the library in a way that make my software graphing 250% faster.

Here's the callstack of the tentative to open the LineGraphControl in VS:

at System.ComponentModel.Design.Serialization.CodeDomDesignerLoader.EnsureDocument(IDesignerSerializationManager manager)
at System.ComponentModel.Design.Serialization.CodeDomDesignerLoader.PerformLoad(IDesignerSerializationManager manager)
at Microsoft.VisualStudio.Design.Serialization.CodeDom.VSCodeDomDesignerLoader.PerformLoad(IDesignerSerializationManager serializationManager)
at System.ComponentModel.Design.Serialization.BasicDesignerLoader.BeginLoad(IDesignerLoaderHost host)

Here's the activity log

Error message when I try to create a new LineGraphControl:

enter image description here

The ProcMon extract:

enter image description here

like image 346
Thomas Ayoub Avatar asked Jan 14 '15 13:01

Thomas Ayoub


1 Answers

No code, no exception message, no hint what a "LineGraphControl" might be, you make it pretty difficult to help you. I took a look at the ZedGraph project to see what might get you into trouble like this.

No lack of that, there are rather a lot of problems with this control. The code shows very little evidence that the author understood design-time serialization. Lots of the properties that are visible in the Properties Window should not have been visible, are not editable (grayed out) and do accept edits but don't serialize. Some properties are correctly hidden, hinting that this was arrived at with trial and error.

Most severely, almost every single class in the project is binary-serializable. Either by the [Serializable] attribute or implementing ISerializable. But without any regard for version-independent serialization, the [AssemblyVersion] attribute changes for every single version of the control with the effective version number depending on the time of day that the assembly was built. This is what I found in the version I downloaded:

 [assembly: AssemblyVersion( "5.1.5.*" )]

That's the worst possible version strategy you could pick, it doesn't even guarantee a steadily increasing number. In particular lethal when you inherit your own control from ZedGraphControl and expose properties yourself, without the benefit of the author's trial and error approach. Winforms really likes classes that are serializable, it makes it easy to persist their objects at design time. But with the kind of outcome you describe when the assembly version changes, what was previously serialized cannot be deserialized anymore. Kaboom when you try to open the user control or the form that contains the control, Visual Studio cannot find the required assembly anymore.

And yes, that version number is hard to find back, it was embedded in a string inside a .resx file that's part of your project. Created by encoding the serialized bytes with Convert.ToBase64String(). That string is just a random blob of letters, you cannot recognize the version number from it.

So specific advice:

  • Once bitten, twice shy, using this control is a huge liability. Consider something else, the .NET Framework Chart control is fairly decent.
  • Give up on the updated version and restore the original, the simplest fix of course.
  • Check-in the source of the control and add it to the solution. Edit the AssemblyInfo.cs file and hard-code "5.1.4.26270" in the [AssemblyVersion] attribute.
  • That ought to help a lot but is not a guarantee that the previously serialized data can still be deserialized, the class might have changed. You then need to dig through the .resx files of your user control and the forms that use it and look for the Base64 strings. Write a little program that decodes the string to double-check that you found the correct one. And delete the entry from the .resx file.
  • If that doesn't pan out either then you have to edit the Designer.cs file(s) by hand. Delete any statement that references the control. You should then be able to open it in design-mode and add the control back.
like image 103
2 revs Avatar answered Oct 18 '22 18:10

2 revs