आउटपुट निर्देशिका की प्रतिलिपि फ़ोल्डर संरचना की प्रतिलिपि बनाता है, लेकिन केवल फ़ाइलों की प्रतिलिपि बनाना चाहते हैं


87

मेरे पास VS2008 है मैं एक निर्देशिका से कुछ फ़ाइलों को अपने /bin/फ़ोल्डर में कॉपी करना चाहता हूं । मैंने /common/browserhawk/"आउटपुट निर्देशिका में प्रतिलिपि" के लिए फ़ाइलें (में स्थित ) सेट की हैं । हालाँकि, यह फ़ोल्डर संरचना को भी कॉपी करता है: फ़ाइलों को कॉपी किया जाता है/bin/common/browserhawk/

कैसे मैं इन फ़ाइलों को सिर्फ कॉपी करने के लिए मिलता है /bin/? मैं उन्हें सही ढंग से कॉपी करने के लिए वेबसाइट की जड़ में संग्रहीत नहीं करना चाहता।

संबंधित प्रश्न: विजुअल स्टूडियो संकलन के बाद प्रोजेक्ट के लिए .dll और .pdb जोड़ता है

जवाबों:


59

फ़ाइलों की प्रतिलिपि बनाने के लिए आप पोस्ट बिल्ड ईवेंट जोड़ सकते हैं।
प्रोजेक्ट प्रॉपर्टीज पर जाएं, इवेंट्स टैब बनाएं और पोस्ट-बिल्ड इवेंट कमांड लाइन में निम्नलिखित जोड़ें:

copy "$(ProjectDir)\common\browserhawk\*.*" "$(TargetDir)"

यदि आपके प्रोजेक्ट पथ में रिक्त स्थान हैं, तो उद्धरण शामिल करना सुनिश्चित करें।


उस सलाह के लिए धन्यवाद, क्योंकि इसने अभी भी मेरे लिए VS2012 में काम किया है।
डिब सिप

2
मैंने अपने मामले में इसे थोड़ा संशोधित किया है:xcopy /s /d /y "$(ProjectDir)\stuff" "$(TargetDir)\stuff"
डैनी स्टेपल

44

चूँकि मैं पिछले उत्तरों पर टिप्पणी नहीं कर सकता, इसलिए मैं इसका समाधान यहाँ रखूँगा:

@PaulAlexander प्रदान की गई चीज़ में जोड़कर, अपने .csproj / .vbproj फ़ाइल में निम्न जोड़ें:

<ItemGroup>
    <AvailableItemName Include="RootContent">
      <Visible>false</Visible>
    </AvailableItemName>  
</ItemGroup>
<Target Name="AfterBuild">
    <Copy
        DestinationFolder="$(OutputPath)"
        SourceFiles="@(RootContent)"
        SkipUnchangedFiles="true"
        />  
</Target>

यह आपको गुण विंडो में बिल्ड एक्शन के रूप में "रूटकॉन्टेंट" का चयन करने की अनुमति देता है, और सभी को जीयूआई के माध्यम से एक्सेस किया जा सकता है। एक अधिक संपूर्ण विवरण: "AvailableItemName" विकल्प मूल रूप से एक नई नाम-सूची बनाता है जिसे आप गुण विंडो में "बिल्ड एक्शन" संपत्ति के तहत प्रोजेक्ट में असाइन कर सकते हैं। फिर आप अपनी पसंद के किसी भी लक्ष्य में इस नई बनाई गई सूची का उपयोग कर सकते हैं (जैसे "@ (रूटकॉन्टेंट)" के माध्यम से)।


अच्छा जवाब, बस यह खुद को सफलता के लिए इस्तेमाल किया!
क्रिस मैरिसिक

यह भी ध्यान दें कि वीएस 2010 (पुराने संस्करणों के बारे में सुनिश्चित नहीं) AvailableItemNameयदि आप वीएस के भीतर परियोजना फ़ाइल को संपादित करते हैं तो एक अमान्य तत्व होने के बारे में शिकायत करेंगे ; बस चेतावनी को अनदेखा करें, यह वैसे भी काम करता है।
Aaronaught

2
दुर्भाग्य से यह केवल फ़ाइल को प्रोजेक्ट के आउटपुट डायरेक्टरी में कॉपी करता है, जो फाइल का है - और स्टार्टअप प्रोजेक्ट के आउटपुट डायरेक्टरी में नहीं है। लाइब्रेरी प्रोजेक्ट में इसका उपयोग करते समय यह महत्वपूर्ण है।
सेबेस्टियन क्रिम्समेंस्की

2
यह vs2008 के साथ रिलीज़ और डीबग मोड में निर्माण के लिए बहुत अच्छा काम करता है, लेकिन एक क्लिक प्रकाशन का उपयोग करते समय यह काम नहीं करता है। कोई सुझाव?
सोहने

2
Vs2015 में मेरे लिए काम नहीं किया। पुनर्लेखन लक्ष्य द्वारा थोड़ा सा तय किया गया: <Target Name="RootOutputCopyTarget" AfterTargets="Build">... </ लक्ष्य>
lorond

44

यदि आप एक टेक्स्ट एडिटर में .csproj / .vbproj को एडिट करते हैं, तो आप यह नियंत्रित कर सकते हैं कि आउटपुट डायरेक्टरी में फाइल को कहां रखा जाए और आउटपुट डायरेक्टरी में फाइल का क्या नाम होगा। उदाहरण के लिए:

<None Include="content\someContent.txt">
  <Link>someContentInOutputDirectory.txt</Link>
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

यह फ़ाइल content\someContent.txtमें डाल देगा bin\someContentInOutputDirectory.txt। आप चाहें binतो एक उपनिर्देशिका भी चुन सकते हैं; बस इसे लिंक तत्व में जोड़ें।


3
वाह, क्या मैं भाग्यशाली था कि अब दो दिन पहले इसकी आवश्यकता थी। धन्यवाद; यह महान है!
अशेरह

2
हे भगवान, धन्यवाद। मैंने अभी 6 घंटे बिताए हैं कि कुछ कोने-मामले के कचरे को ठीक करने की कोशिश की जा रही है जहाँ वी.एस. एक बुद्धिमान तरीके से .dll की नकल नहीं कर रहा है। यह जीवन, ब्रह्मांड और सब कुछ का वास्तविक उत्तर है।
ब्रैंडन

5
यह अब तक का सबसे अच्छा समाधान है
फिल्ड

1
मैंने एक बार ऐसा करने के बाद पाया और दृश्य स्टूडियो में प्रोजेक्ट को फिर से लोड किया, निर्भरता फाइलें समाधान एक्सप्लोरर से गायब हो गईं जैसे कि परियोजना में शामिल नहीं किया गया। हालांकि यह अभी भी उम्मीद के मुताबिक बनाता है, और आउटपुट को वांछित के रूप में कॉपी करता है। काम के इर्द-गिर्द मैं वर्तमान में प्रत्येक फ़ाइल को दो बार जोड़ रहा हूँ; एक बार बिना किसी क्रिया के, और एक बार 'कॉपी टू आउटपुट' सेट के साथ।
Éलिट्टे

1
यह इस टैग का इच्छित उपयोग नहीं है। VS2013 में, यह प्रोजेक्ट लोड करते समय एक चेतावनी फेंकता है, और फ़ाइल प्रोजेक्ट में जोड़ा नहीं जाता है क्योंकि यह प्रोजेक्ट डायरेक्टरी है।
jpmc26

15

मेरा मानना ​​है कि XCOPY कमांड निर्देशिकाओं और फाइलों को बेहतर तरीके से संभालती है। इसलिए,

    XCOPY "$(ProjectDir)common/browserhawk" "$(TargetDir)" /E /I /F /Y

जो लक्ष्य निर्देशिका से फ़ोल्डर बनाने की अनुमति देता है।

    XCOPY "$(ProjectDir)Templates" "$(TargetDir)" /E /I /F /Y

प्रोजेक्ट फ़ोल्डर / फ़ाइल संरचना:

    A:\TEMP\CONSOLEAPPLICATION3\TEMPLATES
    ├───NewFolder1
    ├───NewFolder2
    │       TextFile1.txt
    │       TextFile2.txt
    └───NewFolder3
            TextFile1.txt
            TextFile2.txt
            TextFile3.txt

हो जाता है:

    A:\TEMP\CONSOLEAPPLICATION3\BIN\DEBUG
    │   ConsoleApplication3.exe
    │   ConsoleApplication3.pdb
    │   ConsoleApplication3.vshost.exe
    │   ConsoleApplication3.vshost.exe.manifest
    ├───NewFolder1
    ├───NewFolder2
    │       TextFile1.txt
    │       TextFile2.txt
    │
    └───NewFolder3
            TextFile1.txt
            TextFile2.txt
            TextFile3.txt

/Dसंभावित बदलावों से बचने के लिए भी उपयोगी हो सकता है।
कुरजामेदेटल

10

अपने .csproj / .vbproj फ़ाइल में निम्न जोड़ें

<Target Name="AfterBuild">
    <Copy
        DestinationFolder="$(OutputPath)"
        SourceFiles="@(RootContent)"
        SkipUnchangedFiles="true"
        />  
</Target>

फिर रूट फ़ोल्डर में किसी भी फाइल के रूट एक्शन को रूटकॉन्टेंट में बदलें।


संवादों के माध्यम से नहीं ... लेकिन आप वीएस में अपनी परियोजना को संपादित कर सकते हैं। प्रोजेक्ट पर राइट-क्लिक करें और अनलोड प्रोजेक्ट चुनें। फिर राइट क्लिक करें और एडिट चुनें। तब आप MSBuild फ़ाइल को संपादित कर सकते हैं जो आपकी परियोजना है।
पॉल अलेक्जेंडर

2
धन्यवाद, यह उपयोगी दिखता है। दुर्भाग्य से, अपने स्निपेट को .vbproj फ़ाइल में जोड़ने के बाद भी, RootContent"बिल्ड एक्शन" ड्रॉपडाउन सूची में दिखाई नहीं देता है और इसे मैन्युअल रूप से दर्ज करने से विजुअल स्टूडियो से "संपत्ति का मूल्य मान्य नहीं होता है" त्रुटि हो जाती है। मुझसे क्या छूट गया?
हेनजी

Visual Studio 2010 C # कंसोल एप्लिकेशन प्रोजेक्ट के साथ काम नहीं कर रहा है।
एमीसिको

Visual Studio 2010 VB.NET कंसोल अनुप्रयोग प्रोजेक्ट के साथ काम नहीं कर रहा है।
AMissico

विजुअल स्टूडियो 2008 C # कंसोल एप्लिकेशन प्रोजेक्ट के साथ काम नहीं कर रहा है।
एमीसिको

5

मैंने इसका उपयोग VS2010, VS2015, VS2017 और VS2019 में किया है। मैं इस समाधान को पसंद करता हूं क्योंकि:

  1. XML किसी भी परियोजना में पुन: प्रयोज्य है
  2. "RootContent" को विजुअल स्टूडियो UI में बिल्ड एक्शन के रूप में चुना गया है, किसी अन्य "कंटेंट" की तरह
  3. "CopyToOutputDirectory" का पालन किया जाता है, जैसा कि आप उम्मीद करेंगे
  4. RootContent को प्रोजेक्ट के आउटपुट में जोड़ा जाता है: प्रोजेक्ट-रेफरेंस के माध्यम से किया जाता है, "क्लीन", आदि का पालन करता है।
  5. RootContent को वाइल्डकार्ड के साथ निर्दिष्ट किया जा सकता है, पुनरावर्ती फ़ोल्डर संरचना को संरक्षित करते हुए:
<RootContent Include="common\browserhawk\**">
  <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</RootContent>

प्रोजेक्ट फ़ाइल की शुरुआत में:

  <ItemGroup>
    <AvailableItemName Include="RootContent">
      <!-- Add "RootContent" as a choice in the "Build Action" dropdown. -->
      <Visible>True</Visible>
    </AvailableItemName>
  </ItemGroup>

इस उत्तर से उधार लिया गया

Microsoft .targets आयात के बाद:

  <PropertyGroup>
    <AssignTargetPathsDependsOn>
      $(AssignTargetPathsDependsOn);
      IncludeRootContentAsContent;
    </AssignTargetPathsDependsOn>
  </PropertyGroup>
  <Target Name="IncludeRootContentAsContent">
    <CreateItem Include="@(RootContent)" AdditionalMetadata="TargetPath=%(RecursiveDir)%(Filename)%(Extension)">
      <Output ItemName="ContentWithTargetPath" TaskParameter="Include" />
    </CreateItem>
  </Target>

इस उत्तर से उधार लिया गया


यह अच्छा है - मैं बाहर स्वैप करना होगा RootContentजो CustomContentइंगित करता है कि "हार्ड कोडित" यह इंगित करने के लिए है कि यह विशेष सामग्री है जिसे हम इस परियोजना में जोड़ रहे हैं और हमें इस विशेष तरीके से कॉपी करने की आवश्यकता है। एक तरफ के रूप में, मुझे TargetPath=%(RecursiveDir)%(Filename)%(Extension)निर्दिष्ट संरचना से CustomContentआउटपुट पथ पर फ़ोल्डर संरचना को फिर से बनाने की आवश्यकता थी ।
जोनो

@ जोंनो का लक्ष्य है कि रिकर्सिवडायरेरी की परवाह किए बिना फ़ाइल को सीधे रूट आउटपुट डायरेक्टरी में कॉपी करें। अंतर्निहित "सामग्री" बिल्ड एक्शन पहले से ही हमें RecursiveDirectory को बनाए रखते हुए कॉपी करने के लिए एक तंत्र प्रदान करता है।
मैटरगर्ल

मुझे थोड़ी देर में इसका परीक्षण करने का मौका नहीं मिला, लेकिन "कंटेंट" बनाने की कार्रवाई नहीं होगी क्योंकि ओपी के अनुसार /common/browserhawk/कॉपी की जाने वाली फाइलों के तहत कार्रवाई का कारण बनना चाहिए /bin/common/browserhawk/? IIRC, मेरा इरादा /common/browserhawk/a.txtअंत तक था, /bin/a.txtलेकिन वहाँ से पुनरावृत्ति की अनुमति देता है, इसलिए में /common/browserhawk/secret/stuff.pngसमाप्त होता है /bin/secret/stuff.png
जोनो

@ जोंनो ठीक है, हाँ, अब कुल समझ में आता है। मैंने शामिल करने के उत्तर को अपडेट किया %(RecursiveDirectory)। यह वास्तव में अच्छा है, क्योंकि आईडीई में व्यक्तिगत फ़ाइलों का चयन करने के अलावा, आप वाइल्डकार्ड के साथ कई फाइलें भी निर्दिष्ट कर सकते हैं। **वाइल्डकार्ड का उपयोग करते समय , संपूर्ण फ़ोल्डर संरचना संरक्षित की जाएगी।
मैटगर्ल

1
ऐसे महान उत्तर के लिए बहुत बहुत धन्यवाद! मुझे लगता है कि यह उत्तर निम्नलिखित के कारण सही उत्तर है: 1. कोई बाहरी सीढ़ियां नहीं हैं। 2. क्रॉस प्लेटफॉर्म
जॉर्ज

2

मैं सफल निर्माण के बाद नकल करने के लिए नांट बिल्ड फ़ाइल में एक कदम जोड़कर समाप्त हुआ

<target name="action.copy.browserhawk.config" depends="compile.source">
    <copy todir="${App.Web.dir}/bin/" includeemptydirs="false">
        <fileset basedir="${browserhawk.config.dir}">
            <include name="bhawk_bb.dat" />
            <include name="bhawk_sp.dat" />
            <include name="browserhawk.properties" />
            <include name="maindefs.bdd" />
            <include name="maindefs.bdf" />
            <include name="BH_PRO.lic" />
        </fileset>
    </copy>
    <echo message="COPY BROWSERHAWK CONFIG: SUCCESS   ${datetime::now()}" />
</target>

2
+1 क्योंकि कोई व्यक्ति नेंट का उपयोग करता है, यह अभी भी एक उपयोगी उत्तर है
क्रिस हैन्स

1

आप फ़ाइलों की प्रतिलिपि बनाने और इसे पोस्ट-बिल्ड ईवेंट के रूप में निष्पादित करने के लिए एक बैच फ़ाइल बना सकते हैं।


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