2012-03-01 15 views
15

पृष्ठभूमि: मैं काफी बड़े समाधान का प्रबंधन करता हूं। हर बार, लोग समाधान में एक परियोजना के लिए एक डीएलएल संदर्भ जोड़ते हैं जहां उन्हें एक परियोजना संदर्भ जोड़ा जाना चाहिए था। मैं इस तरह के मामले में एक चेतावनी जारी करना चाहता हूँ। मैं अपने हिंटपाथ * में 'bin \ debug' के साथ सभी संदर्भ ढूंढकर ऐसा करना चाहता हूं। मुझे पता है कि संदर्भ मेटाडाटा "हिंटपाथ" के साथ आइटम ग्रुप में आइटम हैं।मेटाडेटा मानों पर आइटम फ़ंक्शंस का उपयोग

मैं काम करने के लिए कुछ इस तरह की उम्मीद:

<Warning Text="Reference %(Reference.Identity) should be a project reference. HintPath: %(Reference.HintPath)" 
     Condition="%(Reference.HintPath).IndexOf('bin\debug') != -1"/> 

हालांकि, लगता है जैसे मैं उस तरह स्ट्रिंग समारोह indexOf उपयोग नहीं कर सकते। मैंने उपरोक्त के कई क्रमिक प्रयास किए बिना सफलता की कोशिश की।

  • संपादित करें: मुझे पता है कि यह चेक पूर्ण-प्रमाण नहीं है, लेकिन मैं केवल ईमानदार गलतियों को कम करना चाहता हूं।

उत्तर

18

MSBuild 4.0 Property Functions का उपयोग करते हुए यह स्ट्रिंग तुलना करने के लिए संभव है:

<Target Name="AfterBuild"> 

    <Message Text="Checking reference... '%(Reference.HintPath)'" Importance="high" /> 

    <Warning Text="Reference %(Reference.Identity) should be a project reference. HintPath: %(Reference.HintPath)" 
      Condition="$([System.String]::new('%(Reference.HintPath)').Contains('\bin\$(Configuration)'))" /> 

</Target> 
+1

+1: मैं आइटम मेटाडेटा से एक संपत्ति प्राप्त करने में था, कि मुझे यह स्पष्ट चीज़ नहीं दिखाई दे रही थी। असल में, आपकी विशिष्ट आवश्यकता को देखते हुए, यह बहुत बेहतर दिखता है। –

+0

मेरे लिए काम करता है। काश मैं केस-असंवेदनशील लुकअप कर सकता हूं - इंडेक्सऑफ ('\ bin \ $ (कॉन्फ़िगरेशन)', स्ट्रिंग कॉम्परिसन। ऑर्डिनल इग्नोरकेस) - लेकिन एमएसबिल्ड ओवरलोड के साथ फ़ंक्शंस का आह्वान करने में सक्षम नहीं प्रतीत होता है। – Jonathan

+0

+1 जब मैं गलत तरीके से इस मुद्दे को हल करने की कोशिश कर रहा था, मैंने इस विचार के बारे में सोचा, लेकिन एहसास नहीं हुआ, स्ट्रिंग ऑब्जेक्ट को तुरंत कैसे चालू करें (वास्तव में, मैं सी # में बहुत धाराप्रवाह नहीं हूं)। समाधान के लिए धन्यवाद। –

2

पहले नहीं है कि अपने वाक्य रचना कार्यों लागू करने के लिए सही नहीं है, यह अवश्य होना चाहिए कि:

%(Reference.HintPath.IndexOf(...))  # Note: not supported by MSBuild 

हालांकि, MSBuild में संपत्ति कार्यों not allowed आइटम मेटाडाटा पर कर रहे हैं, ताकि मदद करने के लिए नहीं जा रहा है आप या तो।

एक अलग लक्ष्य का आह्वान करके आप इसके आसपास क्या काम कर सकते हैं, जिसे मूल रूप से प्रत्येक आइटम के लिए बुलाया जाता है।

<Target Name="CheckProjectReferences"> 
    <MSBuild 
     Projects="$(MSBuildProjectFullPath)" 
     Properties="Identity=%(Reference.Identity);HintPath=%(Reference.HintPath)" 
     Targets="_Warn"/> 
    </Target> 

    <Target Name="_Warn"> 
    <Warning Text="Reference $(Identity) should be a project reference. HintPath: $(HintPath)" 
      Condition="$(HintPath.IndexOf('bin\debug')) != -1"/> 
    </Target> 

सच कहूं, मुझे लगता है कि अगर सब कुछ "उल्लंघन" को पकड़ने के लिए पर्याप्त है यकीन नहीं है। उदाहरण के लिए, उपरोक्त केवल bin\debug के लिए काम करेगा, लेकिन bin\Debug या अन्य मिश्रित-आधारित विविधताओं के लिए नहीं, जो कार्यात्मक रूप से समकक्ष हैं। साथ ही उन्हें देखने के लिए, आपको, IndexOf(string, StringComparison) अधिभार कॉल करने के लिए आवश्यकता होगी लेकिन अभी कर रही:

$(HintPath.IndexOf('bin\debug', System.StringComparison.OrdinalIgnoreCase)) 

काम नहीं करेगा, क्योंकि MSBuild अधिभार संकल्प IndexOf(char, Int32) लेने और आपको यह त्रुटि दे देंगे:

MSB4184: The expression ""bin\debug".IndexOf(bin\debug, System.StringComparison.OrdinalIgnoreCase)" cannot be evaluated. String must be exactly one character long.

तुम भी 012 के लिए जाँच करने के लिए आवश्यकता हो सकती है

$(HintPath.IndexOf('bin\debug', 0, 9, System.StringComparison.OrdinalIgnoreCase)) 

:

तो, आप IndexOf(String, Int32, Int32, StringComparison) अधिभार सीधे का उपयोग करके इसे समझाने के लिए की आवश्यकता होगीया अन्य विविधताएं। मुझे यकीन नहीं है कि संदर्भ का पता लगाने का यह सबसे अच्छा तरीका एक परियोजना संदर्भ होना चाहिए, लेकिन यदि आप जानते हैं (और एक निश्चित विस्तार नियंत्रण) आपके पर्यावरण को संभव हो सकता है।

+0

यह हालांकि मैं HintPath बिना refs के लिए एक अतिरिक्त शर्त की जरूरत है, काम करने के लिए लगता है। हालांकि, प्रत्येक संदर्भ के लिए msbuild का आह्वान धीमा है - मेरा समाधान 2 सेकंड से 34 सेकेंड तक धीमा हो गया है! यदि एक ही एमएसबिल्ड उदाहरण में ऐसा करने का कोई तरीका नहीं है, तो यह मेरे लिए इसके लायक नहीं है। – Jonathan

+0

@ जोनाथन मैं उसी एमएसबिल्ड उदाहरण में ऐसा करने का एक तरीका खोजने की कोशिश कर रहा था, लेकिन किसी को भी नहीं मिला (शायद अपना खुद का कार्य लिखने से कम)। –

0

@ Christian.K सही अपने विश्लेषण में है। एक अन्य समाधान के भावों का &quot; का उपयोग कर प्रकार स्ट्रिंग की अधिभार मजबूर करने के लिए होगा:

<Warning 
    Text="..." 
    Condition="$(HintPath.IndexOf(&quot;bin\debug&quot;, System.StringComparison.OrdinalIgnoreCase)) != -1" /> 
संबंधित मुद्दे