c# - T4 使用 DTE 打开生成的文件时出现 Visual Studio 序列化错误

标签 c# visual-studio-2015 t4 envdte

我们有一个名为 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/

相关文章:

c# - mailItem.PropertyChange 停止触发

c# - ASP.NET MVC5 Entity Framework 应用程序中的单一上下文

entity-framework - 将自定义数据源添加到 visual studio 2015

razor - 为什么在 razor cshtml 文件中进行更改时需要重建整个解决方案

asp.net-mvc - 服务/存储库模式的 MvcScaffolding?

visual-studio - 如何解决此错误 : Loading the include file 'EF.Utility.CS.ttinclude' returned a null or empty string

c# - Elasticsearch/Nest-使用MultiMatch TextQueryType.Phrase和通配符

c# - .NET : Monitoring Objects Lifetime (Birth/Death/Memory)

visual-studio - 像片段一样插入 T4 生成的代码

MySQL' 未被识别为内部或外部命令 - VS2015 中的 Cordova