Использование шаблонов T4 с VS2010 Express и XNA

Я использую VS2010 Express для создания игры, созданной с помощью t4 (для создания строго типизированные классы расположений содержимого, таким образом, используя Level1Location = Content.Levels.Level1 вместо Level1Location = @"Content\Levels\Level1".

Я читал, что шаблоны T4 неправильно настроены в экспресс-выпусках, но если я создам файл с расширением .tt, он должен работать. Однако, когда я создаю файл .tt в своей библиотеке классов XNA, я получаю следующее предупреждение (без файла кода):

The custom tool 'TextTemplatingFileGenerator' failed. Could not load file or assembly 'Microsoft.VisualStudio.ServicesProxy, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.

Я искал и искал, но ничего полезного не нашел. Кто-нибудь раньше сталкивался с этой проблемой? Кто-нибудь знает, есть ли решение?

Я также попытался изменить настраиваемый инструмент на TextTemplatingFilePreprocessor, как было предложено, но получаю ту же ошибку.

РЕДАКТИРОВАТЬ: Я обнаружил, что проблема в том, что он находится в проекте / библиотеке XNA. Он отлично работает в обычном классе, поэтому моя работа - добавить проект в решение только для шаблона. Однако остается открытым вопрос: сможете ли вы заставить его работать в проекте XNA?


person George Duckett    schedule 11.05.2011    source источник
comment
Не должно быть TextTemplatingFilePreprocessor для настраиваемого инструмента?   -  person Marcote    schedule 11.05.2011
comment
Он автоматически вставлял TextTemplatingFileGenerator, когда я менял расширение на .tt. Я пробовал TextTemplatingFilePreprocessor, но получаю ту же ошибку (с измененным именем настраиваемого инструмента).   -  person George Duckett    schedule 11.05.2011
comment
@Markust. Перезапуск VS2010, похоже, устранил проблему после того, как я изменил настраиваемый инструмент! Спасибо. Измените это на ответ, и я приму. РЕДАКТИРОВАТЬ: Хм, моя ошибка, я получаю ту же ошибку, но только после того, как я попытаюсь запустить пользовательский инструмент   -  person George Duckett    schedule 11.05.2011
comment
Вы пробовали добавить шаблон с помощью Add- ›New Item-› Text Template, вместо того, чтобы вручную переименовывать его в .tt?   -  person lysergic-acid    schedule 14.05.2011
comment
Эта опция недоступна в VS2010 Express.   -  person George Duckett    schedule 15.05.2011
comment
Лучше всего надеяться, что stackoverflow.com/users/330543/garethj увидит этот вопрос;)   -  person MattDavey    schedule 19.05.2011
comment
связаны с stackoverflow.com/questions/3309551?   -  person Jeff Atwood    schedule 20.05.2011
comment
@Jeff, это вроде как связано, однако я уже пытался вручную изменить расширение на .tt, и у меня возникли проблемы, описанные выше.   -  person George Duckett    schedule 20.05.2011
comment
Хорошо, думаю, мы просто не сможем, по крайней мере, до следующего выпуска XNA, может быть.   -  person George Duckett    schedule 25.05.2011


Ответы (1)


Хотя я опубликовал этот ответ, я все еще ищу более простой способ сделать это (т.е. файл tt в проекте XNA сам по себе)

Если кто-то найдет эту страницу, вот моя работа:

Создайте новый проект библиотеки классов (не XNA).

Добавьте текстовый файл с расширением .tt.

Напишите свой код T4 (см. Ниже).

В своем проекте XNA добавьте существующий элемент, перейдите к созданному файлу .cs и добавьте его как ссылку.

Затем, чтобы убедиться, что у нас всегда есть обновленный файл cs, щелкните правой кнопкой мыши проект XNA и выберите зависимости проекта, затем отметьте свой проект библиотеки классов, содержащий файл .tt.

Используя приведенный ниже код шаблона, вы можете делать такие вещи, как Content.Load (Content.MyGameContent.Graphics.Textures.AwesomeTexture); Вы также можете получить имена папок в виде строк с Content.MyGameContent.Graphics.Textures, например, благодаря забавному неявному оператору преобразования строк.

<#@ template language="c#" hostspecific="true" #>
<#@ assembly name="EnvDTE100" #>
<#@ assembly name="EnvDTE" #>
<#@ assembly name="System" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="EnvDTE100" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections.Generic" #>
namespace Content
{
<#
var serviceProvider = this.Host as IServiceProvider;
var dte = serviceProvider.GetService(typeof(DTE)) as DTE;

foreach (Project Proj in dte.Solution.Projects)
{
    bool IsContentProj = false;
    foreach(Property Prop in Proj.Properties)
    {
        if(Prop.Name == "Microsoft.Xna.GameStudio.ContentProject.ContentRootDirectoryExtender.ContentRootDirectory")
        {
            IsContentProj = true;
        }
    }
    if (IsContentProj)
    {
#>
    public static class <#=Proj.Name #>
    {
<#
        foreach(ProjectItem PI in Proj.ProjectItems)
        {
GenerateProjectItemClass(PI, true, "        ");
        }
#>
    }
<#
    }
}
#>
}
<#+
    void GenerateProjectItemClass(ProjectItem Item, bool Static, string Indent)
    {
        const string FolderItemKind = "{6BB5F8EF-4483-11D3-8BCF-00C04F8EC28C}";
        const string FileItemKind = "{6BB5F8EE-4483-11D3-8BCF-00C04F8EC28C}";
        string ClassName = Path.GetDirectoryName(Item.FileNames[0]).Substring(Path.GetDirectoryName(Item.FileNames[0]).LastIndexOf(Path.DirectorySeparatorChar) + 1);
        int ContentRootLength = Path.GetDirectoryName(Item.ContainingProject.FileName).Length;

        string RelativeLocation = Path.ChangeExtension(Path.GetFullPath(Item.FileNames[0]).Substring(ContentRootLength + 1), null);

        switch(Item.Kind)
        {
            case FolderItemKind:
#>
<#=Indent#>public class <#=ClassName #>Class
<#=Indent#>{
<#=Indent#>    private const string Location = @"<#= RelativeLocation #>";
<#=Indent#>    public static implicit operator string(<#=ClassName #>Class MyClass)
<#=Indent#>    {
<#=Indent#>        return Location;
<#=Indent#>    }
<#+
            foreach(ProjectItem ChildItem in Item.ProjectItems)
                GenerateProjectItemClass(ChildItem, false, Indent + "    ");
#>
<#=Indent#>}
<#=Indent#>
<#=Indent#>public <#= Static ? "static " : " " #><#=ClassName#>Class <#=ClassName#> = new <#=ClassName#>Class();
<#=Indent#>
<#+
            break;
            case FileItemKind:
#>
<#=Indent#>public <#= Static ? "static " : " " #>string <#= Path.GetFileNameWithoutExtension(Item.FileNames[0]) #> = @"<#=RelativeLocation #>";
<#+
            break;
        }
    }
#>
person George Duckett    schedule 19.05.2011