开发者

Can I use T4 to write raw bytes into the output?

开发者 https://www.devze.com 2023-03-15 05:22 出处:网络
I\'m using T4 templates a lot, but only for text-based files (after all one of the T\'s stands for Text).

I'm using T4 templates a lot, but only for text-based files (after all one of the T's stands for Text).

However, I now have a scenario where it would be beneficial use it on an image - read the image, do something with it, write it back. (I want to avoid msbuild-tasks or postbuild applications if possible because T4 integrates nicely into Visual Studio and source control).

However, even when setting <#@ output extension=".png" encoding="ASCII" #>, the generated file has not the exact bytes in it, presumably because converting a byte into a char or string causes a conversion that changes it.

Is there any way to 开发者_StackOverflow社区do that? I don't want to do File.WriteAllBytes because this then doesn't nicely work with source control.


Our T4 templates have a common base class (<#@ template language="C#" inherits="MySpecialBaseForT4s"...). We added a WriteBinary(byte[] data) protected method to that base class, allowing our T4 templates to, for instance, generate a zip file and pass it to the part of our system that invokes the CompiledTemplate.Process() method.

public abstract class MySpecialBaseForT4s: TextTransformation
{
    protected void WriteBinary(byte[] binaryData)
    {
        string base64EncodedZip = Convert.ToBase64String(binaryData);
        Write(BASE64_HEADER);
        Write(base64EncodedZip);
    }
    public const string BASE64_HEADER = "Content-Transfer-Encoding: base64\n";
}

The logic which invokes CompiledTemplate.Process() looks for the known header in the generated string, and turns the string back into a byte array for writing to disk.

string content = myTemplate.Process();
if (content.Trim().StartsWith(MySpecialBaseForT4s.BASE64_HEADER))
{
    string contentWithoutBase64Hdr = content.Trim().Replace(MySpecialBaseForT4s.BASE64_HEADER, "");
    byte[] binaryContent = Convert.FromBase64String(contentWithoutBase64Hdr);
    File.WriteAllBytes(filenameAndExtension, binaryContent);
}

Does that help?


I don't think it's possible with T4, but you could write your own custom VS file generator without too much effort, see here: Writing a custom tool to generate code for Visual Studio .NET


Text templates always generate a string (you can see this when you create a preprocessed text template, in the code behind file). It generates some code that will concatenate a string. Unless you create your own method of parsing them there is no way to use text templates for purposes other than generating text files.

0

精彩评论

暂无评论...
验证码 换一张
取 消