출력 디렉토리에 복사는 폴더 구조를 복사하지만 파일 만 복사하려고합니다.


87

VS2008이 있는데 특정 파일을 디렉터리에서 내 /bin/폴더 로 복사하고 싶습니다 . 파일 (에 있음 /common/browserhawk/)을 "출력 디렉토리에 복사"로 설정했습니다. 그러나 폴더 구조도 복사합니다. 파일이/bin/common/browserhawk/

이 파일을 어떻게 복사 할 수 /bin/있습니까? 올바르게 복사하기 위해 웹 사이트의 루트에 저장하고 싶지 않습니다.

관련 질문 : Visual Studio는 컴파일 후 프로젝트에 .dll 및 .pdb를 추가합니다.

답변:


59

빌드 후 이벤트를 추가하여 파일을 복사 할 수 있습니다.
프로젝트 속성, 빌드 이벤트 탭으로 이동하여 빌드 후 이벤트 명령 줄에 다음을 추가합니다.

copy "$(ProjectDir)\common\browserhawk\*.*" "$(TargetDir)"

프로젝트 경로에 공백이있는 경우 따옴표를 포함해야합니다.


그 조언에 감사드립니다. VS2012에서도 저에게 효과적이었습니다.
Dib 2014 년

2
제 경우에는 이것을 약간 수정했습니다.xcopy /s /d /y "$(ProjectDir)\stuff" "$(TargetDir)\stuff"
Danny Staple

44

이전 답변에 대해 언급 할 수 없으므로 여기에 솔루션을 넣겠습니다.

@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"옵션은 기본적으로 속성 창의 "Build Action"속성 아래에 프로젝트의 항목을 할당 할 수있는 새 명명 된 목록을 만듭니다. 그런 다음이 새로 생성 된 목록을 원하는 대상에서 사용할 수 있습니다 (예 : "@ (RootContent)"를 통해).


좋은 대답, 성공을 위해 이것을 직접 사용했습니다!
Chris Marisic 2011 년

또한 VS 2010 (이전 버전에 대해서는 확실하지 않음) AvailableItemName에서 VS 내에서 프로젝트 파일을 편집하면 잘못된 요소가 된다고 불평 합니다. 경고를 무시하십시오. 어쨌든 작동합니다.
Aaronaught 2011 년

2
불행히도 이것은 파일이 시작 프로젝트의 출력 디렉토리가 아니라 파일이 속한 프로젝트의 출력 디렉토리에만 파일을 복사합니다. 이것은 도서관 프로젝트에서 이것을 사용할 때 중요합니다.
Sebastian Krysmanski 2012 년

2
이것은 vs2008을 사용하여 릴리스 및 디버그 모드에서 빌드하는 데 적합하지만 원 클릭 게시를 사용할 때는 작동하지 않는 것 같습니다. 어떤 제안?
Soenhay

2
vs2015에서 나를 위해 일하지 않았습니다. 대상을 약간 다시 작성하여 수정했습니다. <Target Name="RootOutputCopyTarget" AfterTargets="Build">... </ Target>
lorond

44

텍스트 편집기에서 .csproj / .vbproj를 편집하면 파일이 출력 디렉터리에 배치되는 위치와 출력 디렉터리에 파일 이름이 지정되는 것을 제어 할 수 있습니다. 예를 들면 :

<None Include="content\someContent.txt">
  <Link>someContentInOutputDirectory.txt</Link>
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

그러면 파일 content\someContent.txtbin\someContentInOutputDirectory.txt. bin원하는 경우 하위 디렉토리를 선택할 수도 있습니다 . Link 요소에 추가하기 만하면됩니다.


3
와, 이틀 전이 아니라 지금 이걸 필요로해서 다행 이었어요. 감사; 이것은 훌륭합니다!
아세라

2
오 마이 갓, 감사합니다. VS가 .dll을 지능적으로 복사하지 않은 코너 케이스 쓰레기를 고치려고 6 시간을 보냈습니다. 이것은 생명, 우주 및 모든 것에 대한 진정한 답입니다.
Brandon

5
이는 지금까지 가장 좋은 방법입니다
PhilHdt

1
이 작업을 수행하고 Visual Studio에서 프로젝트를 다시로드하면 종속성 파일이 프로젝트에 포함되지 않은 것처럼 솔루션 탐색기에서 사라진 것을 발견했습니다. 그러나 여전히 예상대로 빌드되고 원하는대로 출력에 복사합니다. 해결 방법으로 현재 각 파일을 두 번 추가하고 있습니다. 한 번은 작업이없고 한 번은 '출력으로 복사'가 설정됩니다.
Éliette 2015

1
이것은이 태그의 의도 된 사용법이 아닙니다. VS2013에서는 프로젝트를로드 할 때 경고가 발생하고 파일이 프로젝트 디렉터리이므로 프로젝트에 추가 된 것으로 표시되지 않습니다.
jpmc26

15

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가능한 변경 사항을 덮어 쓰지 않도록하는데도 유용 할 수 있습니다.
KurzedMetal 2015 년

10

.csproj / .vbproj 파일에 다음을 추가합니다.

<Target Name="AfterBuild">
    <Copy
        DestinationFolder="$(OutputPath)"
        SourceFiles="@(RootContent)"
        SkipUnchangedFiles="true"
        />  
</Target>

그런 다음 루트 폴더에서 원하는 파일의 빌드 작업을 RootContent로 변경합니다.


대화 상자를 통해서가 아니라 VS에서 프로젝트를 편집 할 수 있습니다. 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 프로젝트 언로드를 선택합니다. 그런 다음 마우스 오른쪽 버튼을 클릭하고 편집을 선택합니다. 그런 다음 프로젝트 인 MSBuild 파일을 편집 할 수 있습니다.
Paul Alexander

2
감사합니다. 유용 해 보입니다. .vbproj 파일에 코드 조각을 추가 한 후에도 RootContent"Build Action"드롭 다운 목록에 표시되지 않고 수동으로 입력하면 Visual Studio에서 "Property value is not valid"오류가 발생합니다. 내가 놓친 게 무엇입니까?
Heinzi

Visual Studio 2010 C # 콘솔 응용 프로그램 프로젝트에서 작동하지 않습니다.
AMissico

Visual Studio 2010 VB.NET 콘솔 응용 프로그램 프로젝트에서 작동하지 않습니다.
AMissico

Visual Studio 2008 C # 콘솔 응용 프로그램 프로젝트에서 작동하지 않습니다.
AMissico

5

나는 이것을 VS2010, VS2015, VS2017 및 VS2019에서 사용했습니다. 다음과 같은 이유로이 솔루션을 선호합니다.

  1. XML은 모든 프로젝트에서 재사용 가능
  2. "RootContent"는 다른 "Content"와 마찬가지로 Visual Studio UI에서 빌드 작업으로 선택됩니다.
  3. "CopyToOutputDirectory"는 예상대로 준수됩니다.
  4. RootContent는 프로젝트의 출력에 추가됩니다. Project-References를 통해 전달되고 "Clean"을 준수합니다.
  5. RootContent는 재귀 폴더 구조를 유지하면서 와일드 카드로 지정할 수 있습니다.
<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파일에서 출력 경로로 폴더 구조를 다시 만들어야했습니다 .
Jonno 2015

@Jonno 목표는 RecursiveDirectory에 관계없이 파일을 루트 출력 디렉토리에 직접 복사하는 것입니다. 내장 된 "Content"Build Action은 이미 RecursiveDirectory를 유지하면서 복사 할 수있는 메커니즘을 제공합니다.
MattGerg

나는 이것을 한동안 테스트 할 기회가 없었지만 "Content"빌드 동작을 설정 하면 OP가 말한대로 파일 /common/browserhawk/이 복사되지 /bin/common/browserhawk/않습니까? IIRC, 내 의도는 것이 었 /common/browserhawk/a.txt에 결국 /bin/a.txt그렇게하지만, 거기 아래에서 재귀를 허용 /common/browserhawk/secret/stuff.png에 끝납니다 /bin/secret/stuff.png.
Jonno

@Jonno 좋아, 네, 이제 완전히 말이됩니다. 을 포함하도록 답변을 업데이트했습니다 %(RecursiveDirectory). IDE에서 개별 파일을 선택하는 것 외에도 와일드 카드를 사용하여 여러 파일을 지정할 수 있기 때문에 정말 멋집니다. **와일드 카드를 사용하면 전체 폴더 구조가 유지됩니다.
MattGerg

1
훌륭한 답변에 감사드립니다! 다음과 같은 이유로이 답변이 정답이라고 생각합니다. 1. 외부 cmd 없음 2. 크로스 플랫폼
George Anisimov

2

성공적인 컴파일 후 복사 할 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>

2
일 때문에 사람이 여전히 도움이 대답 NANT를 사용
크리스 헤인즈

1

배치 파일을 빌드하여 파일을 복사하고 빌드 후 이벤트로 실행할 수 있습니다.


결국 내 프로젝트 중 하나에서이 작업을 수행했습니다 (박쥐 대신 Python 스크립트를 사용했지만).
Fire Lancer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.