종속 DLL이 Visual Studio의 빌드 출력 폴더로 복사되지 않습니다


188

비주얼 스튜디오 솔루션이 있습니다. 솔루션에 많은 프로젝트가 있습니다. 시작 역할을하고 다른 프로젝트를 사용하는 하나의 주요 프로젝트가 있습니다. "ProjectX"라는 프로젝트가 있습니다. 참조는 기본 프로젝트에 추가됩니다. ProjectX는 솔루션의 일부가 아닌 다른 .NET dll (예 : abc.dll)을 참조합니다.

이제이 abc.dll은 기본 프로젝트의 bin / debug 폴더에 복사해야하지만 복사되지는 않습니다. 알려진 이유가 무엇입니까?


이것을 알아낼 수 없다면 사전 빌드에서 복사하십시오.
Dilshod

메인 프로젝트에서 'ProjectX'를 어떻게 사용합니까-프로젝트의 유형, 대상 등
NSGaga 대부분 비활성 상태

나는 같은 문제
Gordon Tucker


RestoreProjectStyle 가능한 솔루션 . 아이디어는 <RestoreProjectStyle>PackageReference</RestoreProjectStyle>솔루션의 각 .Net Framework 프로젝트에 대해 설정 하는 것입니다.
oleksa

답변:


105

ProjectX가 abc.dll을 참조했지만 abc.dll에서 DEFINED 유형을 직접 사용하지 않으면 abc.dll이 기본 출력 폴더로 복사되지 않습니다. (이는 혼동을 피하기 위해 ProjectX 출력 폴더로 복사됩니다.)

따라서 ProjectX의 어느 곳에서나 abc.dll의 유형을 명시 적으로 사용하지 않는 경우 더미 선언을 ProjectX의 파일 중 하나에 넣으십시오.

AbcDll.AnyClass dummy006; // this will be enough to cause the DLL to be copied

모든 클래스에 대해이 작업을 수행 할 필요는 없습니다. 한 번만하면 DLL 복사본을 만들 수 있고 모든 것이 예상대로 작동합니다.

부록 : 디버그 모드에서는 작동하지만 릴리스에서는 작동하지 않을 수 있습니다. 자세한 내용은 @nvirth의 답변을 참조하십시오.


7
이것은 해킹처럼 보입니다. 주 프로젝트에 참조를 추가하는 것으로 충분합니다.
Mike K

3
그것은 해킹이지만 오늘날의 CodeProject 뉴스에서 알 수 있듯이 컴파일러조차도 잘못 될 수 있습니다!
오버로드 주르그

4
정말 미친 일이 될 수 있습니다. @OverlordZurg 내 XAML (WPF)에서 종속 DLL에 대한 참조를 가지고 당신이 말한대로 나는 간단한 더미 참조를 추가 할 때까지 ... 감사합니다 어쨌든 메인 프로젝트에 DLL을 복사하지 않았다 귀하의 솔루션 일
모센 아프신

5
@MohsenAfshin 나는 같은 문제가 있었다-XAML에서 종속 DLL을 참조했다. 그러나 더미 변수를 선언하는 대신 XAML에서 사용하고있는 구성 요소의 이름 만 지정하면 해당 어셈블리를 복사 할 수 있습니다.
redcurry

5
@MikeK (직접적으로 의존하지 않는) 메인 프로젝트에 추가하는 것은 훨씬 더 큰 해킹입니다. 그런 다음 두 위치를 관리해야합니다 (업그레이드 또는 제거에서와 같이 "관리"). 해킹을 사용하면 최소한 종속성을 제거 할 때이 해킹을 제거하도록 알려주는 멋진 컴파일 시간 오류가 발생하지만 여전히 한곳에서 업데이트해야합니다.
jpmc26

71

오버로드 주르그의 답변에 대한 주석.

이 방법으로 더미 참조를 추가했으며 디버그 모드에서 작동했습니다.

public class DummyClass
{
    private static void Dummy()
    {
        var dummy = typeof(AbcDll.AnyClass);
    }
}

그러나 릴리스 모드에서 종속 dll은 여전히 ​​복사되지 않았습니다.
그러나 이것은 효과가있었습니다.

public class DummyClass
{
    private static void Dummy()
    {
        Action<Type> noop = _ => {};
        var dummy = typeof(AbcDll.AnyClass);
        noop(dummy);
    }
}

이 정보는 실제로 알아내는 데 몇 시간이 걸렸으므로 공유하기로 생각했습니다.


7
릴리스 모드에서 옵티마이 저는 "더미"가 사용되지 않는다고 가정하므로이 행은 불필요하므로 제거해야합니다. 그러나 코드에서 "더미"를 사용할 때 옵티마이 저는 불필요한 염을 가정하지 않습니다.
Yucel

1
이것은 나를 위해 작동하지 않습니다. AbcDll.AnyClass는 여전히 다른 프로젝트로 복사되지 않습니다
Matthew Lock

3
AbcDll.AnyClass공용 클래스에서 공용 필드 또는 속성으로 사용 되는지 확인 하면 작동합니다. 이와 같은 메소드 본문에서 사용하면 컴파일러에서 볼 수 없습니다 . 원하는 어셈블리가 아닌이 어셈블리의로드를 지연시킵니다.
John Leidegren

52

예,로 설정 Copy Local해야 true합니다. 그러나 나는 확신 당신은 또한 조립 주요 프로젝트와 세트에서 참조해야합니다 Copy Localtrue그것은 단지 종속 어셈블리에서 복사되지 않습니다 -뿐만 아니라.

Copy Local아래의 어셈블리를 클릭 References하고 F4를 눌러 속성으로 이동할 수 있습니다 .


2
@Brij, 원하는 기본 프로젝트 에서 어셈블리를 참조 합니까? 내가 말했듯이, 나는 당신이 그 프로젝트에서 참조 할 필요가 있다고 확신 합니다-의존적 어셈블리는 그렇게 복사되지 않습니다. 이 경우 NuGet을 사용할 때 모든 관련 프로젝트에 어셈블리를 추가 할 필요가 없습니다.
Mike Perrenoud

1
여기서 결론은 무엇입니까? CopyLocal이 true로 설정되어 있어도 올바른 종속 참조가 복사되지 않는 것 같습니다. 그 배후의 논리는 무엇입니까?
mcmillab

29
@mcmillab, 즉 Visual Studio는 다른 종속 프로젝트의 종속성을 유추 하지 않습니다 . 프로젝트 A가 프로젝트 B를 참조하는 경우 프로젝트 A는 모든 프로젝트 B의 참조를 가져야합니다. 모든 프로젝트 B에 .NET 어셈블리가 필요한 경우에는 잘 작동하지만 타사 어셈블리 인 경우 두 프로젝트 모두에 참조를 추가해야합니다.
Mike Perrenoud

12
@MichaelPerrenoud 나는 그것이 사실이라고 생각하지 않습니다. 자세한 MSBuild 출력을 보면 "2 차 및 n 차 종속 항목 포함"을 나타내는 ResolveAssemblyReference에 대한 호출이 표시됩니다 . 이것은 내 bin 폴더에 표시된 것과 일치합니다 (n 번째 종속성이 복사됩니다). 문제는 주로 GAC 및 간접 참조에 대해 복사되는 내용에 대한 몇 가지주의 사항이 있습니다 (참조 추가로는 충분하지 않음)
Jack Ukleja

2
내 현재 경험은 이것이 '복사 된'종속성을 제외하고 작동 한다는 것 입니다. 프로젝트 A.net은 외부 C ++ dll을 '항상 복사'인 파일로 참조합니다. 프로젝트 B.net은 프로젝트 A를 참조합니다. 빌드시 B / Debug에는 C ++ dll이 포함됩니다. 그러나 프로젝트 B를 참조하는 응용 프로그램 X를 빌드하면 C ++ dll이 때로는 복사됩니다 (다시 빌드하는 경우에만 나타남).
Benjol

34

어셈블리 속성으로 만들 때 매끄럽게 보입니다.

[AttributeUsage(AttributeTargets.Assembly)]
public class ForceAssemblyReference: Attribute
{        
    public ForceAssemblyReference(Type forcedType)
    {
        //not sure if these two lines are required since 
        //the type is passed to constructor as parameter, 
        //thus effectively being used
        Action<Type> noop = _ => { };
        noop(forcedType);
    }
}

사용법은 다음과 같습니다.

[assembly: ForceAssemblyReference(typeof(AbcDll.AnyClass))]

감사합니다.하지만 이미 AbcDll.AnyClass를 참조하는 종속성 (프로젝트 X)에 어셈블리 속성을 추가 할 때만 무언가를 수행합니다. 그런 다음 AbcDll을 종속성의 출력 디렉토리에 복사하는 평소보다 더 많은 작업을 수행하지 않습니다. 여전히 주요 종속 프로젝트의 출력으로 복사하지 않습니다. 그리고 AbcDll에 대한 참조를 추가하지 않으면 종속 어셈블리에 속성을 추가 할 수 없습니다. 그렇게하면 AbcDll이 속성없이 이미 복사됩니다.
JS

25

이 같은 문제에 부딪쳤다. 배경 정보 : 구축하기 전에 솔루션에 새로운 Project X를 추가했습니다. 프로젝트 Y는 프로젝트 X에 의존하고 프로젝트 A, B, C는 프로젝트 Y에 의존했습니다.

빌드 오류는 프로젝트 A, B, C, Y 및 X dll을 찾을 수 없다는 것입니다.

근본 원인은 새로 생성 된 Project X가 .NET 4.5를 대상으로했지만 나머지 솔루션 프로젝트는 .NET 4.5.1을 대상으로했기 때문입니다. 프로젝트 X가 빌드되지 않아 나머지 프로젝트가 빌드되지 않았습니다.

새로 추가 된 프로젝트가 나머지 솔루션과 동일한 .NET 버전을 대상으로해야합니다.


1
참조 된 프로젝트는 .NET의 이전 버전 일 수 있습니다. .NET 4.5 용으로 작성된 프로젝트에서 .NET 4 용으로 작성된 프로젝트를 참조 할 수 있습니다.
redcurry

18

이것이 도움이되는지 확실하지는 않지만, 여러 번 DLL을 참조합니다 (물론 자동으로 bin 폴더에 추가합니다). 그러나 해당 DLL에는 사용중인 기능에 따라 추가 DLL이 필요할 수 있습니다. 프로젝트에서 실제로 참조하는 것과 같은 폴더에 있어야하기 때문에 프로젝트에서 참조하고 싶지 않습니다.

Visual Studio에서 "기존 파일 추가"를 통해이 작업을 수행합니다. Add_data 폴더를 제외한 모든 위치에 추가 할 수 있어야합니다. 개인적으로 나는 그것을 루트에 추가합니다.

그런 다음 해당 파일의 속성을 ...로 변경하십시오.

빌드 조치 = 없음 (이 세트를 Content와 같은 것으로 설정하면 실제로는 "루트"버전을 루트에 복사하고 Bin의 사본을 복사합니다).

출력 폴더에 복사 = 최신 인 경우 복사 (기본적으로 BIN 폴더에없는 경우에만 폴더를 저장하지만 그 후에는 수행하지 않음)

게시 할 때 .. 추가 된 DLL은 BIN 폴더와 게시 위치 (원하는 위치)에만 존재합니다.


10

찾고있는 DLL이 GAC에 포함되어 있지 않은지 확인할 수도 있습니다. Visual Studio가 빌드 머신의 GAC에 이미 존재하는 경우 해당 파일을 복사하지 않는 것이 현명하다고 생각합니다.

최근에 GAC에 어셈블리가 필요한 SSIS 패키지를 테스트하고있는 상황에 처했습니다. 나는 그것을 잊어 버렸고 왜 DLL이 빌드 중에 나오지 않는지 궁금했습니다.

Visual Studio 개발자 명령 프롬프트에서 GAC의 내용을 확인하려면

gacutil -l

또는 쉽게 읽을 수 있도록 파일로 출력하십시오.

gacutil -l > output.txt
notepad.exe output.txt

어셈블리를 제거하려면

gacutil -u MyProjectAssemblyName

또한 GAC에서 파일을 제거한 후에는 빌드 후 \ bin 디렉토리에 올바르게 출력되었습니다 (루트 프로젝트에서 직접 참조되지 않은 어셈블리의 경우에도). 이것은 Visual Studio 2013 업데이트 5에있었습니다.


감사합니다. 맞습니다. MSBuild는 dll을 GAC에서 찾은 경우 출력 폴더에 dll을 복사하지 않습니다.
John-Philip

3

필자의 경우, 동의하지 않는 TFS / VS의 기본 동작으로 인해 가장 어리석은 일이었습니다.

주 프로젝트에 대한 참조로 dll을 추가해도 작동하지 않았으므로 Copy Local = Always를 사용하여 "기존 항목"으로 추가하기로 결정했습니다. 그때도 파일이 없었습니다.

파일이 VS 솔루션에 있고 로컬 및 서버 모두에서 컴파일 된 모든 파일이 있더라도 VS / TFS는 실제로 파일을 소스 제어에 추가하지 않았습니다. "대기중인 변경 사항"에는 전혀 포함되지 않았습니다. 소스 제어 탐색기로 수동으로 이동하여 "폴더에 항목 추가"아이콘을 명시 적으로 클릭해야했습니다.

VS에서 15 년 동안 개발 해 왔기 때문에 어리 석습니다. 나는 전에 이것을 만났고, 나는 단지 기억하지 못했고 어떻게 든 그것을 참조하지 않았기 때문에 모든 것이 여전히 컴파일 되었기 때문에 그것을 놓쳤다. 그러나 기존 항목으로 추가 된 파일은 존재하지 않았기 때문에 복사되지 않았다. 소스 제어 서버

나는 이것으로 2 일을 잃었 기 때문에 이것이 누군가를 구하기를 바랍니다.


1
고마워요 ... 시간을 많이 절약했습니다. 이것은 나를위한 해결책이었습니다. 또한 루트 문제를 노출 시켰으며, 참조로 추가 한 DLL은 gitignore패턴 과 일치 하므로 참조로 추가 할 때 프로젝트에 추가되지 않았습니다. 소스 제어에 파일을 수동으로 추가해야합니다 !!!
Mattkwish

2

이것은 nvirth의 예제에서 약간의 조정입니다.

internal class DummyClass
{
    private static void Dummy()
    {
        Noop(typeof(AbcDll.AnyClass));
    }
    private static void Noop(Type _) { }
}

2

Postbuild 이벤트에 추가하여 필요한 라이브러리를 출력 디렉토리에 복사합니다. XCopy pathtolibraries와 같은 것

프로젝트 속성-> 빌드 이벤트에서 찾을 수 있습니다.


이것은 나를 위해 일했고 이것이 더 나은 대답이라고 생각합니다. 더미 참조 솔루션은 작동하지만 해킹이지만 빌드 후 규칙은 동일한 결과를 달성하는 확실한 방법입니다.
Kevin Fichter

2

발행물:

빌드 출력에 참조 된 DLL이 포함되지 않은 NuGet 패키지 DLL (Newtonsoft.json.dll)과 비슷한 문제가 발생했습니다. 그러나 컴파일은 괜찮습니다.

고치다:

텍스트 편집기에서 프로젝트를 살펴보고 태그가있는 참조를 찾으십시오. 참 또는 거짓처럼. "비공개"는 "로컬 복사"의 동의어입니다. 작업의 어딘가에서 MSBuild는 종속성을 찾으려고합니다. 다른 곳에서 종속성을 찾고 복사하지 않기로 결정합니다.

따라서 각 .csproj / .vbproj 파일을 통해 수동으로 태그를 제거하십시오. 다시 빌드하면 Visual Studio와 MSBuild에서 모두 작동합니다. 작업이 완료되면 다시 들어가서 필요한 위치로 업데이트 할 수 있습니다.

참고:

https://www.paraesthesia.com/archive/2008/02/13/what-to-do-if-copy-local-works-in-vs-but.aspx/


1

더미 코드 필요 없음
그냥 :

실행 가능한 프로젝트에 대한 참조 추가

또는 실행 가능한 프로젝트의 참조 "Copy Local"TRUE( "내" 오류 ")로 설정되어 있는지 확인하면 이것이 기본 참조 라이브러리 프로젝트의 설정을 "덮어 쓴 것 "으로 보입니다 ...


1

참조 된 어셈블리를 마우스 오른쪽 버튼으로 클릭하면 로컬 복사 라는 속성이 표시됩니다 . 로컬 복사가 true로 설정된 경우 어셈블리가 저장소에 포함되어야합니다. 그러나 Visual Studio에 문제가있는 이음새가 있습니다. 때로는 bin 폴더에 참조 된 dll이 포함되어 있지 않습니다 ... 이것은 저에게 효과적이었습니다.

여기에 이미지 설명을 입력하십시오


1
Copy Loal이 비활성화
되었으므로

1

TLDR; Visual Studio 2019를 다시 시작해야 할 수도 있습니다.

Microsoft.NET.Sdk 프로젝트 기반 프로젝트를 사용하여이 상황이 발생했습니다.

<Project Sdk="Microsoft.NET.Sdk">

구체적으로 특별히:

  • Project1: 목표 .netstandard2.1
    • Microsoft.Extensions.Logging.ConsoleNuget을 통한 참조
  • Project2: 목표 .netstandard2.1
    • Project1프로젝트 참조 를 통한 참조
  • Project2Tests: 목표 .netcoreapp3.1
    • Project2프로젝트 참조 를 통한 참조

테스트 실행시 Microsoft.Extensions.Logging.Console찾을 수 없다는 오류 메시지가 표시 되었으며 실제로 출력 디렉토리에 없었 습니다.

파일에 존재하더라도 Visual Studio의 Nuget Manager가에 설치된 것으로 표시되지 않았 음을 발견 Microsoft.Extensions.Logging.Console하기 위해 에 추가하여 문제를 해결하기로 결정했습니다 .Project2Microsoft.Extensions.Logging.ConsoleProject1Project1.csproj

Visual Studio를 간단히 종료하고 다시 시작하면 추가 참조를 추가 할 필요없이 문제가 해결되었습니다. 아마도 이것은 45 분의 생산성 손실을 누군가에게 줄 것입니다 :-)


실제로 테스트하는 방식으로 전체 PC를 다시 시작했지만 나에게
효과적

0

메인 프로젝트와 ProjectX의 빌드 출력 경로를 동일한 폴더로 설정하면 해당 폴더에 필요한 모든 dll을 얻을 수 있습니다.


0

사용하는 종속 dll에 프로젝트 응용 프로그램의 대상 .net 프레임 워크보다 높은 대상 .net 프레임 워크가 없는지 확인하십시오.

프로젝트를 선택하여 확인한 다음 Alt + Enter를 누르고 왼쪽에서 응용 프로그램을 선택한 다음 프로젝트의 대상 프레임 워크를 선택하십시오.

종속 dll 대상 프레임 워크 = 4.0 및 응용 프로그램 dll 대상 프레임 워크 = 3.5라고 가정하고이를 4.0으로 변경하십시오.

감사합니다!


0

위의 일반적인 것 외에도 게시 할 다중 프로젝트 솔루션이있었습니다. 분명히 일부 파일은 다른 프레임 워크를 대상으로합니다.

그래서 내 솔루션 : 속성> 특정 버전 (False)



0

VS2019 V16.6.3

나에게 문제는 어떻게 든 주요 .proj 파일이 DLL이 부모 프로젝트 bin 폴더에 복사되지 않은 프로젝트에 대한 다음과 같은 항목으로 끝나는 것입니다.

<ProjectReference Include="Project B.csproj">
  <Project>{blah blah}</Project>
  <Name>Project B</Name>
  <Private>True</Private>
</ProjectReference>

수동으로 줄을 삭제하고 <Private>True</Private>DLL은 기본 프로젝트의 모든 빌드에서 기본 프로젝트 bin 폴더에 복사되었습니다.

주 프로젝트의 reference 폴더에서 문제가있는 프로젝트의 참조로 이동하면 해당 프로젝트를 클릭하고 "로컬 복사"설정이있는 속성을 봅니다. 개인 태그는이 설정과 동일하지만 어떤 이유로 든 로컬 복사를 변경해도 .proj 파일의 개인 태그에는 영향을 미치지 않았습니다.

짜증나게 나는 참조에 대한 사본 로컬 값을 변경하지 않았다. 어떻게 그렇게 설정되어 있고 언젠가 VS의 어리석은 문제를 추적하는 데 낭비되었다.

원인에 대한 영역을 넓히는 데 도움이 된 다른 모든 답변 덕분에.

HTH

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