दृश्य स्टूडियो: फ़ोल्डर संरचना की नकल के बिना "आउटपुट निर्देशिका में कॉपी" कैसे करें?


111

मेरे पास मेरे प्रोजेक्ट फोल्डर के कुछ dll फाइलें हैं। Dll के संपत्ति पृष्ठ में, मैंने "बिल्ड एक्शन" को "कंटेंट" और "कॉपी टू आउटपुट डायरेक्टरी" को "हमेशा कॉपी करें" के रूप में चुना है।

निर्माण के बाद मैं वास्तव में dll की नकल प्राप्त कर रहा हूँ, लेकिन वे \ bin \ रिलीज़ \ lib के अंदर हैं और \ bin \ रिलीज़ में नहीं।

क्या पोस्ट-बिल्ड स्क्रिप्ट लिखने या नेंट आदि का सहारा लिए बिना dll फ़ाइलों को कॉपी करने के लिए एक तरीका है (और बिन \ रिलीज़ \ lib) नहीं?

जवाबों:


255

इसके बजाय लक्ष्य पथ का <Content>उपयोग <ContentWithTargetPath>और निर्दिष्ट करें:

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

ध्यान दें कि यह प्रविष्टि विजुअल स्टूडियो (2012, 2015, 2017) से दिखाई नहीं दे सकती है, लेकिन एक बार csproj में मैन्युअल रूप से जोड़ देने के बाद, यह विज़ुअल स्टूडियो में दिखाई देगी। लक्ष्य पथ यूआई के माध्यम से संपादन योग्य नहीं होगा।


2
मुझे VS 2015 में ContentWithTargetPath को बिल्ड एक्शन विकल्प के रूप में नहीं देखा गया है। क्या इसे जोड़ने का कोई तरीका है?
किम

1
एक बार जब मैंने प्रवेश को मैन्युअल रूप से .csproj फ़ाइल में जोड़ा तो यह IDE में एक विकल्प के रूप में दिखाई देता है। हालाँकि मैं अभी भी IDE से लक्ष्य पथ को संपादित नहीं कर सकता।
किम

9
मेरी एकमात्र चिंता यह है कि यह MSBuild / .NET / Visual Studio / के भविष्य के संस्करणों के साथ असमर्थित हो जाएगा, जो भी, क्योंकि VS2015 UI इस विकल्प या TargetPath संपत्ति को नहीं दिखाता है।
मारियोडीएस

1
यह मेरे लिए काम करता है। अन्य कोई भी उत्तर मेरे लिए काम नहीं करता है। इसका उत्तर होना चाहिए।
गन वांडरर

1
ध्यान दें कि ContentWithTargetPathवृद्धिशील संकलन का उपयोग करना (वीएस 2017 15.9.9 पर परीक्षण किया गया)
मैड्स रावन

26

उन्हें अंदर रखें $(ProjectDir)\Lib, लेकिन उन फ़ाइलों को "। लिंक की तरह " अपने .csproj की जड़ में जोड़ें। अब वे बिन \ _ डिबग (या जो भी अन्य आउटपुट फ़ोल्डर) में बिना किसी परिवाद के कॉपी किए जाएंगे।

EDIT: जब ContentWithTargetPath VS / MSBuild I के संस्करणों में उपलब्ध नहीं था, तब यह उत्तर वापस लिखा गया था। इस उत्तर को उन लोगों के लिए छोड़कर, जिन्हें पुराने संस्करण का उपयोग करना पड़ सकता है। कृपया इस पर टिप्पणी करना बंद करें, हम सभी जानते हैं कि अब बेहतर तरीके हैं।


4
धन्यवाद ananthonline मैंने आपके चरणों की कोशिश की लेकिन यह मदद नहीं की। हो सकता है मैं कुछ गलत कर रहा हूं। यहाँ मैं क्या कर रहा हूँ, कृपया सही है अगर आपको लगता है कि कुछ गलत है: 1. उन dlls को प्रोजेक्ट से बाहर करें लेकिन उन्हें lib में रहने दें। प्रोजेक्ट पर राइट क्लिक करें और "मौजूदा आइटम जोड़ें"। एफएल से डीएलएस का चयन करें और उन्हें "लिंक के रूप में जोड़ें" 3. डीएलएस पर राइट क्लिक करें और फिर से "कॉपी ऑलवेज" को "आउटपुट निर्देशिका में कॉपी करें" चुनें। 4. स्वच्छ और पुनर्निर्माण। परिणाम: मैं फिर से उन dlls को \ bin \ रिलीज़ \ lib
ओह्डियर

1
कृपया इसे कॉन्फ़िगर करने के बाद अपने समाधान फ़ोल्डर का स्क्रीनशॉट पोस्ट करें
एनी

3
अगर मैं परियोजना के पेड़ में पहले से ही एक फ़ाइल के लिए एक लिंक जोड़ने की कोशिश करता हूं, तो यह मना कर देता है और इसके बजाय बस परियोजना में फ़ाइल को फिर से शामिल करता है ...
Nyerguds

1
@Nyerguds की तरह मैं अनुभव कर रहा हूं कि आप एक फ़ाइल के लिए लिंक नहीं जोड़ सकते हैं जो पहले से ही प्रोजेक्ट ट्री में है इसलिए यह उत्तर प्रश्न को हल नहीं करता है।
तोर oreस्टरगार्ड

1
यह समाधान एक्सप्लोरर में परियोजना निर्देशिका की जड़ बाढ़ नहीं है? ऐसी कई फाइलों के साथ यह एक समस्या हो सकती है। आमतौर पर एक परियोजना निर्देशिका की जड़ में पहले से ही बहुत सारी फाइलें होती हैं।
एलेक्स

10

यदि आपका मुख्य इरादा परियोजना जड़ निर्देशिका को बंद किए बिना DLL को शामिल करना है, तो एक और समाधान DLL को एक अलग साझा परियोजना में स्थानांतरित करने और मूल परियोजना में एक संदर्भ के रूप में इसे जोड़ना है।

(ध्यान दें कि यह पोस्ट सीधे इस प्रश्न का उत्तर नहीं देती है क्योंकि यह फ़ोल्डर और प्रोजेक्ट संरचना को संरक्षित नहीं करता है, लेकिन मुझे यह दृष्टिकोण उपयोगी लगा, क्योंकि मैं अपने मामले में अपनी परियोजना का पुनर्गठन करने में सक्षम था और क्योंकि मैं कुछ से बचना चाहता था अन्य दृष्टिकोणों के डाउनसाइड यहां हैं।)

कदम

  • अपने राइट-क्लिक करें Solution -> Add -> New Project -> Shared Project
  • इस प्रोजेक्ट में DLL को जोड़ें (इस प्रोजेक्ट की रूट डायरेक्टरी में, "lib" सब-फोल्डर में नहीं)
  • (जाँच DLL फ़ाइल गुण सही तरीके से सेट हैं, उदा Build Action: Contentऔर Copy to Output Directory: Copy Always)
  • मूल प्रोजेक्ट पर राइट-क्लिक करें References -> Add Reference -> Shared Projects
  • पहले आपके द्वारा बनाए गए साझा प्रोजेक्ट का चयन करें

सेटअप इस तरह दिखता है:

समाधान-एक्सप्लोरर-स्क्रीनशॉट


2
अब तक परियोजना को सुव्यवस्थित रखने के लिए सरल और सुरुचिपूर्ण समाधान।
रवि गणेश

मुझे यह UAP और * .bin फ़ाइलों के साथ काम करने के लिए नहीं मिला।
मट्टियो

7

Dll-files को प्रोजेक्ट के संदर्भ के रूप में जोड़ें, और संदर्भ सेट पर "स्थानीय कॉपी करें" को सच करें।


1
धन्यवाद एरिक। यह पूरी तरह से एक dll को छोड़कर काम करता है जिसे मैं संदर्भ के रूप में जोड़ने में सक्षम नहीं हूं। संदर्भ के रूप में जोड़ते समय मुझे जो त्रुटि हुई है वह 'libeay32.dll' का संदर्भ है जिसे जोड़ा नहीं जा सका। कृपया सुनिश्चित करें कि फ़ाइल सुलभ है, और यह एक मान्य असेंबली या COM घटक है।
ओहिदे

7
@MAnony: केवल .NET असेंबली या COM इंटरॉप असेंबली को प्रोजेक्ट संदर्भ के रूप में जोड़ा जा सकता है; देशी DLLs नहीं हो सकते। आपको DLL to \ bin \ रिलीज़ को कॉपी करने के लिए कुछ अन्य तरीके खोजने होंगे।
माइकल लियू

धन्यवाद एरिक और माइकल और एंथनलाइन। क्षमा करें, मैं आपके जवाब और टिप्पणियों को आगे नहीं बढ़ा सकता क्योंकि मेरे पास आवश्यक प्रतिष्ठा बिंदु नहीं हैं।
ओहदीप

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 में ऐसा किया है, और संस्करण से संस्करण में चीजें बदल सकती हैं।

इसे काम करने के लिए, अब अपनी परियोजना पर राइट-क्लिक करें, और "अनलोड प्रोजेक्ट" चुनें। फिर अनलोड किए गए प्रोजेक्ट पर राइट-क्लिक करें और "Project_name.vcxproj संपादित करें" चुनें।

संपादक में, फ़ाइल के निचले भाग पर सभी तरह से जाएं और सही लक्ष्य को सही अनुगामी </Project>टैग से पहले डालें:

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

अब अनलोड्ड प्रोजेक्ट पर राइट क्लिक करें और "रीलोड प्रोजेक्ट" चुनें। यदि आपको संकेत मिले तो सहेजें और बंद करने का चयन करें।

मैं भी इसके लिए तैयार हूं OutputDirectory:

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

और इसे IntermediateDirectory:

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

प्रोजेक्ट गुण सामान्य पृष्ठ में। यह आउटपुट को "बिन" फ़ोल्डर में रखता है, और आपके समाधान की जड़ में एक "obj" फ़ोल्डर में मध्यवर्ती करता है।

नोट: $(SolutionDir)जब आप MSBuild कमांड लाइन से चलाते हैं, तो इसे परिभाषित नहीं किया जाता है। एक चाल है जिसे आप उस फ़ोल्डर में परिभाषित करने के लिए उपयोग कर सकते हैं जहाँ .sln फ़ाइल GetDirectoryNameOfFileAbove का उपयोग करके रहती है। (पाठक के लिए एक अभ्यास के रूप में छोड़ दिया)। इसके अलावा, ऐसा लगता है कि 2019 में वे कमांड लाइन पर इसे सही ढंग से संभाल रहे हैं। हाँ :)$(SolutionDir) इसमें पीछे एक पीछे का भाग शामिल है, इसलिए इसके बाद कोई नहीं। प्रत्येक के परिणामों में एक पीछे की ओर होना चाहिए।

अब, यदि आप प्रो या इसके बाद के संस्करण के मालिक हैं, तो कृपया प्रोजेक्ट बनाने के लिए हर बार ऐसा न करें। वह लंगड़ा होगा। इसके बजाय, एक बार जब आप अपना प्रोजेक्ट सेटअप ठीक उसी तरह से कर लेते हैं, जैसा आप चाहते हैं Project -> Export Template। आप इसे एक नाम देते हैं, और अगली बार जब आप एक प्रोजेक्ट बनाना चाहते हैं, तो बस उस नाम को न्यू प्रोजेक्ट डायलॉग में चुनें। (पुराने संस्करण में, मुझे लगता है कि यह था Files -> Export Teamplate...।)


-1

मुझे विजुअल स्टूडियो 2010 / C # प्रोजेक्ट के साथ भी यही समस्या थी।

असेंबलियों के लिए (अर्थात .NET इंटरफ़ेस होने) समाधान एक्सप्लोरर में अपनी परियोजना के तहत फ़ोल्डर "संदर्भ" का उपयोग करें। इसे राइट क्लिक करें, "मौजूदा आइटम जोड़ें" चुनें और अपनी .dll असेंबली का पता लगाएं।

आम। Dll फ़ाइलों को एक सबफ़ोल्डर में रखा जा सकता है (जैसा कि "\ lib" ऊपर उल्लेख किया गया था) और गुणों में चुनें:

  • एक्शन बनाएँ = "हेल्प फ़ाइल्स"
  • आउटपुटडायरेरी पर कॉपी करें = "यदि नया है"

यह मेरे लिए बिल्कुल वांछित था - निर्माण के दौरान, .DLL को "\ lib" सबफ़ोल्डर के बिना आउटपुट डायरेक्टरी में कॉपी किया जाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.