T4使用DTE打开生成的文件时,Visual Studio序列化错误
作者:互联网
我们有一个名为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已在
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);
标签:visual-studio-2015,t4,envdte,c 来源: https://codeday.me/bug/20191026/1936668.html