.NET Core 프로젝트를 가져와 NuGet 참조를 빌드 출력에 복사하려면 어떻게하나요?


109

.NET Core를 사용하여 플러그인 시스템을 작성하려고하는데 내 요구 사항 중 하나는 플러그인 DLL을 사용자에게 배포하여 설치할 수 있도록하는 것입니다.

그러나 NuGet 종속성을 빌드 아티팩트 dotnet publish로 포함하고 해킹 으로 사용할 필요없이 빌드 폴더에 출력하도록하는 방법을 알아낼 수 없습니다 . .csproj 파일 (프로젝트 파일)에서 이것을 지정할 수있는 방법이 있습니까?


2
dotnet publish해킹을 사용 하는 이유는 무엇 입니까? 빌드 후 스크립트로 csproj 파일에 명령을 포함합니다.
Austin Drenski

3
dotnet publish플러그인을 작성하고 있기 때문에 프레임 워크가 이미 부트 스트 래퍼 프로그램에 의해로드되기 때문에 대부분의 파일이 필요하지 않으므로 게시 폴더에 전체 프레임 워크를 던집니다. .NET Framework에서 빌드가 작동하는 방식과 유사한 것을 찾고 있습니다.
chyyran

그리고 <CopyToOutputDirectory>Always</CopyToOutputDirectory>이동하려는 각 dll에 csproj를 포함 시키는 것이 트릭을 수행하지 않습니까? 아마도 <link>노드 와 결합 되었을까요 ?
Austin Drenski

7
<PackageReference/>지원하지 않습니다 <CopyToOutputDirectory>.
chyyran

1
은 "전체 프레임 워크는"하지만 .. NuGet에서 제공하고 빌드 출력에 모든 NuGet 어셈블리를 복사로 선택하는 경우, 당신은 그들 모두 .. 얻을 것이다
마틴 울리히

답변:


178

이를 <PropertyGroup>csproj 파일 내부에 추가 하여 NuGet 어셈블리를 빌드 출력에 복사하도록 할 수 있습니다.

<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

그러나 빌드 출력 ( bin/Release/netcoreapp*/*)은 이식 가능하고 배포 할 수 없어야 dotnet publish합니다. 그러나 귀하의 경우 어셈블리를 빌드 출력에 복사하는 것은 테스트 목적으로 매우 유용 할 것입니다. 그러나 DependencyContextapi를 사용하여 로컬 디렉터리를 열거하는 대신 애플리케이션 종속성 그래프의 일부인 DLL 및 해당 위치 를 확인할 수도 있습니다 .


7
그것은 모든 DLL을뿐 아니라 Nuget DLL을 복사됩니다
모하마드 Dayyan

2
Core 2 모든 Microsoft DLL도 받고 있습니다. 이유는 확실하지 않지만 NuGet 만 받기 전에는 중단 되었습니까? 성가신
피오트르 쿨라

4
@MartinUllrich에 대해 자세히 설명해 주 DependencyContext시겠습니까? 응용 프로그램 디렉터리에없는 DLL을 찾는 데 어떻게 사용할 수 있습니까? 어쨌든 어디 있니?
ygoe

2
asp.net 핵심 System.ValueTuple.dll 복사하지 않고 나를 위해하지 작업
알리 Yousefi

1
.NET 프레임 워크 프로젝트 @AliYousefie system.valuietuple는 더 이상 최근의 .NET 프레임 워크 버전 및 빌드 도구에 NuGet에서 나오지 말아야합니다
마틴 울리히

10

PostBuildEvent를 사용하여 빌드시 모듈 배포를 자동화 할 수 있습니다.

빌드 폴더에서 NuGet 어셈블리를 가져 오려면 모듈의 csproj 에 추가 하세요.

<PropertyGroup>
    <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>

Include / Exclude를 사용하여 원하는 모듈 파일을 정의합니다 (필요에 따라 경로 수정).

<ItemGroup>
    <ModuleFiles
      Include="$(TargetDir)*.dll"
      Exclude="$(TargetDir)System*.dll;$(TargetDir)Microsoft*.dll"
      DestinationPath="$(SolutionDir)src\MyProject\Modules\MyModule\%(Filename)%(Extension)">
    </ModuleFiles>
</ItemGroup>

빌드 폴더를 기본값으로 재설정하고 PostbuildEvent를 추가하십시오.

<Target Name="PublishModule" AfterTargets="PostBuildEvent" Inputs="@(ModuleFiles)" Outputs="@(ModuleFiles->'%(DestinationPath)')">
    <WriteLinesToFile File="$(SolutionDir)src\[YOURAPP]\app_offline.htm" />
    <Copy SourceFiles="@(ModuleFiles)" DestinationFiles="@(ModuleFiles->'%(DestinationPath)')" />
    <Delete Files="$(SolutionDir)src\[YOURAPP]\app_offline.htm" />
</Target>

파일 사용 오류를 방지하기 위해 이미 실행중인 경우 앱을 재활용하기 위해 app_offline을 포함합니다.


내 프로젝트에서 "Microsoft.Extensions.Logging.Log4Net.AspNetCore"Nuget 라이브러리에 대한 종속성이 있으며 NetCore의 일부가 아니므로이 접근 방식이 작동하지 않습니다
sad_robot 2018-04-13

4

첨가

<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

작동하지 않았지만 Framework .csproj 파일에 다음을 추가하십시오.

<RestoreProjectStyle>PackageReference</RestoreProjectStyle>

했다.


이것은 .Net Framework 4.7.2 프로젝트 내에서 .net Standard 2.0 라이브러리를 참조 할 때 잘 작동했습니다. 다른 어떤 것도 그것을 고치지 않았습니다.
Grungondola

3

나는 이것을 더 간단한 방법으로 "해결"(해결책을 만들었다).

빌드 후

dotnet publish "$(ProjectFileName)" --no-build -o pub
xcopy "$(ProjectDir)pub\3rdPartyProvider.*.dll" "$(OutDir)"

pub 게시 된 항목을 스테이징 할 폴더입니다.

참고 :dotnet.exe 사용 하는 버전에 따라--no-build 하지 못할 수 있습니다.

예를 들어 v2.0.3에서는 사용할 수 없습니다. v2.1.402에서 사용할 수 있습니다. VS2017 Update4에 v2.0.3이 있다는 것을 알고 있습니다. Update8에는 2.1.x가 있습니다.

최신 정보:

위의 설정은 기본 디버그 환경에서 작동하지만 빌드 서버 / 프로덕션 환경에 배치하려면 더 많은 것이 필요합니다. 내가 해결해야한다고 위의 예에서, 구축 Release|x64Release|x86별도. 그래서 저는 둘 다 설명했습니다. 하지만 빌드 후 dotnet publish명령 을 지원하기 위해 먼저 RuntimeIdentifier프로젝트 파일에 추가 했습니다.

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
  <OutputPath>..\..\lib\</OutputPath>
  <RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
  <OutputPath>..\..\lib\</OutputPath>
  <RuntimeIdentifier>win-x86</RuntimeIdentifier>
</PropertyGroup>

왜 내가 그것을 필요로했고 왜 그것없이 도망 갈 수 있습니까? 빌드 프로그램이 경고 MSB3270 을 가로 채고 표시 되면 빌드가 실패하도록 설정 되었기 때문에 이것이 필요 했습니다. 이 경고는 "종속성에있는 일부 파일의 형식이 잘못되었습니다."라고 말합니다. 하지만이 운동의 목표를 기억하십니까? 패키지 종속성 DLL을 가져와야합니다. 그리고 많은 경우에이 경고가 있는지 여부는 사후 빌드가 상관하지 않기 때문에 중요하지 않습니다. 다시 말하지만 이것은 내 빌드 프로그램입니다. 따라서 RuntimeIdentifier프로덕션 빌드 중에 사용하는 2 개의 구성 만 추가 했습니다.

전체 포스트 빌드

if not exist "$(ProjectDir)obj\$(ConfigurationName)" mkdir "$(ProjectDir)obj\$(ConfigurationName)"
xcopy  "$(ProjectDir)obj\$(PlatformName)\$(ConfigurationName)" "$(ProjectDir)obj\$(ConfigurationName)" /E /R /Y

if $(ConfigurationName) == Release (
    dotnet publish "$(ProjectFileName)" --runtime win-$(PlatformName) --no-build -c $(ConfigurationName) -o pub --no-restore --no-dependencies
) else (
    dotnet publish "$(ProjectFileName)" --no-build -c $(ConfigurationName) -o pub --no-restore --no-dependencies
)

xcopy "$(ProjectDir)pub\my3rdPartyCompany.*.dll" "$(OutDir)" /Y /R

설명 : dotnet publish에서 obj\Debug또는을 (를 ) 찾고 obj\Release있습니다. 빌드가 obj\x64\Release또는 obj\x86\Release. 1 행과 2 행은이 문제를 완화합니다. 3 행에서 dotnet.exe특정 구성 및 대상 런타임을 사용하도록 지시합니다. 그렇지 않으면 이것이 디버그 모드 일 때 런타임 항목과 경고에 대해 신경 쓰지 않습니다. 그리고 마지막 줄에서 dll을 가져 와서 출력 폴더에 복사합니다. 완료되었습니다.


프로젝트에 디버그 구성이없는 경우 (제 경우와 같이) "dotnet publish"명령에 "-c Release"매개 변수가 필요합니다. : 나는 빌드 후 이벤트 등이 배치 사용 그래서 dotnet publish "$(ProjectFileName)" -c Release --no-build -o bin\pub xcopy "$(ProjectDir)pub\PostSharp.dll" "$(OutDir)"
Xtro

0

위의 답변과 함께 : 빌드 후 이벤트 명령 줄 에서이 작업이 훌륭하게 작동 합니다. Visual Studio에서. 선택한 dll (System * .dll 및 Microsoft .dll) *을 반복 한 다음 특정 dll의 삭제를 건너 뜁니다. System.Data.SqlClient.dllSystem.Runtime.Loader.dll

for %%f in ($(OutDir)System*.dll $(OutDir)Microsoft*.dll) do if not %%f == $(OutDir)System.Data.SqlClient.dll if not %%f == $(OutDir)System.Runtime.Loader.dll del %%f
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.