VS2022 17.2.0 Preview 2.0: T4 template serialization exception when accessing projects, etc
Asked Answered
K

1

10

Using VS2022 17.2.0 Preview 2.0 to generate data layer using T4 templates. Part of the T4 uses VS interop / DTE to access projects in solution.

The following T4 is a test:

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="Microsoft.VisualStudio.Shell.Interop"#>
<#@ import namespace="Microsoft.VisualStudio.Shell"#>
<#@ import namespace="Microsoft.VisualStudio.Shell.Interop"#>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="EnvDTE80" #>
<#@ output extension=".txt" #>
<#

var hostServiceProvider = Host as IServiceProvider;
var dte = hostServiceProvider.GetService(typeof(DTE)) as DTE2;

foreach (Project project in dte.Solution)
{
    #><#= project.Name #>
    <#
}
#>

This produces following exception:

Error       Running transformation: System.Runtime.Serialization.SerializationException: Type 'Microsoft.VisualStudio.CommonIDE.Solutions.CMiscProject' in Assembly 'Microsoft.VisualStudio.CommonIDE, Version=17.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' is not marked as serializable.

Issue did not exist in Preview 1.0 or in VS2019.

I have had a look around and pulled in nuget package for Microsoft.VisualStudio.Interop, version 17.1.32210.191, but problem persists when accessing anything through the EnvDTE.DTE(2).

I know I'm jumping the gun on this as it is a preview version, but has anyone had this issue and solved it? Is there a different approach needed to access projects in the solution from the T4 template?

The error does not occur when debugging the T4 template.

Kiruna answered 22/3, 2022 at 16:10 Comment(2)
I have the same error appearing in VS2019 - though I'm setting up my T4 templates in a .NET Standard 2.0 project where they were previously in a .NET framework project. Have you had any joy with your issue? I tried adding [Serializable] attributes to all the generated classes in the file and it worked on the initial save after doing that, but not since (unless run in debug).Salesgirl
No luck. I submitted issue to Microsoft and it simply says under investigation. The serialization error I'm receiving is from within the libraries so I can't add an attribute to that. Unless I'm totally misunderstanding the error message and it's all my fault somewhere.Kiruna
S
22

I had a bit of a play (and a lot of a Google) and found the following solved it for me under VS 2022:

Ensure you have the following assemblies and namespaces

<#@ assembly name="Microsoft.VisualStudio.Interop" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="EnvDTE80" #>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>

and then swap out the IServiceProvider's GetService for GetCOMService

//var dte = hostServiceProvider.GetService(typeof(DTE)) as DTE2;
var dte = hostServiceProvider.GetCOMService(typeof(DTE)) as DTE2;

Mostly from answer here: https://mcmap.net/q/1043891/-visual-studio-serialization-error-when-t4-uses-dte-to-open-generated-file

Salesgirl answered 11/4, 2022 at 4:34 Comment(4)
Just tried it out and this fixes it. Thank you! I'll have a look at my other T4 includes and see where I need to apply the same approach for other calls.Kiruna
Glad it helped, since your post started me looking for the right things to fix my own instance of the issue :DSalesgirl
This solved an issue for us, not a preview, saw this on 17.2.6, to be fair t4 Templates haven't been looked at for ages... references and changing to GetCOMService worked.Planchette
This fixed it for us, too in VS 2022 Community released (v17.3...) - great answer, thank you! Our particular case was for InMemoryDatabaseModuleInclude.tt as part of database auditing templates from Enrique Catala after Dr. John Tunnicliffe (I'm adding this in case Google finds this for other people searching for solutions for those scripts)Boardman

© 2022 - 2024 — McMap. All rights reserved.