2012-12-19 29 views
8

मुझे पता है कि Powershell, .NET कोड कॉल कर सकते हैं इसमैं ओवरलोडेड .NET फ़ंक्शन को कैसे कॉल कर सकता हूं जो पावरहेल से सी # आउट तर्क का उपयोग करता है?

PS> [Reflection.Assembly]::LoadFile(($ScriptDir + ".\SharpSvn-x64\SharpSvn.dll")) 
PS> $SvnClient = New-Object SharpSvn.SvnClient 

की तरह लग रहे हो सकता है और मुझे पता है कि जहां सी # out तर्क हैं, तो Powershell [ref] तर्क है, जो इस प्रकार दिखाई देंगे है:

PS> $info = $null 
PS> $SvnClient.GetInfo($repo.local, ([ref]$info)) 

True 

PS> $info 

(...long output snipped...) 
NodeKind   : Directory 
Revision   : 16298 
Uri    : http://server/path/to/remoterepo 
FullPath   : C:\path\to\localrepo 
(...long output snipped...) 

और मुझे पता है कि सी # में आप कार्यों को ओवरलोड कर सकते हैं, SharpSvn पुस्तकालय की तरह अपने SvnClient.Update() method के लिए करता है:

  1. Update(ICollection(String)) - रिकर्सिवली नवीनतम (सिर) संशोधन
  2. Update(String) करने के लिए निर्दिष्ट पथ अपडेट - रिकर्सिवली नवीनतम (सिर) संशोधन
  3. Update(ICollection(String), SvnUpdateArgs) को निर्दिष्ट पथ अपडेट - निर्दिष्ट संशोधन
  4. Update(ICollection(String), SvnUpdateResult) करने के लिए निर्दिष्ट पथ अपडेट - रिकर्सिवली अद्यतन करता है नवीनतम (सिर) संशोधन
  5. Update(String, SvnUpdateArgs) करने के लिए निर्दिष्ट पथ - रिकर्सिवली नवीनतम (सिर) के लिए निर्दिष्ट पथ अद्यतन करता Revi - रिकर्सिवली निर्दिष्ट पथ
  6. Update(String, SvnUpdateResult) अद्यतन करता है सायन
  7. Update(ICollection(String), SvnUpdateArgs, SvnUpdateResult) - अपडेट निर्दिष्ट संशोधन
  8. Update(String, SvnUpdateArgs, SvnUpdateResult) करने के लिए निर्दिष्ट पथ - रिकर्सिवली नवीनतम (सिर) संशोधन

लेकिन करने के लिए निर्दिष्ट पथ अद्यतन करता है, अगर हम यह सब एक साथ रखना चाहते हैं? यदि, कहें, मैं Update() का 6 वां संस्करण कॉल करना चाहता हूं, जो स्ट्रिंग और एक SvnUpdateResult लेता है, जहां SvnUpdateResult एक C# आउट ऑब्जेक्ट है? मेरा पहला वृत्ति इस तरह कुछ करने की कोशिश कर रहा था:

PS> $repopath = "C:\path\to\localrepo" 
PS> $update = $null 
PS> $svnclient.update($repopath, [ref]$update) 

Multiple ambiguous overloads found for "Update" and the argument count: "2". 
At line:1 char:18 
+ $svnclient.update <<<< ($repopath, [ref]$update) 
    + CategoryInfo   : NotSpecified: (:) [], ParentContainsErrorRecordException 
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest 

ठीक है, शायद मुझे तर्क डालना होगा?

PS> $svnclient.update([string]$repopath, [ref][SharpSvn.SvnUpdateResult]$update) 

Multiple ambiguous overloads found for "Update" and the argument count: "2". 
At line:1 char:18 
+ $svnclient.update <<<< ([string]$repopath, [ref][SharpSvn.SvnUpdateResult]$update) 
    + CategoryInfo   : NotSpecified: (:) [], ParentContainsErrorRecordException 
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest 

लेकिन ऐसा लगता है कि यह भी काम नहीं करता है। अन्य बातों के मैं कोशिश की है:

  • $update[SharpSvn.SvnUpdateResult][ref] के रूप में कास्टिंग - जो है, आदेश पीछे मैं इसे डाली कि। इसके परिणामस्वरूप एक त्रुटि होती है जो कहती है: "[ref] केवल प्रकार का रूपांतरण अनुक्रम में अंतिम प्रकार हो सकता है।"
  • $updateSharpSvn.SvnUpdateResult का उपयोग करने से पहले $update = [SharpSvn.SvnUpdateResult]$null कास्टिंग। इसके परिणामस्वरूप मैं "एकाधिक अस्पष्ट अधिभार" त्रुटि में
  • $updateref का उपयोग करने से पहले $update = [ref]$null कास्टिंग कर रहा था। इसका परिणाम एक त्रुटि में होता है: '"SharpSvn.SvnUpdateResult" टाइप करने के लिए "System.Management.Automation.PSReference" प्रकार का "System.Management.Automation.PSReference" मान को परिवर्तित नहीं किया जा सकता है।

ऐसा लगता है कि इसे दो बार कास्टिंग करना समस्या है - अंतिम कलाकार सिर्फ पहली कलाकार को ओवरराइड करता है, वे एक-दूसरे के पूरक नहीं होते हैं। क्या यह हो रहा है? क्या दो बार कुछ डालने का कोई तरीका है? क्या इस समस्या के आसपास एक और तरीका है?

किसी भी मदद के लिए अग्रिम धन्यवाद।

+0

मुझे पता चला है कि आप '$ svnclient.Update.OverloadedDefinitions' के साथ ओवरलोडेड परिभाषाओं की जांच कर सकते हैं, लेकिन वहां से उनसे कॉल करने का कोई तरीका नहीं है जो मैं देख सकता हूं। –

+0

पावरशेल के प्रकार रूपांतरण/सदस्य रिज़ॉल्यूशन आंतरिक कार्यों में कुछ अंतर्दृष्टि प्राप्त करने का एक तरीका है 'ट्रेस-कमांड -नाम ऑल-एक्सपेरेशन {$ svnclient.update ($ repopath, [ref] $ अपडेट)} -PSHost' और देखें कि क्या जो कुछ भी उपयोगी बताता है। –

+0

दुर्भाग्यवश, यह "एकाधिक अस्पष्ट अधिभार" संदेश देता है। –

उत्तर

0

यह एक आदर्श समाधान नहीं हो सकता है लेकिन आप एड-टाइप का उपयोग कर सकते हैं और एक अधिक PowerShell दोस्ताना प्रकार बना सकते हैं जो अद्यतन विधि को लपेटता है।

Add-Type -TypeDefinition " 
public class SvnClientEx 
{ 
    public static SvnUpdateResult Update(SvnClient client, string path) 
    { 
     SvnUpdateResult result; 
     client.Update(path, out result); 
     return result; 
    } 
} 
" 

$result = [SvnClient]::Update($svnClient, $repopath) 
+0

जिसके परिणामस्वरूप इस तरह की त्रुटि होती है: 'एड-टाइप: सी: \ उपयोगकर्ता \ ऑटोटेस्टर \ AppData \ Local \ Temp \ 89jqcyvc.0.cs (4): प्रकार या नामस्थान नाम' SvnClient 'नहीं मिला आप एक प्रयोग निर्देश या असेंबली संदर्भ खो रहे हैं?) '... मैंने परिभाषा के शीर्ष पर' SharpSvn का उपयोग करके 'जोड़ने का प्रयास किया है, लेकिन यह SharpSvn खोजने में सक्षम नहीं होने के बारे में एक समान त्रुटि देता है। मुझे यकीन है कि मुझे कुछ आसान याद आ रही है ... मैं आम तौर पर सी # से बहुत परिचित नहीं हूं या कैसे पावरहेल विशेष रूप से इसके साथ बातचीत करता है। मैं क्या गलत कर रहा हूं? (और सूचक के लिए धन्यवाद!) –

+0

ऐड-टाइप के संदर्भित एस्सेम्ब्ली पैरामीटर पर एक नज़र डालें। आपको उपरोक्त एड-टाइप कमांड में एसवीएन क्लाइंट असेंबली जोड़ने की आवश्यकता होगी। उसके लिए माफ़ करना! –

0

आप बस एक कोड ब्लॉक का उपयोग करें और इस खंड के भीतर परिणाम (बाहर) वस्तु का उपयोग कर सकते हैं:

PS> $repopath = "C:\path\to\localrepo" 
PS> $svnclient.update($repopath, { 
     Write-Host $_.Revision 
     Write-Host $_.HasRevision 
     # Access all the Member and Methods of the result object here 
    }) 
1

यह काफी सही पाने के लिए कठिन हो सकता है प्रतीत होता है।

पावरशेल का कौन सा संस्करण यह है? SvnUpdateArgs और SvnUpdateResult संबंधित हैं (यानी एक वर्ग दूसरे से निकला है)? मैं नहीं मानूंगा।

एक समान परिदृश्य मैं का निर्माण किया, PowerShell के वर्तमान संस्करण (4.0) के साथ के आधार पर, इस काम करता है, मुझे लगता है कि:

PS> $repopath = "C:\path\to\localrepo" 
PS> [SharpSvn.SvnUpdateResult]$update = $null 
PS> $svnclient.Update([string]$repopath, [ref]$update) 

हालांकि, मैं केवल इस भार के से एक के साथ काम करने के लिए मिल सकता है !? यह सुनिश्चित नहीं है कि यह संयोग से है, लेकिन यह ओवरलोड था जिसे पहले सूचीबद्ध किया गया था जब मैंने ओवरलोड परिभाषाओं को देखने के लिए $svnclient.Update कहा था।

पावरशेल के मेरे संस्करण में, यदि मैं [ref][SharpSvn.SvnUpdateResult]$update के रूप में दूसरा तर्क देता हूं, तो ओवरलोड को सही तरीके से हल किया जाता है, विधि बिना त्रुटि के चलती है, लेकिन "आउट" पैरामीटर को असाइन की गई वस्तु खो जाती है।

भले ही $repopath को [string]$repopath = "C:\path\to\localrepo" के रूप में टाइप-सुरक्षित रूप से घोषित किया गया हो, ऐसा लगता है कि हमें अभी भी [string]$repopath कहना होगा जब हम इसे (मूल्य के अनुसार) पास करेंगे।

0

योग्य कुछ बातें तुम कर सकते हो:

पहले, परिणाम $svnclient.update द्वारा लौटाए गए एक PSMethod है। PSMethod में Invoke विधि है। आप इसका उपयोग करने का प्रयास कर सकते हैं।

दूसरा, कि आप वास्तविक प्रतिबिंब इस्तेमाल कर सकते हैं काम नहीं करता है, तो:

# To get all methods: 
$svnclient.gettype().getmethods()  

# Then filter the results to get overload you need. 
# Use GetParameters to get parameters of an overloaded method 
# return by GetMethods 
# For example (using PS 3.0 features): 

$svnclient.gettype().getmethods()|? name -eq Update | 
% {write-host "***`n"';$_} | % GetParameters 

# Will list parameter sets for each overload of Update, each set separated by stars 

# Alternatively use getmethod with appropriate parameters  
# GetMethod (link below) can be used to select correct overload without the 
# filtering above. The next to the last overload of GetMethod at the link is the one to use 

# After obtaining correct overload, then call the Invoke method like this: 
$correctOverload.Invoke($svnclient, @($repopath, [ref] $SvnUpdateResult)) 

GetMethod Link

+0

@ माइक-आर-लेडबेटर या तो सी # सीएमडीएलट्स लिखना या यह प्रतिबिंब समाधान सबसे अच्छा विकल्प जैसा लगता है। मैं पावरशेल टीम के साथ अनुवर्ती हूं कि कॉल क्यों काम नहीं कर रहा है, लेकिन मुझे संदेह है कि फिक्स जल्द ही पावरशेल में होगा। मुझे उपर्युक्त समाधान में समस्याएं मिलीं (आमंत्रण वाक्यविन्यास गलत है।) यदि आप उपर्युक्त काम करने के लिए फिक्स में रूचि रखते हैं, तो जवाब दें। – TravisEz13

1

वहाँ एक विधि है कि आप एक बाहर पैरामीटर के साथ कहते हैं जब वहाँ PowerShell में एक मुद्दा हो रहा है एक वर्ग और एक समान हस्ताक्षर के साथ एक और अधिभार (कक्षा इस हस्ताक्षर में कोई वर्ग हो सकती है।)

मैंने इस समस्या के लिए एक सरल रेपो बनाया और filed an issue पावरशेल के लिए बनाया।

संबंधित मुद्दे

 संबंधित मुद्दे