2010-04-27 54 views
1

我有一些内容文件,我想在Visual Studio中的多个项目之间共享。仅使用内容文件创建VS 2010项目

我已经把这些文件放在他们自己的项目中,将build动作设置为“Content”,并将复制到输出目录设置为“Copy if newer”。我希望所有这些文件都被复制到引用它们的项目的bin/debug目录中。

我可以通过在每个需要这些文件的项目中包含对“内容”项目的引用来工作,但这需要生成最小程序集(3K)。我假设有一种方法,使用MSBuild,使这一切工作,而不创建空的大会?

回答

4

感谢任何花时间就如何解决此问题提出建议的人。

事实证明,如果我想我的编译内容文件能像内容文件进行处理(在它们被复制到引用我的项目在其他项目的输出目录),我需要创建之前运行的目标GetCopyToOutputDirectoryItems,并将编译的内容文件的完整路径添加到AllItemsFullPathWithTargetPath ItemGroup。 MSBuild为当前项目所依赖的项目调用GetCopyToOutputDirectoryItems,并使用生成的文件列表确定与assembly.dll一起复制的文件。这里是我的.csproj中的XML,以防其他人有类似的问题。

我有一个名为“ZipDictionary”的自定义任务,我积累了所有要编译的ItemGroup中称为DictionaryCompile的文件。我的目标“FixGetCopyToOutputDirectoryItems”在“GetCopyToOutputDirectoryItems”之前执行。我不会在那里做实际的编译,因为这个目标可以通过引用项目多次调用,并且会损害性能。目标执行一些转换以获得后编译文件名,然后将完整路径返回到所有文件,因为从引用项目调用副本时相对路径不起作用。

<ItemGroup> 
    <DictionaryCompile Include="Dictionaries\it-IT.dic"> 
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> 
    </DictionaryCompile> 
</ItemGroup> 
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> 
<UsingTask TaskName="ZipDictionary" AssemblyFile="..\LogicTree.DictionaryCompiler\bin\Debug\LogicTree.DictionaryCompiler.dll"/> 
<Target Name="BeforeCompile"> 
    <Message Text="Files @(DictionaryCompile)" Importance="high" /> 
    <ZipDictionary DictionaryFiles="@(DictionaryCompile)" OutputDirectory="$(OutputPath)"> 
    <Output TaskParameter="OutputFiles" ItemName="DictionaryOutputFiles" /> 
    </ZipDictionary> 
</Target> 
<Target Name="FixGetCopyToOutputDirectoryItems" BeforeTargets="GetCopyToOutputDirectoryItems"> 
    <ItemGroup> 
    <_DictionaryCompile Include="@(DictionaryCompile->'$(OutputPath)Dictionaries\%(FileName).ltdic')" /> 
    </ItemGroup> 
    <AssignTargetPath Files="@(_DictionaryCompile)" RootFolder="$(MSBuildProjectDirectory)\$(OutputPath)"> 
    <Output TaskParameter="AssignedFiles" ItemName="_DictionaryCompileWithTargetPath" /> 
    </AssignTargetPath> 
    <ItemGroup> 
    <AllItemsFullPathWithTargetPath Include="@(_DictionaryCompileWithTargetPath->'%(FullPath)')" Condition="'%(_DictionaryCompileWithTargetPath.CopyToOutputDirectory)'=='Always' or '%(_DictionaryCompileWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'" /> 
    <_SourceItemsToCopyToOutputDirectoryAlways Include="@(_DictionaryCompileWithTargetPath->'%(FullPath)')" Condition="'%(_DictionaryCompileWithTargetPath.CopyToOutputDirectory)'=='Always'" /> 
    <_SourceItemsToCopyToOutputDirectory Include="@(_DictionaryCompileWithTargetPath->'%(FullPath)')" Condition="'%(_DictionaryCompileWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'" /> 
    </ItemGroup> 
</Target> 
+0

你应该接受你的答案 - 它提供了一个详细的解决方案。 – Filburt 2010-05-04 18:51:36

3

一个 更好 可能的解决办法是

  • 发生在解决方案目录常见的目录,并有把你常用的内容文件。

  • 在VS

    ,在应该分享这个内容,请右键单击add existing item,浏览到所需的项目(S),选择后,点击该按钮add的向下箭头,然后选择add as link每个项目。在该项目中,您会注意到这些文件添加了一个“快捷方式”叠加层。

  • 在该项目中,选择新添加的链接并右键单击属性,然后选择生成操作:内容,复制到输出目录:始终复制。

这是给出的问题的简单解决方案。

我使用这种技术,如SQL脚本和部分配置文件(使用configSource),取得了巨大成功。这使我可以在一个位置对这些文件进行更改,并保证它们将在整个解决方案中得到支持。

更强大的解决方案是创建一个嵌入资源的项目。这需要更多的工作来管理接收端的内容,但从长远来看,这可能是值得的,因为有大量散布的文物会出现问题。

希望有所帮助。

+0

那很酷,不知道这... – 2010-04-27 17:07:45

+0

就是爽...对问题的后续是,我有一些我使用的是内部工具(我有一个自定义的MSBuild任务)编译的文件。我想与许多项目分享这个产出。你也有这个建议吗? – 2010-04-27 19:03:05

+0

@Cameron - 我们在谈论什么样的输出?即单个组件?多个工件?都? – 2010-04-27 19:20:55

0

我们做了类似的地方,我们有“...... ReleaseBuilds”,它引用了我们对特定项目所需的dll和内容。编译将所有内容复制到bin调试文件夹并确实创建了空的程序集。

在Visual Studio中,我们在“... RealeaseBuild”(在项目属性中)复制/删除或运行批处理文件以确保我们拥有所有文件(配置,服务等等)需要并删除空的程序集。

HTH

相关问题