Visual Studio : 폴더 구조를 복사하지 않고 "출력 디렉터리로 복사"하는 방법은 무엇입니까?


111

내 프로젝트 폴더의 \ lib 폴더에 몇 개의 dll 파일이 있습니다. dll의 속성 페이지에서 "Build Action"을 "Content"로, "Copy to Output Directory"를 "Copy always"로 선택했습니다.

빌드 후 실제로 dll을 복사했지만 \ bin \ Release가 아닌 \ bin \ Release \ lib 안에 있습니다.

빌드 후 스크립트를 작성하거나 nant 등에 의존하지 않고 dll 파일을 \ bin \ Release (\ bin \ Release \ lib가 아닌)에 복사하는 방법이 있습니까?

답변:


255

대신 다음 과 같이 대상 경로 를 <Content>사용 <ContentWithTargetPath>하고 지정하십시오.

<ItemGroup>
  <ContentWithTargetPath Include="lib\some_file.dat">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    <TargetPath>some_file.dat</TargetPath>
  </ContentWithTargetPath>
<ItemGroup>

이 항목은 Visual Studio (2012, 2015, 2017)에서 표시되지 않을 수 있지만 csproj에 수동으로 추가되면 Visual Studio에 표시됩니다. 하지만 대상 경로는 UI를 통해 편집 할 수 없습니다.


2
VS 2015에서 ContentWithTargetPath가 빌드 작업 옵션으로 표시되지 않습니다. 추가하는 방법이 있습니까?
Kim

1
.csproj 파일에 수동으로 항목을 추가하면 IDE의 옵션으로 나타납니다. 그러나 여전히 IDE에서 대상 경로를 편집 할 수 없습니다.
Kim

9
내 유일한 걱정은 VS2015 UI가이 옵션이나 TargetPath 속성을 표시하지 않기 때문에 MSBuild / .NET / Visual Studio / Whatever의 향후 버전에서는이 기능이 지원되지 않는다는 것입니다.
MarioDS

1
이것은 나를 위해 작동합니다. 다른 답변 중 어느 것도 나를 위해 작동하지 않습니다. 이것이 답이되어야합니다.
GunWanderer

1
참고 사용 ContentWithTargetPath(VS 2017 15.9.9에서 테스트) 휴식 증분 컴파일
MADS Ravn

26

그들에 보관 $(ProjectDir)\Lib하지만, "해당 파일을 추가 링크로 당신의 .csproj의 루트". 이제 lib에 있지 않고 bin \ Debug (또는 다른 출력 폴더)에 복사됩니다.

편집 :이 답변은 ContentWithTargetPath가 내가 사용하고 있던 VS / MSBuild 버전에서 사용할 수 없었을 때 작성되었습니다. 이전 버전의 VS를 사용해야 할 수도있는 사람들을 위해이 답변을 남겨주세요. 이에 대해 더 이상 언급하지 마십시오. 우리 모두는 더 나은 방법이 있다는 것을 알고 있습니다.


4
감사합니다 ananthonline. 나는 당신의 단계를 시도했지만 도움이되지 않았습니다. 내가 뭔가 잘못하고있을 수 있습니다. 제가하는 일은 다음과 같습니다. 잘못된 것이 있다고 생각되면 수정하십시오. 1. 프로젝트에서 해당 dll을 제외하고 lib에 있도록합니다. 2. 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 "기존 항목 추가"를 클릭합니다. lib에서 dll을 선택하고 "링크로"추가합니다. 3. dll을 마우스 오른쪽 버튼으로 클릭하고 "Copy to Output Directory"에서 "Copy Always"를 다시 선택합니다. 4. 청소 및 재건. 결과 : 다시 \ bin \ release \ lib에있는 dll을 얻었습니다
OhDear

1
솔루션 폴더를 구성한 후 스크린 샷을 게시하십시오
Ani

3
이미 프로젝트 트리에서 파일에 대한 링크를 추가하려고하면, 그것은 거부하고 대신 ... 다시 프로젝트에 파일을 포함
Nyerguds

1
@Nyerguds처럼 이미 프로젝트 트리에있는 파일에 대한 링크를 추가 할 수 없으므로이 답변으로 질문이 해결되지 않습니다.
Tore Østergaard

1
솔루션 탐색기에서 프로젝트 디렉터리의 루트가 넘치지 않습니까? 이러한 파일이 많으면 문제가 될 수 있습니다. 일반적으로 프로젝트 디렉토리의 루트에는 이미 너무 많은 파일이 포함되어 있습니다.
Alex34758

10

주요 의도가 프로젝트 루트 디렉터리를 복잡하게하지 않고 DLL을 포함하는 것이라면 또 다른 솔루션은 DLL을 별도의 공유 프로젝트이동하고 이를 원본 프로젝트의 참조로 추가하는 것입니다.

(이 게시물은 폴더와 프로젝트 구조를 보존하지 않기 때문에이 질문에 직접 답변하지는 않지만, 제 경우에 내 프로젝트를 재구성 할 수 있었고 여기에 다른 접근 방식의 단점이 있습니다.)

단계

  • 마우스 오른쪽 버튼으로 Solution -> Add -> New Project -> Shared Project
  • 이 프로젝트에 DLL을 추가합니다 ( "lib"하위 폴더가 아닌이 프로젝트의 루트 디렉토리에 있음).
  • (DLL 파일 속성이 올바르게 설정되었는지 확인하십시오. Build Action: ContentCopy to Output Directory: Copy Always)
  • 원래 프로젝트의 오른쪽 클릭 References -> Add Reference -> Shared Projects
  • 이전에 만든 공유 프로젝트를 선택하십시오.

설정은 다음과 같습니다.

솔루션 탐색기 스크린 샷


2
프로젝트를 깔끔하게 유지하는 간단하고 우아한 솔루션입니다.
Ravi Ganesh

UAP 및 * .bin 파일에서 작동하도록 가져올 수 없습니다.
Matteo

7

dll 파일을 프로젝트에 대한 참조로 추가하고 참조에서 "로컬 복사"를 true로 설정합니다.


1
고마워 Erik. 참조로 추가 할 수없는 하나의 dll을 제외하고는 완벽하게 작동합니다. 참조로 추가하는 동안 발생하는 오류는 'libeay32.dll'에 대한 참조를 추가 할 수 없다는 것입니다. 파일에 액세스 할 수 있고 유효한 어셈블리 또는 COM 구성 요소인지 확인하십시오.
OhDear 2013-09-11

7
@MAnthony : .NET 어셈블리 또는 COM interop 어셈블리 만 프로젝트 참조로 추가 할 수 있습니다. 네이티브 DLL은 될 수 없습니다. DLL을 \ bin \ Release에 복사하는 다른 방법을 찾아야합니다.
Michael Liu

Erik과 Michael과 ananthonline에게 감사드립니다. 필요한 평판 포인트가 없기 때문에 답변과 댓글을 찬성 할 수 없습니다.
OhDear

1
관리되지 않는 DLL의 경우 아래에서 제안한 방법을 사용해야합니다.
Ani

4

Libs 디렉터리에서 루트 폴더 VS2017로 파일을 복사해야하는 경우 :

<ItemGroup Condition="'$(Platform)' == 'x64'">
    <None Include="Libs\x64\**" Link="\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
<ItemGroup Condition="'$(Platform)' == 'x86'">
    <None Include="Libs\x86\**" Link="\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

Libs (RecursiveDir) 폴더를 포함한 다른 폴더로

<ItemGroup Condition="'$(Platform)' == 'x86'">
    <None Include="Libs\x86\**" Link="mycustomfolder\%(RecursiveDir)%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

3

VisualStudio 2015에서 '링크로 추가하는'dll 이 동일한 프로젝트의 하위 폴더에있는 경우 경우 자동으로 폴더에 저장되고 출력도 본 것처럼 폴더에 배치됩니다.

dll이 프로젝트 의 하위 폴더가 아닌 디스크의 다른 프로젝트 또는 디렉토리에 있는 경우 '링크로 추가'할 수 있으며 루트 디렉토리에 제대로 배치됩니다.


VS2012와 동일합니다. 링크를 만드는 것을 거부하고 콘텐츠로 추가합니다. 결국 슬프게도 가장 쉬운 해결책은 프로젝트 루트에 버리는 것 같습니다.
Nyerguds

0

다른 방법은 항목을 유형으로 두는 것 None입니다. 솔루션 탐색기에서 배포하려는 항목을 클릭하고 Content속성을로 설정합니다 True.

참고 : VS2019에서이 작업을 수행했으며 버전마다 상황이 변경 될 수 있습니다.

이 작업을 수행하려면 이제 프로젝트를 마우스 오른쪽 단추로 클릭하고 "프로젝트 언로드"를 선택하십시오. 그런 다음 언로드 된 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 "프로젝트 _ 이름 .vcxproj 편집"을 선택합니다.

편집기에서 파일 맨 아래로 이동하여 후행 </Project>태그 바로 앞에이 대상을 삽입하십시오 .

  <Target Name="CopyContent" AfterTargets="Build">
    <Copy SourceFiles="@(None)" Condition="'%(None.DeploymentContent)' == 'true'" DestinationFolder="$(OutputPath)" ContinueOnError="true" />
  </Target>

이제 언로드 된 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 "프로젝트 다시로드"를 선택합니다. 메시지가 표시되면 저장하고 닫으려면 선택하십시오.

또한 다음과 같이 설정 OutputDirectory했습니다.

$(SolutionDir)bin\$(Configuration)\$(Platform)\

IntermediateDirectoryto :

$(SolutionDir)obj\$(Configuration)\$(ProjectName)\$(Platform)\

프로젝트 속성 일반 페이지에서. 그러면 출력이 "bin"폴더에 저장되고 중간 파일은 솔루션 루트의 "obj"폴더에 저장됩니다.

참고 : $(SolutionDir)명령 줄에서 MSBuild를 실행할 때는이 정의되지 않습니다. GetDirectoryNameOfFileAbove를 사용하여 .sln 파일이있는 폴더에이를 정의하는 데 사용할 수있는 트릭이 있습니다. (독자를위한 연습으로 남았습니다). 또한 2019 년에는 어쨌든 명령 줄에서 올바르게 처리하고있는 것 같습니다. 네 :)$(SolutionDir) 후행 백 슬래시, 그 후에 따라서 없음이 포함되어 있습니다. 각 결과에는 뒤에 백 슬래시가 있어야합니다.

이제 Pro 이상을 소유하고 있다면 프로젝트를 생성해야 할 때마다이 작업을 수행하지 마십시오. 그것은 절름발이입니다. 대신 원하는 방식으로 프로젝트를 설정했으면을 선택하십시오 Project -> Export Template. 이름을 지정하고 다음에 그와 같은 프로젝트를 만들려면 새 프로젝트 대화 상자에서 해당 이름을 선택하기 만하면됩니다. (이전 버전에서는 이것이라고 생각합니다 Files -> Export Teamplate....)


-1

Visual Studio 2010 / C # 프로젝트에서 동일한 문제가 발생했습니다.

어셈블리 (예 : .NET 인터페이스가있는 경우)의 경우 솔루션 탐색기에서 프로젝트 아래의 "참조"폴더를 사용하십시오. 마우스 오른쪽 단추로 클릭하고 "기존 항목 추가"를 선택한 다음 .dll 어셈블리를 찾습니다.

일반적인 .dll 파일은 하위 폴더 (위에서 언급 한 "\ lib")에 배치 할 수 있으며 속성에서 다음을 선택합니다.

  • 빌드 작업 = "HelpFiles"
  • OutputDirectory에 복사 = "최신 인 경우"

이것은 원하는대로 정확하게 작동했습니다. 빌드하는 동안 .DLL이 "\ lib"하위 폴더없이 출력 디렉토리에 복사됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.