2011-09-23 8 views
20

एक बार फिर मैं एमएसबिल्ड से जूझ रहा हूं। मैं एक रूट पथ के साथ परिभाषित एक संपत्ति मूल्य चाहते हैं। निर्माण के हिस्से के रूप में, पथ संस्करण जानकारी के साथ अद्यतन हो जाएगा। हालांकि, एमएसबिल्ड के पास अपने स्वयं के स्कोपिंग नियम हैं जो पूरी तरह पीछे की तरफ लगते हैं।एमएसबिल्ड संपत्ति स्कोप

<?xml version="1.0" encoding="utf-8"?> 
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> 

    <PropertyGroup> 
    <MyPath>\\server\path</MyPath> 
    </PropertyGroup> 

    <Target Name="Main"> 
    <Message Text="In Main Before - MyPath = $(MyPath)"/> 
    <PropertyGroup> 
     <MyPath>$(MyPath)\version5</MyPath> 
    </PropertyGroup> 
    <Message Text="In Main After PropertyGroup - MyPath = $(MyPath)"/> 
    <CallTarget Targets="Task1" /> 
    <CallTarget Targets="Task2" /> 
    <CallTarget Targets="Task3" /> 
    <Message Text="In Main After - MyPath = $(MyPath)"/> 
    </Target> 

    <Target Name="Task1"> 
    <Message Text="In Task1 - MyPath = $(MyPath)"/> 
    </Target> 

    <Target Name="Task2"> 
    <Message Text="In Task2 - MyPath = $(MyPath)"/> 
    </Target> 

    <Target Name="Task3"> 
    <Message Text="In Task3 - MyPath = $(MyPath)"/> 
    </Target> 

</Project> 
: msbuild PropertyScopeTest1.proj /target:Main

Project "C:\Temp\PropertyScopeTest1.proj" on node 1 (Main target(s)). 
Main: 
    In Main Before - MyPath = \\server\folder 
Task1: 
    In Task1 - MyPath = \\server\folder\version5 
Task2: 
    In Task2 - MyPath = \\server\folder\version5 
Task3: 
    In Task3 - MyPath = \\server\folder\version5 
Main: 
    In Main After - MyPath = \\server\folder 
Done Building Project "C:\Temp\PropertyScopeTest1.proj" (Main target(s)). 

अब, यहाँ एक अलग मुख्य लक्ष्य में MyPath चर की स्थापना संस्करण है:

<?xml version="1.0" encoding="utf-8"?> 
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> 

    <PropertyGroup> 
    <MyPath>\\server\folder</MyPath> 
    </PropertyGroup> 

    <Target Name="Main"> 
    <Message Text="In Main Before - MyPath = $(MyPath)"/> 
    <CallTarget Targets="Task1" /> 
    <CallTarget Targets="Task2" /> 
    <CallTarget Targets="Task3" /> 
    <Message Text="In Main After - MyPath = $(MyPath)"/> 
    </Target> 

    <Target Name="Task1"> 
    <PropertyGroup> 
     <MyPath>$(MyPath)\version5</MyPath> 
    </PropertyGroup> 
    <Message Text="In Task1 - MyPath = $(MyPath)"/> 
    </Target> 

    <Target Name="Task2"> 
    <Message Text="In Task2 - MyPath = $(MyPath)"/> 
    </Target> 

    <Target Name="Task3"> 
    <Message Text="In Task3 - MyPath = $(MyPath)"/> 
    </Target> 

</Project> 

यहाँ इस कमांड लाइन के साथ उत्पादन है: यह पहली उदाहरण लें

यहां इस कमांड लाइन के साथ आउटपुट है: msbuild PropertyScopeTest2.proj /target:Main

Project "C:\Temp\PropertyScopeTest2.proj" on node 1 (Main target(s)). 
Main: 
    In Main Before - MyPath = \\server\path 
    In Main After PropertyGroup - MyPath = \\server\path\version5 
Task1: 
    In Task1 - MyPath = \\server\path 
Task2: 
    In Task2 - MyPath = \\server\path 
Task3: 
    In Task3 - MyPath = \\server\path 
Main: 
    In Main After - MyPath = \\server\path\version5 
Done Building Project "C:\Temp\PropertyScopeTest2.proj" (Main target(s)). 

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

उत्तर

23

भवन का उपयोग कर बुलाया लक्ष्य के लिए सुलभ नहीं कर रहे हैं, लक्ष्य है कि नए पथ निर्भरता सेट बनाने के बजाय का उपयोग कर

<?xml version="1.0" encoding="utf-8"?> 
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> 

    <PropertyGroup> 
    <MyPath>\\server\folder</MyPath> 
    </PropertyGroup> 

    <Target Name="Main" DependsOnTargets="SetMyPathProperty"> 
    <Message Text="In Main Before - MyPath = $(MyPath)"/> 
    <CallTarget Targets="Task1" /> 
    <Message Text="In Main After - MyPath = $(MyPath)"/> 
    </Target> 

    <Target Name="SetMyPathProperty"> 
    <PropertyGroup> 
     <MyPath>$(MyPath)\version5</MyPath> 
    </PropertyGroup> 
    </Target> 

    <Target Name="Task1"> 
    <Message Text="In Task1 - MyPath = $(MyPath)"/> 
    </Target> 

</Project> 

आउटपुट बिल्ड:

Main: 
    In Main Before - MyPath = \\server\folder\version5 
Task1: 
    In Task1 - MyPath = \\server\folder\version5 
Main: 
    In Main After - MyPath = \\server\folder\version5 
अपेक्षित व्यवहार निकलेगा

बनाना SetMyPathProperty की Task1के बजाय मुख्य अपने PropertyScopeTest1.proj के समान व्यवहार का परिणाम देगा निर्भरता।

+0

यह समाधान मुझे और अधिक समझ में आता है। मैं कल यह कोशिश करने की योजना बना रहा हूं और देख सकता हूं कि यह मेरे उपयोग के मामले में काम करेगा या नहीं। – dprice

+0

बस इस समाधान की कोशिश की और यह वही है जो मैं चाहता था। बहुत बहुत धन्यवाद! – dprice

16

यह एक बहुत ही दिलचस्प सवाल जो निम्न आलेख में उदाहरण के साथ गहराई से जांच की जाती है: Scope of properties and item in an MSBuild script

मूल रूप से वहाँ एक स्थानीय और वैश्विक संदर्भ के साथ चाल हैं लक्ष्य फांसी भर में स्विच:

  • एक प्रोजेक्ट क्लास का उदाहरण स्क्रिप्ट के लिए बनाया गया है और में वैश्विक संदर्भ में गुणों और वस्तुओं के सभी मान शामिल हैं।
  • जब कोई लक्ष्य निष्पादित किया जाता है, तो वैश्विक संदर्भ स्थानीय संदर्भ में कॉपी किया जाता है जिसका उपयोग लक्ष्य द्वारा किया जाएगा।
  • एक लक्ष्य निष्पादन समाप्त होता है, स्थानीय संदर्भ अपडेट को वैश्विक संदर्भ में वापस विलय कर दिया जाता है।
  • लक्ष्य निष्पादन तक समाप्त हो गया है स्थानीय अपडेट SLL के जवाब पर CallTarget या MSBuild कार्य