PAYATHON 2026

Infragistics 13.1 升级至 15.2 后出现编译错误

排障赵师傅

结论

这是程序集版本混用导致的错误。Shell.xaml.cs 传入的 XamDockManager 来自 InfragisticsWPF4.DockManager.v15.2.dll,而 IXamDockManagerInstance.setXamDockManagerInstance(...) 的参数类型仍指向 InfragisticsWPF4.DockManager.v13.1.dll。

虽然两个类型的命名空间和类名完全相同,但它们来自不同的强名称程序集,CLR 和 C# 编译器会将其视为不同类型,强制转换也无法解决。

整个解决方案及其依赖程序集需要统一引用 15.2。先检查定义 IXamDockManagerInstance 的项目或 DLL,它很可能仍是用 13.1 编译的。

为什么会出现看似矛盾的类型转换错误

错误信息中的两种类型表面上都是:

Infragistics.Windows.DockManager.XamDockManager

它们实际对应不同的程序集身份:

InfragisticsWPF4.DockManager.v13.1
InfragisticsWPF4.DockManager.v15.2

.NET 类型身份由命名空间、类型名及定义该类型的程序集共同决定。这里的两个类型可以理解为:

XamDockManager from InfragisticsWPF4.DockManager.v13.1.dll
XamDockManager from InfragisticsWPF4.DockManager.v15.2.dll

错误 6 已经指出,当前调用涉及的某个接口或程序集仍要求:

InfragisticsWPF4.DockManager.v13.1,
Version=13.1.20131.1009,
PublicKeyToken=7dd5c3163f2cd0cb

因此,计算机上安装了哪些 Infragistics 版本不会直接决定编译结果。编译时使用的是项目文件中的引用,以及已编译 DLL 元数据中记录的依赖关系。

先检查 IXamDockManagerInstance 的定义

检查范围不要局限于 Shell.xaml.cs,还要找到以下接口的定义:

Prism.Modules.Common.IXamDockManagerInstance

它可能类似于:

public interface IXamDockManagerInstance
{
    void setXamDockManagerInstance(
        Infragistics.Windows.DockManager.XamDockManager dockManager);
}

如果 Prism.Modules.Common 是当前解决方案中的项目,请检查它引用的 InfragisticsWPF4.DockManager 版本。

如果它是预编译 DLL,可以用 ILSpy、dotPeek、Visual Studio 对象浏览器或 ildasm 查看程序集引用。发现其中仍引用 InfragisticsWPF4.DockManager.v13.1 时,需要找到源项目并使用 15.2 重新编译。只替换应用程序项目中的 Infragistics 引用无法消除这个依赖。

搜索解决方案中的旧版本引用

关闭 Visual Studio 后,在解决方案目录中搜索:

InfragisticsWPF4.DockManager.v13.1
InfragisticsWPF4
13.1.20131.1009
Infragistics\2013.1

PowerShell 搜索命令如下:

Get-ChildItem -Recurse -File |
    Select-String -Pattern 'InfragisticsWPF4.*v13\.1|13\.1\.20131\.1009|Infragistics\\2013\.1'

重点检查以下文件:

*.csproj
*.vbproj
*.xaml
app.config
packages.config
licenses.licx

项目文件中的旧引用通常类似:

<Reference Include="InfragisticsWPF4.DockManager.v13.1">
  <HintPath>..\lib\InfragisticsWPF4.DockManager.v13.1.dll</HintPath>
</Reference>

删除旧引用,再通过 Visual Studio 添加对应的 15.2 DLL。更新后的项目文件应指向 15.2,例如:

<Reference Include="InfragisticsWPF4.DockManager.v15.2">
  <HintPath>C:\Program Files (x86)\Infragistics\2015.2\WPF\CLR4.0\Bin\InfragisticsWPF4.DockManager.v15.2.dll</HintPath>
  <Private>True</Private>
</Reference>

具体路径以本机安装位置或项目统一使用的第三方库目录为准,不要直接照搬示例路径。

检查项目引用是否退化成了 DLL 引用

大型解决方案中常见这样的组合:

  • Prism.ApplicationHost 引用 15.2;
  • Prism.Modules.Common 仍引用 13.1;
  • 主项目引用的是旧版 Prism.Modules.Common.dll,没有直接引用 Prism.Modules.Common 项目。

在 Visual Studio 的“引用”或“依赖项”中检查 Prism.Modules.Common:

  • 源项目已包含在当前解决方案中时,优先使用项目引用。
  • 如果引用指向某个 bin\Debug、bin\Release 或公共输出目录中的 DLL,确认它是否为升级前遗留的二进制文件。
  • 必须使用 DLL 时,其提供方需要先完成 15.2 升级并重新编译。

项目引用通常应类似:

<ProjectReference Include="..\Prism.Modules.Common\Prism.Modules.Common.csproj">
  <Project>{PROJECT-GUID}</Project>
  <Name>Prism.Modules.Common</Name>
</ProjectReference>

不要继续引用旧输出:

<Reference Include="Prism.Modules.Common">
  <HintPath>..\SomeOldOutput\Prism.Modules.Common.dll</HintPath>
</Reference>

按依赖顺序重新编译

迁移时从依赖链底部开始:

  1. 找出所有直接引用 Infragistics 的基础类库。
  2. 将这些类库统一升级到 15.2。
  3. 编译基础类库。
  4. 编译引用这些类库的 Prism 模块。
  5. 最后编译应用程序宿主项目。

针对当前错误,优先处理以下依赖关系:

Prism.Modules.Common
    ↓
Prism.ApplicationHost

如果 Prism.Modules.Common 的公共接口使用了 XamDockManager,调用方在编译时也必须解析到定义该参数类型的同一版本程序集。

清除旧的构建产物

修改引用后,关闭 Visual Studio,删除各项目中的以下目录:

bin
obj

同时检查解决方案是否使用了公共输出目录。例如:

<OutputPath>..\..\Build\Bin\</OutputPath>

如果存在这类配置,还要清理公共输出目录中的旧 DLL。无法确认用途的文件不要删除。

重新打开解决方案后执行:

Clean Solution
Rebuild Solution

如果 Visual Studio 仍显示旧引用,请删除该引用并重新添加。单独修改引用属性可能无法解决问题。

检查最终加载和复制的 DLL

编译前后都应检查输出目录,确认其中没有同时混入:

InfragisticsWPF4.DockManager.v13.1.dll
InfragisticsWPF4.DockManager.v15.2.dll

迁移完成后,应用程序输出目录通常不应同时存在这两个版本。还要检查各引用的 Path 属性,避免 Visual Studio 中显示的是 15.2,实际复制的 DLL 却来自旧的共享目录。

需要进一步排查时,可以使用 MSBuild 诊断日志追踪引用解析过程:

msbuild YourSolution.sln /t:Rebuild /v:diag > msbuild.log

然后在 msbuild.log 中搜索:

InfragisticsWPF4.DockManager
v13.1
13.1.20131.1009

日志通常会显示哪个项目请求了旧程序集,以及 MSBuild 最终从哪个路径解析该程序集。

不要用强制类型转换处理

下面的修改无法解决问题:

instance.setXamDockManagerInstance(
    (Infragistics.Windows.DockManager.XamDockManager)dockManager);

编译器看到的源类型和目标类型来自两个不同的程序集,两者之间没有继承关系,也不存在合法的引用转换。使用反射、dynamic 或序列化绕过同样不合适,只会掩盖依赖版本尚未统一的问题。

应当重新编译接口及其实现,让方法参数和调用方使用同一个 15.2 类型。

Binding Redirect 通常不适用于这个错误

app.config 中的程序集绑定重定向主要影响运行时程序集加载。当前问题发生在编译期,而且 Infragistics 的程序集名称带有版本后缀:

InfragisticsWPF4.DockManager.v13.1
InfragisticsWPF4.DockManager.v15.2

这通常表示它们是名称不同的程序集,并非同名程序集使用了不同的 AssemblyVersion。绑定重定向无法代替旧类库的重新编译。

只有当程序集名称相同、厂商明确支持重定向,而且错误发生在运行时加载阶段,才适合考虑 binding redirect。当前错误不足以支持这种处理方式。

建议的处理顺序

按以下顺序排查:

  1. 定位 IXamDockManagerInstance 定义所在的项目或 DLL。
  2. 检查该项目或 DLL 是否依赖 InfragisticsWPF4.DockManager.v13.1。
  3. 搜索整个解决方案中的 v13.1、旧 HintPath 和旧版本号。
  4. 将所有直接依赖 Infragistics 的项目统一升级到 15.2。
  5. 将可以使用项目引用的旧 DLL 引用改为项目引用。
  6. 清理所有 bin、obj 以及公共输出目录中的旧构建产物。
  7. 从基础类库开始,按依赖顺序重新编译。
  8. 使用 MSBuild 诊断日志定位仍在请求 13.1 的项目。

卸载 Infragistics 13.1 不会修改项目文件或 DLL 元数据中已经写入的引用。整条项目依赖链都使用 15.2 重新编译后,迁移才能完成。

备注:内容仅供参考。