2008-11-05 8 views
7

मुझे अपने निर्माण को स्क्रिप्ट करने की आवश्यकता है। मैं MSBUILD का उपयोग कर रहा हूं क्योंकि यह VS.net के साथ एकीकरण है। मैं बिल्डिंग वातावरण से कुछ फ़ाइलों को तैनाती फ़ोल्डर में कॉपी करने की कोशिश कर रहा हूं। मैं एमएसबिल्ड के कॉपी कार्य का उपयोग कर रहा हूं। लेकिन निर्देशिका पेड़ की प्रतिलिपि बनाने की बजाय मैं अपेक्षा करता हूं। यह सभी सामग्रियों को एक फ़ोल्डर में कॉपी करता है। मैं एक फ़ोल्डर में निर्देशिका पेड़ से सभी फाइलों को दोहराता हूं। मुझे फ़ोल्डर फ़ोल्डर में फ़ोल्डर और निर्देशिका के पेड़ की प्रतिलिपि बनाने की आवश्यकता है। क्या मुझे कुछ याद आ रही है?एमएसबिल्ड कॉपी क्यों नहीं करता है क्योंकि मुझे उम्मीद है कि

यहाँ अपने निर्माण स्क्रिप्ट के प्रासंगिक भागों है:

<PropertyGroup> 
    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion> 
    <Source>outputfolder</Source> 
    <DestEnv>x</DestEnv> 
    <DeployPath>\\networkpath\$(DestEnv)</DeployPath> 
</PropertyGroup> 
<ItemGroup> 
    <TargetDir Include="$(DeployPath)\**\*" Exclude="**\web.config"></TargetDir> 
    <SourceDir Include="$(Source)\**\*" /> 
</ItemGroup>  
<Target Name="Clean" > 
    <!-- clean detail ... --> 
</Target> 
<Target Name="migrate" DependsOnTargets="Clean"> 
    <Copy DestinationFolder="$(DeployPath)" SourceFiles="@(SourceDir)" /> 
</Target> 

उत्तर

4

मैं MSDN में उदाहरणों में से एक में उदाहरण पाया मैं इसे समझ में नहीं आता, लेकिन stackoverflow में यहाँ मेरे साथी travlers के लिए एक उदाहरण छोड़ देंगे । यहां से माइग्रेट लक्ष्य का निश्चित संस्करण दिया गया है:

<Target Name="migrate" DependsOnTargets="Clean"> 
    <Copy DestinationFiles="@(SourceDir->'$(DeployPath)\%(RecursiveDir)%(Filename)%(Extension)')" SourceFiles="@(SourceDir)" /> 
</Target> 

यदि कोई वास्तव में इस उदाहरण को समझता है तो कृपया समझाएं। शुभ लाभ!

12

जब आप प्रतिलिपि कार्य के लिए गंतव्य फ़ॉल्डर निर्दिष्ट करते हैं, तो यह सभी आइटम स्रोतफ़ाइल संग्रह से लेता है और उन्हें गंतव्य फ़ोल्डर में कॉपी करता है। इसकी अपेक्षा की जाती है, क्योंकि कॉपी कार्य को पेड़ की संरचना को बनाए रखने के लिए प्रत्येक आइटम के पथ के किस भाग को गंतव्य फोल्डर के साथ प्रतिस्थापित करने की आवश्यकता होती है, इसका पता लगाने का कोई तरीका नहीं है। उदाहरण के लिए, यदि आपका SourceDir संग्रह इस प्रकार परिभाषित किया गया है:

<ItemGroup> 
    <SourceDir Include="$(Source)\**\*" /> 
    <SourceDir Include="E:\ExternalDependencies\**\*" /> 
    <SourceDir Include="\\sharedlibraries\gdiplus\*.h" /> 
</ItemGroup> 

गंतव्य फ़ोल्डर पेड़ की तरह आप क्या अपेक्षा करेंगे?

पेड़ को संरक्षित करने के लिए, आपको पहचान परिवर्तन करने और SourceFiles संग्रह में प्रत्येक आइटम के लिए एक गंतव्य आइटम उत्पन्न करने की आवश्यकता है। यहाँ एक उदाहरण है:

<Copy SourceFiles="@(Compile)" DestinationFiles="@(Compile->'$(DropPath)%(Identity)')" /> 

कॉपी कार्य SourceFiles संग्रह में प्रत्येक आइटम ले जाएगा, और $ (DropPath) के साथ स्रोत मद विनिर्देश में ** से पहले भाग की जगह अपने रास्ते बदल सकते हैं।

यह तर्क हो सकता है कि DestinationFolder संपत्ति निम्नलिखित परिवर्तन के लिए एक शॉर्टकट के रूप में लिखा गया है चाहिए:

<Copy SourceFiles="@(Compile)" DestinationFiles="@(Compile->'$(DestinationFolder)%(Identity)')" /> 

ओह, कि करने के लिए समतल फ़ोल्डर परिदृश्य गहरी प्रतिलिपि है कि आप से बचने के लिए कोशिश कर रहे हैं रोका जा सके, लेकिन अन्य लोग अपनी निर्माण प्रक्रिया में उपयोग कर सकते हैं।

5

बहुत ही सरल उदाहरण है कि प्रतियां एक निर्देशिका सामग्री और रिकर्सिवली संरचना:

<Copy SourceFiles="@(Compile)" DestinationFolder="c:\foocopy\%(Compile.RecursiveDir)"></Copy> 

@ (संकलित) सभी फ़ाइलें आप प्रतिलिपि बनाना चाहते का एक ItemGroup है। कुछ ऐसा हो सकता है:

<ItemGroup> 
     <Compile Include=".\**\*.dll" /> 
    </ItemGroup> 

कॉपी कार्य सभी फ़ाइलों को xcopy की तरह c: \ foocopy में कॉपी करेगा।

+0

<कॉपी SourceFiles = "$ (SourceViewsLocation)" DestinationFolder = "$ (RepositoryLocation) \% (RecursiveDir)"> त्रुटि देता है आइटम मेटाडाटा% (RecursiveDir) एक बिना संदर्भित किया जा रहा है वस्तु का नाम। % (Itemname.RecursiveDir) का उपयोग करके आइटम का नाम निर्दिष्ट करें। –

+0

मेरे पास कोई संकेत नहीं है कि –

+1

पर क्या चल रहा है बग तय होना चाहिए ... गंतव्य के मूल्य के लिए वैकल्पिक वाक्यविन्यास: गंतव्य फ़ॉल्डर = "@ (संकलन -> 'सी: \ foocopy \% (रिकर्सिव डीआईआर)') – Adam

13

बस एक मणि हमने पाया के रूप में हम नकल के आसपास MSBuild मुद्दों की डिबगिंग गया:

http://blog.scrappydog.com/2008/06/subtle-msbuild-bug-feature.html

ItemGroups, लक्ष्य से पहले पार्स कर रहे हैं ताकि किसी भी लक्ष्य है कि नई फ़ाइलें बनाएं (उदा कम्पाइल हो गया!) जब एक आइटम समूह को स्क्रिप्ट के साथ आगे संदर्भित किया जाता है तब नहीं उठाया जाएगा। उसे

<Target Name="Copy" > 
    <CreateItem Include="..\Source\**\bin\**\*.exe" 
     Exclude="..\Source\**\bin\**\*.vshost.exe"> 
     <Output TaskParameter="Include" ItemName="CompileOutput" /> 
    </CreateItem> 
    <Copy SourceFiles="@(CompileOutput)" 
     DestinationFolder="$(OutputDirectory)"></Copy> 
</Target> 

कई प्रशंसा:

एरिक बोवेन भी CreateItem कार्य इस "सुविधा" के लिए एक काम के आसपास का वर्णन करता है! MSBuild: त्रुटि MSB4095: