C# 如何在将文件添加到程序集之前转换文件?
我想做以下工作: (项目是WPF的用户控制库)C# 如何在将文件添加到程序集之前转换文件?,c#,file,build-process,transformation,C#,File,Build Process,Transformation,我想做以下工作: (项目是WPF的用户控制库) 将一组.FX(着色器源代码)文件作为资源添加到项目中(生成操作) 通过调用FXC.EXE实用程序将每个文件转换为.PS文件(编译着色器) 使用生成的文件代替输入的文件 我一直想写一个,不幸的是,Visual Studio从来没有看到过本文中提到的工具。在这篇文章中,有人说,有时它是看不见的,但在我的情况下,它翻译成每一次 我也看过,但我不确定它是否适合这个任务 这样做的目的是包含着色器文件源代码,并在生成时对其进行转换,而不是从命令行手动生成着
- 将一组.FX(着色器源代码)文件作为资源添加到项目中(生成操作)
- 通过调用FXC.EXE实用程序将每个文件转换为.PS文件(编译着色器)
- 使用生成的文件代替输入的文件
public class CompileEffectTask : Task
{
public string[] Files { get; set; }
public override bool Execute()
{
if (Files != null)
{
foreach (string file in Files)
{
if (file != null)
{
Log.LogMessage(MessageImportance.High, file);
string s = @"C:\Program Files (x86)\Windows Kits\8.1\bin\x86\fxc.exe";
string changeExtension = Path.ChangeExtension(file, "ps");
string arguments = string.Format("/T ps_3_0 /Fo \"{0}\"" + " " + "\"{1}\"", changeExtension,
file);
Log.LogMessage(MessageImportance.High, arguments);
var process = new Process
{
StartInfo = new ProcessStartInfo(s, arguments)
};
process.Start();
process.WaitForExit();
}
}
}
return true;
}
}
以及MSBuild部分:
<UsingTask TaskName="CompileEffectTask" AssemblyFile="D:\HLSLCompiler.dll" />
<PropertyGroup>
<BuildDependsOn>
MyCustomTarget1;
$(BuildDependsOn);
</BuildDependsOn>
</PropertyGroup>
<Target Name="MyCustomTarget1">
<Message Text="CompileEffectTask started" Importance="high" />
<Message Text="Compiling FX files ..." Importance="high" />
<CompileEffectTask Files="@(CompileEffectTask)"/>
<Message Text="Adding resulting .PS files as resources ..." Importance="high" />
<ItemGroup>
<Resource Include="**\*.ps" />
</ItemGroup>
</Target>
<Target Name="AfterBuild">
<CreateItem Include="**\*.ps">
<Output TaskParameter="Include" ItemName="DeleteAfterBuild" />
</CreateItem>
<Delete Files="@(DeleteAfterBuild)" />
</Target>
MyCustomTarget1;
$(BuildDependsOn);
(仍然需要一些清理,但它可以工作:D)事实上,自定义工具确实可以工作,但它们的设置相当棘手-它们是Visual Studio的COM扩展。但是,对于您的情况,更好的解决方案是自定义生成目标或预生成事件—自定义工具(代码生成器)更适合生成代码(文本)而不是二进制文件 因此,预构建事件是一个简单的事件。它只是在项目开始构建之前运行的一些脚本。您可以在项目属性中找到它。最简单的方法是将所有
.fx
文件放在一个目录中,在预构建事件中,只需对每个文件调用fxc.exe
现在,构建目标更酷了。它们允许您将自己的构建操作添加到文件中。因此,您只需在文件的buildaction
中选择CompileEffect
,奇迹就发生了
目标文件可以非常简单:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<AvailableItemName Include="CompileEffect"></AvailableItemName>
</ItemGroup>
</Project>
这基本上是说“先运行我的构建目标,然后运行你想要的任何东西”
现在,对于建筑:
<Target Name="MyCompileTarget">
<CompileEffectTask
ProjectDirectory="$(ProjectDir)"
Files="@(CompileEffect)"
RootNamespace="$(RootNamespace)">
</CompileEffectTaskTask>
</Target>
然后您只需要实现编译器任务本身
现在,如果只想调用可执行文件或批处理脚本,甚至不需要该自定义任务,因为MSBuild中有很多内置任务(甚至更多的内置任务)<代码>执行任务应能工作:
<Target Name="MyCompileTarget">
<Exec Command="fxc.exe @(CompileEffect)" />
</Target>
你可能必须在那里为循环编写一个
,我不完全确定。你可以做很多事情来定制项目构建(特别是任务引用部分),这是一个很好的开始。听起来很有希望:D我今天下午会尝试一下,然后回来。非常好,完成了工作:D谢谢!
<UsingTask TaskName="MyAssembly.CompileEffectTask"
AssemblyFile="C:\MyAssembly.dll"/>
<Target Name="MyCompileTarget">
<Exec Command="fxc.exe @(CompileEffect)" />
</Target>