Msbuild का उपयोग करके सभी फ़ाइलों और फ़ोल्डरों को कॉपी करें


93

बस सोच रहा था कि कोई मुझे कुछ msbuild स्क्रिप्ट के साथ मदद कर सकता है जिसे मैं लिखने की कोशिश कर रहा हूं। मैं जो करना चाहूंगा वह सभी फाइलों और उप फ़ोल्डरों को एक फ़ोल्डर से दूसरे फ़ोल्डर में msbuild का उपयोग करके कॉपी करना है।

{ProjectName}
      |----->Source
      |----->Tools
              |----->Viewer
                       |-----{about 5 sub dirs}

मुझे जो करने में सक्षम होना चाहिए वह एप्लिकेशन के लिए डिबग फ़ोल्डर में टूल फ़ोल्डर से सभी फाइलों और उप फ़ोल्डरों को कॉपी करना है। यह वह कोड है जो मेरे पास अब तक है।

 <ItemGroup>
<Viewer Include="..\$(ApplicationDirectory)\Tools\viewer\**\*.*" />
 </ItemGroup>

<Target Name="BeforeBuild">
        <Copy SourceFiles="@(Viewer)" DestinationFolder="@(Viewer->'$(OutputPath)\\Tools')" />
  </Target>

बिल्ड स्क्रिप्ट चलती है, लेकिन किसी भी फाइल या फोल्डर को कॉपी नहीं करती है।

धन्यवाद

जवाबों:


132

मैं इस पर भी मदद खोज रहा था। इसमें मुझे थोड़ा समय लगा, लेकिन यहां मैंने वही किया जो वास्तव में अच्छी तरह से काम किया।

<Target Name="AfterBuild">
    <ItemGroup>
        <ANTLR Include="..\Data\antlrcs\**\*.*" />
    </ItemGroup>
    <Copy SourceFiles="@(ANTLR)" DestinationFolder="$(TargetDir)\%(RecursiveDir)" SkipUnchangedFiles="true" />
</Target>

यह नाम के antlrcsलिए फ़ोल्डर की सामग्री को पुनरावर्ती रूप से कॉपी करता है $(TargetDir)


4
हां, यह सबसे अच्छा जवाब है। Msdn
Karsten

2
ठीक काम करता है - धन्यवाद! मुझे आश्चर्य है कि क्यों अन्य अधिक जटिल जवाब अधिक upvotes है ?!
इवान

17
चाल से लगता है कि %(RecursiveDir)गंतव्य फ़ोल्डर में जोड़ना निर्देशिका संरचना को फिर से बनाएगा। अन्यथा आउटपुट सपाट है। यह सबसे अच्छा जवाब है।
जेबी मोनिका के साथ।

1
.Fsproj फ़ाइल के नीचे रखा जाना चाहिए , या यह नहीं लेता है।
हेनरिक

यहां मेरे लिए काम करने वाले महत्वपूर्ण क्षण चर घोषणा ( <ANTLR शामिल करें = ".. \ Data \ antrrcs ***। *" "/> ) के बाद AfterBuild लक्ष्य है। मेरे मामले में यह बाहरी दायरे में घोषित किया गया और काम नहीं किया।
5

71

मुझे लगता है कि समस्या यह हो सकती है कि आप अपना ItemGroup कैसे बना रहे हैं और कॉपी कार्य को कॉल कर रहे हैं। देखें कि क्या यह समझ में आता है:

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
    <PropertyGroup>
        <YourDestinationDirectory>..\SomeDestinationDirectory</YourDestinationDirectory>
        <YourSourceDirectory>..\SomeSourceDirectory</YourSourceDirectory>
    </PropertyGroup>

    <Target Name="BeforeBuild">
        <CreateItem Include="$(YourSourceDirectory)\**\*.*">
            <Output TaskParameter="Include" ItemName="YourFilesToCopy" />
        </CreateItem>

        <Copy SourceFiles="@(YourFilesToCopy)"
                DestinationFiles="@(YourFilesToCopy->'$(YourDestinationDirectory)\%(RecursiveDir)%(Filename)%(Extension)')" />
    </Target>
</Project>

CreateItemकार्य पदावनत है। रेगेक्स का विकल्प है। msdn.microsoft.com/en-us/library/s2y3e43x.aspx
रे चेंग

35

मैं MSBuild के लिए नया हूँ, लेकिन मैं इन जैसी स्थिति के लिए EXEC टास्क को आसान मानता हूँ। मैं अपनी परियोजना में एक ही चुनौती के पार आया और यह मेरे लिए काम किया और बहुत सरल था। अगर कोई अच्छा अभ्यास नहीं है तो कृपया मुझे बताएं।

<Target Name="CopyToDeployFolder" DependsOnTargets="CompileWebSite">
    <Exec Command="xcopy.exe  $(OutputDirectory) $(DeploymentDirectory) /e" WorkingDirectory="C:\Windows\" />
</Target>

9
मैं इस प्रश्न को दूसरे तरीके से पूछने का साहस करता हूं। क्या कभी कोई कारण है कि लॉग फिलिंग का उपयोग करने के लिए msbuild कॉपी कार्य करना है?
bernd_k

4
संभावित। यदि आपके पास बिल्ड फ़ार्म (जेनकिंस, टीमसिटी आदि) है, तो एजेंट सेवा एक अलग खाते के तहत चल सकती है जिसमें पथ में xcopy नहीं है। आप रास्ते में% windir% \ system32 जैसी चीजों की कोशिश कर सकते हैं, लेकिन यह भी कुछ समय काम नहीं करता है।
एंड्रयू डीए

यही वह उपाय है जो मेरे लिए काम करता है। इसके अलावा मुझे वर्कडायरेक्टरी की स्थापना की आवश्यकता नहीं है।
ऐब्सबिस

FYI करें, मुझे फ़ाइल / फ़ोल्डर ओवरराइड प्रॉम्प्ट को दबाने के लिए / Y जोड़ना होगा। इसके अलावा अगर $ (परिनियोजन अप्रत्यक्ष) एक फ़ोल्डर है, तो पथ को छोड़ने के बाद "\" को तुरंत हटा दिया जाएगा: "गंतव्य फ़ोल्डर या फ़ाइल है?"
होएंग लॉन्ग

6
मुझे पता है कि यह समस्या अक्सर सामने नहीं आती है, लेकिन Copyकमांड के बजाय कार्य का उपयोग करने का मेरा मुख्य कारण संगतता है। मैंने पहले मोनो का उपयोग करके लिनक्स पर निर्माण किया है, और स्पष्ट रूप से xcopyवहां काम नहीं करता है।
ग्रेग्रास

12
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
    <PropertyGroup>
        <YourDestinationDirectory>..\SomeDestinationDirectory</YourDestinationDirectory>
        <YourSourceDirectory>..\SomeSourceDirectory</YourSourceDirectory>
    </PropertyGroup>

    <Target Name="BeforeBuild">
        <CreateItem Include="$(YourSourceDirectory)\**\*.*">
            <Output TaskParameter="Include" ItemName="YourFilesToCopy" />
        </CreateItem>

        <Copy SourceFiles="@(YourFilesToCopy)"
                DestinationFiles="$(YourFilesToCopy)\%(RecursiveDir)" />
    </Target>
</Project>

\**\*.*सभी फ़ोल्डर से फ़ाइलें प्राप्त करने में मदद करें। RecursiveDir संबंधित फ़ोल्डर में सभी फ़ाइल को रखने में मदद करता है ...


2
गंतव्य फ़ाइलें 1 आइटम को संदर्भित करती हैं और sourcefiles 33 आइटम को संदर्भित करता है। उनके पास सामानों की संख्या समान होनी चाहिए। ऊघ .. msbuild कमाल हो सकता है, लेकिन कभी-कभी कबाड़ का ऐसा खराब दस्तावेज।
मफिन मैन

CreateItemकार्य पदावनत है। रेगेक्स का विकल्प है। msdn.microsoft.com/en-us/library/s2y3e43x.aspx
रे चेंग

4

क्या आपने इसके बजाय ठोस गंतव्य निर्देशिका निर्दिष्ट करने का प्रयास किया

DestinationFolder="@(Viewer->'$(OutputPath)\\Tools')" ? 

मैं उन्नत MSBuild वाक्यविन्यास के साथ बहुत कुशल नहीं हूँ, लेकिन

@(Viewer->'$(OutputPath)\\Tools') 

मुझे अजीब लगता है। स्क्रिप्ट अच्छी लग रही है, इसलिए समस्या $(ApplicationDirectory)और के मूल्यों में हो सकती है$(OutputPath)

संपादित करें:

यहाँ एक ब्लॉग पोस्ट है जो उपयोगी हो सकती है:

कैसे करें: टास्क का इस्तेमाल करके फाइलों को दोबारा कॉपी करें


1
लिंक के लिए +1, जो अधिक संक्षिप्त है कि zXen से स्वीकृत उत्तर।
bernd_k

3

यह उदाहरण है कि काम किया है:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

   <ItemGroup>
      <MySourceFiles Include="c:\MySourceTree\**\*.*"/>
   </ItemGroup>

   <Target Name="CopyFiles">
      <Copy
        SourceFiles="@(MySourceFiles)"
        DestinationFiles="@(MySourceFiles->'c:\MyDestinationTree\%(RecursiveDir)%(Filename)%(Extension)')"
       />
    </Target>

</Project>

स्रोत: https://msdn.microsoft.com/en-us/library/3e54c37h.aspx


2

यह मेरी अपनी परियोजना में उपयोग की जाने वाली कॉपी कार्य है, यह मेरे लिए पूरी तरह से काम कर रहा था कि उप फ़ोल्डर के साथ फ़ोल्डर को सफलतापूर्वक गंतव्य करने के लिए कॉपी करता है:

<ItemGroup >
<MyProjectSource Include="$(OutputRoot)/MySource/**/*.*" />
</ItemGroup>

<Target Name="AfterCopy" AfterTargets="WebPublish">
<Copy SourceFiles="@(MyProjectSource)" 
 OverwriteReadOnlyFiles="true" DestinationFolder="$(PublishFolder)api/% (RecursiveDir)"/>

मेरे मामले में मैंने एक प्रोजेक्ट के प्रकाशित फ़ोल्डर को दूसरे गंतव्य फ़ोल्डर में कॉपी किया है, मुझे लगता है कि यह आपके मामले से परिचित है।



0

MSBuild का उपयोग करके फ़ाइलों को एक निर्देशिका से दूसरी निर्देशिका में पुन: कॉपी करने का सबसे अच्छा तरीका है SourceFiles और DestinationFiles के साथ प्रतिलिपि कार्य को मापदंडों के रूप में उपयोग करना। उदाहरण के लिए - बिल्ड डायरेक्टरी से लेकर बैक अप डायरेक्टरी तक सभी फाइलों को कॉपी करना होगा

<PropertyGroup>
<BuildDirectory Condition="'$(BuildDirectory)' == ''">Build</BuildDirectory>
<BackupDirectory Condition="'$(BackupDiretory)' == ''">Backup</BackupDirectory>
</PropertyGroup>

<ItemGroup>
<AllFiles Include="$(MSBuildProjectDirectory)/$(BuildDirectory)/**/*.*" />
</ItemGroup>

<Target Name="Backup">
<Exec Command="if not exist $(BackupDirectory) md $(BackupDirectory)" />
<Copy SourceFiles="@(AllFiles)" DestinationFiles="@(AllFiles-> 
'$(MSBuildProjectDirectory)/$(BackupDirectory)/%(RecursiveDir)/%(Filename)% 
(Extension)')" />
</Target>

अब ऊपर की प्रतिलिपि कमांड में सभी स्रोत निर्देशिकाओं का पता लगाया जाता है और गंतव्य निर्देशिका में फ़ाइलों की प्रतिलिपि बनाई जाती है।


0

यदि आप विशिष्ट C ++ टूलकिन के साथ काम कर रहे हैं, तो जाने का एक और तरीका है अपनी फ़ाइलों को मानक CopyFileToFolders सूची में जोड़ना।

<ItemGroup>
  <CopyFileToFolders Include="materials\**\*">
    <DestinationFolders>$(MainOutputDirectory)\Resources\materials\%(RecursiveDir)</DestinationFolders>
  </CopyFileToFolders>
</ItemGroup>

सरल होने के अलावा, यह जाने का एक अच्छा तरीका है क्योंकि CopyFilesToFolders कार्य उचित इनपुट, आउटपुट और यहां तक ​​कि TLog फाइलें उत्पन्न करेगा, इसलिए यह सुनिश्चित करना कि कॉपी ऑपरेशन तभी चलेगा जब इनपुट फ़ाइलों में से एक बदल गया है या आउटपुट फ़ाइलों में से एक गायब है। TLog के साथ, विज़ुअल स्टूडियो प्रोजेक्ट को "अप टू डेट" के रूप में ठीक से पहचान लेगा या नहीं (यह उसके लिए एक अलग U2DCheck तंत्र का उपयोग करता है)।

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