自 dll 更新后 VS 无法打开控件

VS won't open control since dll update

我查看了很多地方,包括 google 和 SO,但没有找到任何相关答案。

我最近对我的应用程序进行了一些更改,包括更新 ZedGraph dll(从 5.1.4.26270 到 5.1.6.405),因为 VS 不会打开我的控件并引发此错误:

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.

其中指向旧版本。我到处找了找,没找到这个旧版本的任何痕迹。

它也会抛出这个错误:

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

而我调用构造函数:

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

我尝试过:

没有成功。

如何清除旧 ZedGraph 库的痕迹以及如何修复此错误?

编辑

这是新旧版本的变化(旧的优先)

<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>

编辑 2

清除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 Microsoft.VisualStudio.Design.Serialization.CodeDom.VSCodeDomDesignerLoader.DeferredLoadHandler.Microsoft.VisualStudio.TextManager.Interop.IVsTextBufferDataEvents.OnLoadCompleted(Int32 fReload) 

我迷路了。

编辑 3

我在整个磁盘中搜索字符串 5.1.4.26270,唯一找到的地方不在项目中。


csproj 片段:

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

编辑 4:

(在 Hans Passant 回答之后)

这是 LineGraphControl 声明:

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

线图(使用 ZedGraph 对象)

public class LineGraph : Graph, ISerializable

图表:

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

不幸的是,ZedGraph 库与软件深度链接以将其更改为另一个。

我不会回滚更改,因为我已经调整了库,使我的软件绘图速度提高了 250%。

这里是尝试在VS中打开LineGraphControl的调用栈:

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

当我尝试创建一个新的 LineGraphControl 时出现错误消息:

ProcMon 提取物:

您的项目中的另一个依赖项可能仍然专门引用旧版本的程序集。

定义Sakura.UI.Graphing.LineGraphControl的assembly/DLL怎么样?

没有代码,没有异常消息,没有提示 "LineGraphControl" 可能是什么,你很难帮助你。我查看了 ZedGraph 项目,看看有什么 可能 让你陷入这样的麻烦。

不乏,这个控件问题比较多。该代码几乎没有显示出作者理解设计时序列化的证据。属性 Window 中可见的许多属性不应该是可见的,不可编辑(变灰)并且接受编辑但不序列化。一些属性被正确隐藏,暗示这是通过反复试验得出的。

最严重的是,项目中几乎每个 class 都是可二进制序列化的。通过 [Serializable] 属性或实现 ISerializable。但是,在不考虑与版本无关的序列化的情况下,[AssemblyVersion] 属性会随着控件的每个版本而变化,其有效版本号取决于一天中构建程序集的时间。这是我在下载的版本中找到的:

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

这是您可以选择的最糟糕的版本策略,它甚至不能保证数量稳定增长。当您从 ZedGraphControl 继承您自己的控件并自己公开属性,而没有受益于作者的反复试验方法时,这尤其致命。 Winforms 非常喜欢可序列化的 classes,这使得在设计时持久保存它们的对象变得容易。但是随着程序集版本更改时您描述的那种结果,以前序列化的内容不能再反序列化了。 Kaboom 当您尝试打开用户控件或包含该控件的窗体时,Visual Studio 无法再找到所需的程序集。

是的,该版本号很难找回,它嵌入在作为项目一部分的 .resx 文件内的字符串中。通过使用 Convert.ToBase64String() 对序列化字节进行编码创建。该字符串只是一串随机字母,您无法从中识别版本号。

所以具体建议:

  • 一次被咬,两次害羞,使用这种控制是一种巨大的负担。考虑别的东西,.NET Framework Chart 控件相当不错。
  • 放弃更新版本,恢复原版,当然是最简单的修复。
  • 签入控件源并将其添加到解决方案中。编辑 AssemblyInfo.cs 文件并在 [AssemblyVersion] 属性中硬编码“5.1.4.26270”。
  • 这应该会有很大帮助,但不能保证以前序列化的数据仍然可以反序列化,class 可能已经改变了。然后,您需要深入了解用户控件的 .resx 文件和使用它的表单,并查找 Base64 字符串。编写一个解码字符串的小程序,以仔细检查您是否找到了正确的字符串。并从 .resx 文件中删除该条目。
  • 如果还是不行,那么您必须手动编辑 Designer.cs 文件。删除任何引用该控件的语句。然后您应该能够在设计模式下打开它并添加回控件。

问题

错误是找不到文件like the one I helped out with the other day:

Could not load file or assembly .. The system cannot find the file specified.

疑难解答

打开 ProcessMonitor 和 运行 当 VS 不允许您打开控件并抛出错误时。失败时停止跟踪并调查 ProcMon (Filemon) 日志以查看 IDE 在哪里寻找它找不到的 DLL。

解决方案

将 DLL 放在预期的位置(这有望解决 VS 库引用失败)。


进程监视器帮助在 Resharper 插件目录中发现了 ZedGraph.dll 的奇怪引用。我已按照以下步骤操作:

  1. 禁用 Resharper
  2. 重启VS
  3. 清理并重建
  4. 再次启用 Resharper
  5. 微笑