在Visual中,可以执行Add -> Existing Item,然后从Add下拉按钮执行Add as Link。
这太棒了。这让我们从另一个项目中添加一个文件,并且编辑该文件也会在原始项目中编辑它。
我希望使用这个特性在一个解决方案中的所有项目中都有一个配置文件(名为Shared.config)。而且文件总是一样的。
解决方案
|
\x{e76f}项目1
Shared.config物理
\x{e76f}项目2
Shared.config链接
发布后,该文件确实会出现在所有已发布的项目中,因此没有问题。
但是在发布之前(在构建的开发过程中),链接文件实际上并不存在。试图在Windows资源管理器中查看该文件证明该文件不在项目目录中。Visual只使它看起来像是存在于解决方案资源管理器中。(虽然在构建时,链接项可能被复制到bin目录;但我不希望使用/访问bin目录中的文件。)
现在,这使问题偏离了方向。在项目发布之前,尝试打印System.IO.File.ReadAllText(HttpContext.Current.Server.MapPath("Shared.config"))将失败,因为Shared.config还不存在于项目根目录中。
我想做的是,我需要你的帮助是:
这将使visual studio具有链接的文件和原始文件的副本,它们都存在于同名的同一个目录中。
通常,VS不允许您在目录中创建链接项,如果该目录已经包含了同名的文件。
但是,我已经进行了测试,首先创建一个链接项,然后使用Windows Explorer将原始文件复制到目标目录,然后查看。解决方案资源管理器简单地隐藏物理文件,取而代之地显示链接的项。(即使在解决方案资源管理器中单击Show all files。)
解决方案
|
\x{e76f}项目1
Shared.config物理
\x{e76f}项目2
Shared.config链接
Shared.config物理,在构建过程中复制到这里,对于解决方案资源管理器来说是不可见的
这正是我想要的!在尝试编辑文件时,将打开“链接项”。在构建时,一个物理文件将被复制到目标目录,以便它存在于试图访问它的代码中。
现在我该怎么做?这应该通过构建事件来完成吗?如果是这样的话,我怎么说‘复制所有链接文件的原件到他们的目标目录?
发布于 2013-03-19 17:25:02
您可能应该使用MSBuild特性来实现这一点。
编辑csproj文件(在Visual中,右击该项目并卸载它。然后右击并编辑)
滚动到底部,你会找到这一行。
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
紧跟在这一行之后,添加这些行。
<ItemGroup>
<LinkedItem Include="@(None)" Condition="'%Link' != ''" />
</ItemGroup>
<Target Name="CopyLinkedFiles" BeforeTargets="Build" Inputs="@(LinkedItem)" Outputs="@(LinkedItem->'%(Filename)%(Extension)')">
<Copy SourceFiles="@(LinkedItem)" DestinationFolder="$(MSBuildProjectDirectory)" />
</Target>现在,每次构建时,就在生成操作发生之前,MSBuild将复制所有链接的文件。
解释
ItemGroup包含名为"LinkedItem“的”数组“。我仅通过添加包含链接属性的"None“项来生成此数组。
Target是一个MSBuild概念。您可以将其看作是构建的一个特定阶段。我将这个阶段命名为"CopyLinkedFiles“,但您可以将其命名为任何东西。
BeforeTargets是一个指令,它告诉MSBuild在指定的阶段之前运行操作。在这里,我选择在“构建”阶段之前运行"CopyLinkedFiles“。
Inputs是一个优化参数。如果没有必要的话,可以跳过副本来加快建造速度。如果你不在乎,你可以忽略这个参数。MSBuild将Inputs与预期的Outputs时间戳进行比较,以查看是否需要执行。
Copy是一个MSBuild任务,它接受要复制的文件并将其输出到指定的文件夹。
降低冗余
您可以将其粘贴到每个.csproj文件中,也可以将其放入中央.proj并将其嵌入到csproj文件中。可悲的是,无论你做什么,你必须编辑每一个.csproj至少一次。:(
在通用项目中创建一个文件,调用WhateverNameYouLike.proj,将这些内容放入文件中。
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- paste the previously shown code here -->
<!-- you can save yourself some hassle by linking the config file here, but if you really enjoy adding the file as a link to every project, you can skip this line -->
<None Include="..\Common\Shared.config">
<Link>Shared.config</Link>
</None>
</Project>现在,烦人的部分是:在每个.csproj中,您必须在<Import Project="..\Common\WhateverNameYouLike.proj" />结束标记的末尾添加一条类似于<Import Project="..\Common\WhateverNameYouLike.proj" />的行。
发布于 2013-07-02 14:59:07
我对dss539 539的答案 (在vs2010中测试)遇到了一些麻烦。首先,每个匹配的文件在解决方案资源管理器中出现重复。其次,'%link'不是属性访问器,它是字符串本身,而且它始终不等于空字符串'',因此每个具有None构建操作的文件都在构建时被匹配、复制和复制。第三,链接的文件正在复制到项目的根目录中,但我需要在放置链接的地方复制文件。所以我做了一些修改:
<Target Name="CopyLinkedFiles" BeforeTargets="Build">
<ItemGroup>
<LinkedItem Include="@(Content)" Condition="%(Content.Link) != ''" />
</ItemGroup>
<Copy SourceFiles="@(LinkedItem)" DestinationFiles="%(LinkedItem.Link)"/>
</Target>LinkedItem不再是解决方案资源管理器中的重复项。要创建要复制的链接,必须设置Content构建操作。
发布于 2013-03-19 17:12:57
右键单击“链接配置文件”,选择“属性”,将Copy to Output Directory从Never更改为Copy always。
https://stackoverflow.com/questions/15505817
复制相似问题