.NET Core를 사용하여 플러그인 시스템을 작성하려고하는데 내 요구 사항 중 하나는 플러그인 DLL을 사용자에게 배포하여 설치할 수 있도록하는 것입니다.
그러나 NuGet 종속성을 빌드 아티팩트 dotnet publish
로 포함하고 해킹 으로 사용할 필요없이 빌드 폴더에 출력하도록하는 방법을 알아낼 수 없습니다 . .csproj 파일 (프로젝트 파일)에서 이것을 지정할 수있는 방법이 있습니까?
답변
이를 <PropertyGroup>
csproj 파일 내부에 추가 하여 NuGet 어셈블리를 빌드 출력에 복사하도록 할 수 있습니다.
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
그러나 빌드 출력 ( bin/Release/netcoreapp*/*
)은 이식 가능하고 배포 할 수 없어야 dotnet publish
합니다. 그러나 귀하의 경우 어셈블리를 빌드 출력에 복사하는 것은 테스트 목적으로 매우 유용 할 것입니다. 그러나 DependencyContext
api를 사용하여 로컬 디렉터리를 열거하는 대신 애플리케이션 종속성 그래프의 일부인 DLL 및 해당 위치 를 확인할 수도 있습니다 .
답변
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을 포함합니다.
답변
첨가
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
작동하지 않았지만 Framework .csproj 파일에 다음을 추가하십시오.
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
했다.
답변
나는 이것을 더 간단한 방법으로 “해결”(해결책을 만들었다).
빌드 후
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|x64
및 Release|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을 가져 와서 출력 폴더에 복사합니다. 완료되었습니다.
답변
위의 답변과 함께 : 빌드 후 이벤트 명령 줄 에서이 작업이 훌륭하게 작동 합니다. Visual Studio에서. 선택한 dll (System * .dll 및 Microsoft .dll) *을 반복 한 다음 특정 dll의 삭제를 건너 뜁니다. System.Data.SqlClient.dll 및 System.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
답변
