我们有一个名为 GenerateProxies.tt 的 C# T4 文件,它调用多个命令行代码生成实用程序。使用 System.Diagnostics Process 类,我们将标准输出重定向到 T4 输出文本文件 (GenerateProxies.txt),以便我们可以检查命令行输出是否有错误。
我在 T4 的末尾添加了以下简单代码,以便 Visual Studio 将打开生成的文本文件作为该过程的最后一步(workingDirectory
变量在模板)。这确实有效,但会引发序列化错误。这个错误可以避免吗?
<#@ assembly name="EnvDTE" #>
<#@ import namespace="EnvDTE" #>
<#
IServiceProvider vssp = (IServiceProvider)this.Host;
DTE dte = vssp.GetService(typeof(DTE)) as DTE;
dte.ItemOperations.OpenFile(
string.Format(@"{0}\GenerateProxies.txt", workingDirectory),
Constants.vsViewKindTextView
);
#>
同样,这确实有效,它打开了文本文件,但它产生了这个错误:
Running transformation: System.Runtime.Serialization.SerializationException:
Type 'Microsoft.VisualStudio.Platform.WindowManagement.DTE.WindowBase' in
Assembly 'Microsoft.VisualStudio.Platform.WindowManagement'
is not marked as serializable.
最佳答案
EnvDTE 程序集是 COM 互操作程序集。通过创建 Runtime Callable Wrapper 可以避免您的错误,它根据互操作程序集中的信息编码对 COM 对象的调用。微软在
Microsoft.VisualStudio.TextTemplating
命名空间:
<#@ template hostspecific="true" language="C#" #>
<#@ assembly name="EnvDTE" #>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
<#
IServiceProvider serviceProvider = (IServiceProvider)this.Host;
EnvDTE.DTE dte = (EnvDTE.DTE) serviceProvider.GetCOMService(typeof(EnvDTE.DTE));
#>
T4 模板在单独的 AppDomain 中运行,我相信这就是您的代码在异常情况下仍能正常工作的原因。 IServiceProvider.GetService(typeof(DTE))
返回一个透明的 Proxy Object .此异常是因为代理要求跨应用程序域的对象使用 Serializable
属性进行修饰。您可以确认代码中的 DTE 对象是这样的“透明代理”:
bool isProxy = RemotingServices.IsTransparentProxy(dte);
关于c# - T4 使用 DTE 打开生成的文件时出现 Visual Studio 序列化错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41000524/