我有一个VS2008,我想将某些文件从目录复制到我的/bin/
文件夹中。我已将文件(位于中/common/browserhawk/
)设置为“复制到输出目录”。但是,它也会复制文件夹结构:将文件复制到/bin/common/browserhawk/
如何将这些文件复制到/bin/
?我不想将它们存储在网站的根目录中,以使其正确复制。
我有一个VS2008,我想将某些文件从目录复制到我的/bin/
文件夹中。我已将文件(位于中/common/browserhawk/
)设置为“复制到输出目录”。但是,它也会复制文件夹结构:将文件复制到/bin/common/browserhawk/
如何将这些文件复制到/bin/
?我不想将它们存储在网站的根目录中,以使其正确复制。
Answers:
您可以添加构建后事件以复制文件。
转到项目属性的“构建事件”选项卡,然后将以下内容添加到“构建后事件”命令行中:
copy "$(ProjectDir)\common\browserhawk\*.*" "$(TargetDir)"
如果您的项目路径中有空格,请确保包含引号。
xcopy /s /d /y "$(ProjectDir)\stuff" "$(TargetDir)\stuff"
由于我无法评论以前的答案,因此将解决方案放在这里:
添加到@PaulAlexander提供的内容中,将以下内容添加到您的.csproj / .vbproj文件中:
<ItemGroup>
<AvailableItemName Include="RootContent">
<Visible>false</Visible>
</AvailableItemName>
</ItemGroup>
<Target Name="AfterBuild">
<Copy
DestinationFolder="$(OutputPath)"
SourceFiles="@(RootContent)"
SkipUnchangedFiles="true"
/>
</Target>
这样,您可以在“属性”窗口中选择“ RootContent”作为“构建操作”,并且可以通过GUI进行访问。更完整的解释:“ AvailableItemName”选项基本上会创建一个新的命名列表,您可以将项目中的项目分配到“属性”窗口中“构建操作”属性下。然后,您可以在任何您喜欢的目标中使用此新创建的列表(例如,通过“ @(RootContent)”)。
AvailableItemName
如果您在VS中编辑项目文件,VS 2010(不确定较旧的版本)将抱怨是无效元素。只是忽略警告,它仍然可以工作。
<Target Name="RootOutputCopyTarget" AfterTargets="Build">
... </ Target>
如果在文本编辑器中编辑.csproj / .vbproj,则可以控制文件在输出目录中的放置位置,以及文件在输出目录中的名称。例如:
<None Include="content\someContent.txt">
<Link>someContentInOutputDirectory.txt</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
这会将文件content\someContent.txt
放入bin\someContentInOutputDirectory.txt
。如果需要,还可以在其中选择一个子目录bin
。只需将其添加到Link元素。
我相信XCOPY命令可以更好地处理目录和文件。因此,
XCOPY "$(ProjectDir)common/browserhawk" "$(TargetDir)" /E /I /F /Y
这允许在目标目录之外创建文件夹。
XCOPY "$(ProjectDir)Templates" "$(TargetDir)" /E /I /F /Y
项目文件夹/文件结构:
A:\TEMP\CONSOLEAPPLICATION3\TEMPLATES
├───NewFolder1
├───NewFolder2
│ TextFile1.txt
│ TextFile2.txt
└───NewFolder3
TextFile1.txt
TextFile2.txt
TextFile3.txt
成为:
A:\TEMP\CONSOLEAPPLICATION3\BIN\DEBUG
│ ConsoleApplication3.exe
│ ConsoleApplication3.pdb
│ ConsoleApplication3.vshost.exe
│ ConsoleApplication3.vshost.exe.manifest
├───NewFolder1
├───NewFolder2
│ TextFile1.txt
│ TextFile2.txt
│
└───NewFolder3
TextFile1.txt
TextFile2.txt
TextFile3.txt
/D
可能也很有用,以避免覆盖可能的更改。
将以下内容添加到您的.csproj / .vbproj文件中
<Target Name="AfterBuild">
<Copy
DestinationFolder="$(OutputPath)"
SourceFiles="@(RootContent)"
SkipUnchangedFiles="true"
/>
</Target>
然后将根文件夹中所需的任何文件的“生成操作”更改为RootContent。
RootContent
也不会显示在“生成操作”下拉列表中,而手动输入它会导致Visual Studio错误“属性值无效”。我错过了什么?
我在VS2010,VS2015,VS2017和VS2019中使用了此功能。我更喜欢这种解决方案,因为:
<RootContent Include="common\browserhawk\**">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</RootContent>
在项目文件的开头:
<ItemGroup>
<AvailableItemName Include="RootContent">
<!-- Add "RootContent" as a choice in the "Build Action" dropdown. -->
<Visible>True</Visible>
</AvailableItemName>
</ItemGroup>
在Microsoft .targets导入之后:
<PropertyGroup>
<AssignTargetPathsDependsOn>
$(AssignTargetPathsDependsOn);
IncludeRootContentAsContent;
</AssignTargetPathsDependsOn>
</PropertyGroup>
<Target Name="IncludeRootContentAsContent">
<CreateItem Include="@(RootContent)" AdditionalMetadata="TargetPath=%(RecursiveDir)%(Filename)%(Extension)">
<Output ItemName="ContentWithTargetPath" TaskParameter="Include" />
</CreateItem>
</Target>
RootContent
它的意思是“硬编码”,CustomContent
以表明这是我们要添加到该项目中的专业内容,我们需要以这种特定方式进行复制。另外,我需要TargetPath=%(RecursiveDir)%(Filename)%(Extension)
从指定CustomContent
文件到输出路径重新创建文件夹结构。
/common/browserhawk/
复制到下面/bin/common/browserhawk/
?IIRC,我的意图是进入/common/browserhawk/a.txt
,/bin/a.txt
但允许从那里向下递归,所以/common/browserhawk/secret/stuff.png
最终进入/bin/secret/stuff.png
。
%(RecursiveDirectory)
。这真的很酷,因为除了在IDE中选择单个文件之外,您还可以使用通配符指定多个文件。使用**
通配符时,将保留整个文件夹结构。
我最终在成功编译后向nant构建文件添加了一个要复制的步骤
<target name="action.copy.browserhawk.config" depends="compile.source">
<copy todir="${App.Web.dir}/bin/" includeemptydirs="false">
<fileset basedir="${browserhawk.config.dir}">
<include name="bhawk_bb.dat" />
<include name="bhawk_sp.dat" />
<include name="browserhawk.properties" />
<include name="maindefs.bdd" />
<include name="maindefs.bdf" />
<include name="BH_PRO.lic" />
</fileset>
</copy>
<echo message="COPY BROWSERHAWK CONFIG: SUCCESS ${datetime::now()}" />
</target>