将单个 .xaml 文件添加到解决方案时,VSTO 外接程序不再编译
VSTO Add-in doesn't compile anymore when a single .xaml file is added to the solution
让我们考虑一个 Excel VSTO 加载项并在其中添加一个 class,如下所示:
public class SomeClass
{
public Range GetCell(Worksheet worksheet)
{
return worksheet.Cells[1, 1];
}
}
编译吧;即使它什么都不做,它也能工作。
现在,将 UserControl (WPF) 添加到项目中,而不引用或使用它:只需添加该项目。
如果您重新编译,您将收到错误消息:
CS0266 Cannot implicitly convert type 'object' to 'Microsoft.Office.Interop.Excel.Range'. An explicit conversion exists (are you missing a cast?)
指成员Cells[1,1]
的返回类型。
注意!如果您不将 "Build Only" 放入此处显示的框中,有时错误甚至不会出现。
似乎禁用了有关动态的功能...但是为什么呢?
可能的解决方案
在需要时进行类型转换仍然是可行的,事实上这是可行的:
return (Range)worksheet.Cells[1, 1];
问题在于 office 对象模型已经相当冗长并且严重依赖于动态。这意味着在实际应用程序中,您将需要很多 此类类型转换,最终每行都有一堆类型转换。
更不用说这个问题可能表明某处发生了非常错误的事情,所以我宁愿解决这个问题也不愿诉诸类型转换作为解决方法。
我在 VS2017 上使用 VSTO Add-in 2010 和 VSTO Add-in 2013-16 测试了这个,结果相同。 .NET Framework 4.7.2.
请禁用并启用 excel 的互操作类型,它将解决问题。
完整的库名称,如项目参考中所示:Microsoft.Office.Interop.Excel
禁用然后启用的选项是引用属性中的嵌入互操作类型。
我遇到了同样的问题,但在我的例子中,我将一个额外的 XAML 文件添加到已经有其他 .xaml 文件的 VSTO 项目中。潜在问题显然是来自 VSTO 项目模板的潜在问题:
<Reference Include="Office, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">
<Private>False</Private>
<EmbedInteropTypes>true</EmbedInteropTypes>
</Reference>
<Reference Include="Microsoft.Office.Interop.Excel, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">
<Private>False</Private>
<EmbedInteropTypes>true</EmbedInteropTypes>
</Reference>
在 .csproj 中将 EmbedInteropTypes
的值从 true
更改为 True
修复了编译问题。这是通过在参考属性中将嵌入互操作类型更改为 False 并再次返回 True 来实现的。
我只需要为 Excel 参考执行此操作即可让项目再次编译,但请注意它在 Office 参考上也是错误的。
在我的例子中,似乎几乎可以肯定的是,这个问题与我的 XAML 文件的根元素是 Application
(如 System.Windows.Application
)这一事实有关还有接口 Microsoft.Windows.Interop.Excel.Application
.
让我们考虑一个 Excel VSTO 加载项并在其中添加一个 class,如下所示:
public class SomeClass
{
public Range GetCell(Worksheet worksheet)
{
return worksheet.Cells[1, 1];
}
}
编译吧;即使它什么都不做,它也能工作。 现在,将 UserControl (WPF) 添加到项目中,而不引用或使用它:只需添加该项目。 如果您重新编译,您将收到错误消息:
CS0266 Cannot implicitly convert type 'object' to 'Microsoft.Office.Interop.Excel.Range'. An explicit conversion exists (are you missing a cast?)
指成员Cells[1,1]
的返回类型。
注意!如果您不将 "Build Only" 放入此处显示的框中,有时错误甚至不会出现。
似乎禁用了有关动态的功能...但是为什么呢?
可能的解决方案
在需要时进行类型转换仍然是可行的,事实上这是可行的:
return (Range)worksheet.Cells[1, 1];
问题在于 office 对象模型已经相当冗长并且严重依赖于动态。这意味着在实际应用程序中,您将需要很多 此类类型转换,最终每行都有一堆类型转换。
更不用说这个问题可能表明某处发生了非常错误的事情,所以我宁愿解决这个问题也不愿诉诸类型转换作为解决方法。
我在 VS2017 上使用 VSTO Add-in 2010 和 VSTO Add-in 2013-16 测试了这个,结果相同。 .NET Framework 4.7.2.
请禁用并启用 excel 的互操作类型,它将解决问题。
完整的库名称,如项目参考中所示:Microsoft.Office.Interop.Excel 禁用然后启用的选项是引用属性中的嵌入互操作类型。
我遇到了同样的问题,但在我的例子中,我将一个额外的 XAML 文件添加到已经有其他 .xaml 文件的 VSTO 项目中。潜在问题显然是来自 VSTO 项目模板的潜在问题:
<Reference Include="Office, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">
<Private>False</Private>
<EmbedInteropTypes>true</EmbedInteropTypes>
</Reference>
<Reference Include="Microsoft.Office.Interop.Excel, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">
<Private>False</Private>
<EmbedInteropTypes>true</EmbedInteropTypes>
</Reference>
在 .csproj 中将 EmbedInteropTypes
的值从 true
更改为 True
修复了编译问题。这是通过在参考属性中将嵌入互操作类型更改为 False 并再次返回 True 来实现的。
我只需要为 Excel 参考执行此操作即可让项目再次编译,但请注意它在 Office 参考上也是错误的。
在我的例子中,似乎几乎可以肯定的是,这个问题与我的 XAML 文件的根元素是 Application
(如 System.Windows.Application
)这一事实有关还有接口 Microsoft.Windows.Interop.Excel.Application
.