निर्माण आउटपुट के लिए NuGet संदर्भों की प्रतिलिपि बनाने के लिए मुझे .NET कोर परियोजनाएं कैसे मिलती हैं?


112

मैं .NET कोर के साथ एक प्लगइन सिस्टम लिखने की कोशिश कर रहा हूं, और मेरी एक आवश्यकता स्थापित करने के लिए उपयोगकर्ता पर निर्भरता के साथ प्लगइन DLL को वितरित करने में सक्षम होना है।

हालाँकि, मैं यह नहीं समझ सकता कि कैसे एक निर्माण विरूपण साक्ष्य के रूप में मेरे NuGet निर्भरता को शामिल किया जाए और उन्हें dotnet publishएक हैक के रूप में उपयोग किए बिना, बिल्ड फ़ोल्डर में आउटपुट किया जाए । क्या कोई तरीका है जो मैं इसे .csproj फ़ाइल (प्रोजेक्ट फ़ाइल) में निर्दिष्ट कर सकता हूँ?


2
यूज़ करना dotnet publishहैक क्यों होगा ? अपनी csproj फ़ाइल में कमांड को पोस्ट बिल्ड स्क्रिप्ट के रूप में शामिल करें।
ऑस्टिन ड्रेंस्की

3
dotnet publishपब्लिश फ़ोल्डर में पूरे ढांचे को फेंक देता है, क्योंकि मैं एक प्लगइन लिख रहा हूं, अधिकांश फाइलें आवश्यक नहीं हैं क्योंकि फ्रेमवर्क प्रोग्रामर द्वारा फ्रेमवर्क पहले से लोड किया जाएगा। मैं कुछ इसी तरह की तलाश कर रहा हूं कि कैसे .NET फ्रेमवर्क पर काम होता है।
चय्यरन

और <CopyToOutputDirectory>Always</CopyToOutputDirectory>आप जो चाल चाहते हैं उनमें से प्रत्येक पर अपने csproj सहित चाल नहीं करता है? शायद एक <link>नोड के साथ संयुक्त ?
ऑस्टिन ड्रेंसकी

7
<PackageReference/>समर्थन नहीं करता है <CopyToOutputDirectory>
चय्यरन

1
"संपूर्ण ढांचा" नूगेट से आता है .. हालांकि और यदि आप सभी नूगेट असेंबली को बिल्ड आउटपुट में कॉपी करने का विकल्प चुनते हैं, तो आपको ये सब मिल जाएगा ..
मार्टिन उलरिच

जवाबों:


180

आप <PropertyGroup>निर्माण के लिए NuGet असेंबली की नकल लागू करने के लिए अपनी csproj फ़ाइल के अंदर इसे जोड़ सकते हैं :

<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

हालाँकि, ध्यान दें कि बिल्ड आउटपुट ( bin/Release/netcoreapp*/*) पोर्टेबल और वितरण योग्य नहीं है, का आउटपुट dotnet publishहै। लेकिन आपके मामले में, विधानसभाओं को बिल्ड आउटपुट में कॉपी करना परीक्षण के उद्देश्यों के लिए बहुत उपयोगी है। लेकिन ध्यान दें कि आप DependencyContextDLL और उनके स्थानों को हल करने के लिए एपीआई का उपयोग कर सकते हैं जो कि स्थानीय निर्देशिका की गणना करने के बजाय अनुप्रयोग की निर्भरता ग्राफ का हिस्सा हैं।


7
यह सभी Dll की नकल करता है, न कि केवल Nuget dll
मोहम्मद दयान

2
Core 2 मुझे Microsoft के सभी DLL भी मिल रहे हैं। यकीन नहीं हो रहा है, लेकिन इससे पहले कि मैं केवल NuGet हो रहा था, लेकिन फिर इसे करना बंद कर दिया? कष्टप्रद
पायोत्र कुला

4
@MartinUllrich आप पर विस्तृत कर सकते हैं DependencyContext? मैं इसका उपयोग DLL को खोजने के लिए कैसे कर सकता हूं जो एप्लिकेशन निर्देशिका में नहीं है? वैसे भी कहाँ है?
ygoe

2
मेरे लिए काम नहीं asp.net कोर नकल नहीं System.ValueTuple.dll
अली Yousefi

1
। नेट फ्रेमवर्क परियोजनाओं के लिए @AliYousefie system.valuietuple अब हाल ही में .net फ्रेमवर्क संस्करणों पर NuGet से नहीं आना चाहिए और टूलिंग का निर्माण करना चाहिए
मार्टिन Ullrich

10

आप बिल्ड पर मॉड्यूल की तैनाती को स्वचालित करने के लिए PostBuildEvent का उपयोग कर सकते हैं।

निर्माण फ़ोल्डर में NuGet असेंबलियों को अपने मॉड्यूल के csproj में लाने के लिए

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

इसमें शामिल करें कि आपको कौन सी मॉड्यूल फ़ाइलों को परिभाषित करना है जहां शामिल करें / बहिष्कृत करें (आवश्यक रूप से पथ संशोधित करें)

<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

4

जोड़ा जा रहा है

<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

काम नहीं किया, लेकिन फ्रेमवर्क में इसे जोड़कर .csproj फ़ाइल:

<RestoreProjectStyle>PackageReference</RestoreProjectStyle>

किया।


जब मैं संदर्भित कर रहा था तो मेरे लिए यह अच्छी तरह से काम कर रहा था। एक .Net फ्रेमवर्क 4.7.2 परियोजना के भीतर से .net Standard 2.0 लाइब्रेरी। और कुछ नहीं इसे तय किया।
ग्रुंगोंडोला

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 अपडेट 4 में v2.0.3 था। और अपडेट 8 में 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 खींचने की आवश्यकता है। और कई मामलों में यह कोई फर्क नहीं पड़ता अगर यह चेतावनी है क्योंकि निम्नलिखित पोस्ट बिल्ड का ध्यान नहीं है। फिर से, यह मेरा निर्माण कार्यक्रम है जो परवाह करता है। इसलिए, मैंने केवल RuntimeIdentifier2 कॉन्फ़िगरेशन जोड़े जिन्हें मैं उत्पादन के दौरान उपयोग करता हूं।

पूरी पोस्ट का निर्माण

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

स्पष्टीकरण: डॉटनैट प्रकाशित की तलाश में है obj\Debugया obj\Release। हमारे पास बिल्ड के दौरान यह नहीं है क्योंकि बिल्ड बनाता है obj\x64\Releaseया obj\x86\Release। लाइन 1 और 2 इस समस्या को कम करते हैं। पंक्ति 3 में मैं dotnet.exeविशिष्ट कॉन्फ़िगरेशन और लक्ष्य रनटाइम का उपयोग करना बताता हूं । अन्यथा, जब यह डिबग मोड होता है, तो मैं रनटाइम सामान और चेतावनी के बारे में परवाह नहीं करता हूं। और अंतिम पंक्ति में मैं बस अपने dll ले और फिर उत्पादन फ़ोल्डर में प्रतिलिपि बनाएँ। काम हो गया।


यदि प्रोजेक्ट में कोई डीबग कॉन्फ़िगरेशन (जैसे मेरे मामले में) नहीं है, तो "डॉटनेट प्रकाशित" कमांड के लिए "-सी रिलीज़" पैरामीटर आवश्यक है। इसलिए मैंने इस बैच को पोस्ट-बिल्ड इवेंट के रूप में इस्तेमाल किया: dotnet publish "$(ProjectFileName)" -c Release --no-build -o bin\pub xcopy "$(ProjectDir)pub\PostSharp.dll" "$(OutDir)"
Xtro

0

उपरोक्त उत्तर के साथ संयोजन में: मैंने पोस्ट-बिल्ड इवेंट कमांड लाइन में यह काम बहुत अच्छा किया है : विज़ुअल स्टूडियो में। यह dlls (सिस्टम * .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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.