Visual Studio 链接文件不存在



在Visual Studio中,您可以从Add下拉按钮中选择Add -> Existing Item,然后选择Add as Link

这太好了。这可以让你从另一个项目中添加一个文件,编辑这个文件也可以在原项目中编辑它。

我想使用这个功能有一个配置文件(名为Shared.config)存在于一个解决方案内的所有项目。并使该文件始终相同。


解决方案<代码> |
|项目1
<代码> | <代码>——共享。配置(物理)
|-项目2
<代码> | <代码>——共享。配置[链接]

发布后,该文件确实在所有已发布的项目中结束,所以没有问题。

但是在发布之前(在开发构建期间)链接的文件并不真正存在。尝试在Windows资源管理器中查看该文件证明该文件不在项目目录中。Visual Studio只是让它看起来好像存在于解决方案资源管理器中。(虽然在构建时,链接项可能被复制到LinkedItem目录;但是我不想使用/访问Content目录下的文件)

这就偏离了轨道。尝试打印出<Import Project="$(MSBuildToolsPath)Microsoft.CSharp.targets" />将在项目发布之前失败,因为Shared。项目根目录中还没有配置文件

我想做什么,我需要你的帮助的地方是:

  • 我想将所有链接的文件从原始位置复制到目标位置。

这将使visual studio拥有链接文件和原始文件的副本,并以相同的名称存在于同一目录中。

通常情况下,VS不允许你在一个目录中创建一个链接项,如果这个目录已经包含了一个同名的文件。

但是,我已经通过先创建一个链接项目进行了测试;然后使用Windows资源管理器将原始文件复制到目标目录,并查看Visual Studio是否正常运行。解决方案资源管理器只是隐藏物理文件,而显示链接项。(即使您在解决方案资源管理器中单击ItemGroup。)


解决方案<代码> |
|项目1
<代码> | <代码>——共享。配置(物理)
|-项目2
<代码> | <代码>——共享。配置[链接]
<代码> | <代码>——共享。config[物理的,在构建期间复制到这里,对解决方案资源管理器不可见]

这正是我想要的!当尝试编辑文件时,Visual Studio将打开"链接项"。在构建时,一个物理文件将被复制到目标目录,这样它就存在于试图访问它的代码中。

我该怎么做呢?这应该用构建事件来完成吗?如果是这样,我怎么说"复制所有链接文件的原件到目标目录?"

我有一些麻烦与dss539的答案(在vs2010中测试)。首先,解决方案资源管理器中出现了每个匹配文件的重复项。其次,Copy to Output Directory不是一个属性访问器,它本身是字符串,它总是不等于空字符串Never,所以Copy always构建动作的每个文件都被匹配,复制和复制。第三,链接的文件被复制到项目的根目录,但我需要文件被复制到链接放置的地方。所以我做了一些修改:

<Target Name="CopyLinkedFiles" BeforeTargets="Build">
  <ItemGroup>
    <LinkedItem Include="@(Content)" Condition="%(Content.Link) != ''" />
  </ItemGroup>
  <Copy SourceFiles="@(LinkedItem)" DestinationFiles="%(LinkedItem.Link)"/> 
</Target>

CC_28不再在解决方案资源管理器中复制项目。要使链接被复制,你必须设置CC_29构建动作。

您可能应该使用MSBuild功能来实现此功能。

编辑csproj文件(在Visual Studio中,右键单击项目并卸载它。然后右键编辑)

滚动到底部,你应该可以找到这一行。

CC_30

紧接该行之后,添加这些行。

  <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将复制所有链接的文件。

CC_31包含我的"数组"名为"LinkedItem"。我通过只添加包含link属性的"None"项来生成这个数组。

CC_32是一个MSBuild概念。您可以将其视为构建的特定阶段。我将这个阶段命名为"CopyLinkedFiles",但是你可以给它取任何名字。

CC_33是一个指令,告诉MSBuild在指定的阶段之前运行操作。这里,我选择在"构建"阶段之前运行"CopyLinkedFiles"。

CC_34是一个优化参数。如果没有必要,它可以通过跳过拷贝来加快构建速度。如果不关心,可以忽略此参数。MSBuild比较CC_35和预期的CC_36时间戳,看看是否需要执行。

CC_37是一个MSBuild任务,它接受一个文件来复制并输出到指定的文件夹。

减少冗余

你可以把它粘贴到每一个。csproj文件中,或者你可以把它放在一个中央的。proj文件中,然后嵌入到csproj文件中。遗憾的是,无论您做什么,您都必须编辑每个.csproj至少一次。(

在Common项目call CC_38中创建一个文件把这些内容放到文件中。

<?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="..CommonShared.config">
    <Link>Shared.config</Link>
  </None>
</Project>

现在是恼人的部分:在每个.csproj中,您必须添加如下行CC_39可能在CC_40结束标记之前的末尾。

右键单击链接的配置文件,选择属性,将CC_41从CC_42更改为CC_43。

您可以在Visual Studio中创建构建前和构建后事件。

选择项目,右键单击,属性,构建事件。

用于预构建-

copy /y "$(LocationOfShared.Config)Shared.config" "$(TargetDir)"

为后构建

cd $(TargetDir)
del shared.config

显然,你需要摆弄将要返回的实际位置,但是你明白了。

编辑-上面的答案更简单和直接,但这应该是一种迂回的方法。

最新更新