2011-09-26 12 views
9

मैं अपने सी # कोड से पावरशेल स्क्रिप्ट चलाने की कोशिश कर रहा हूं, जो उन्हें चलाने वाली असेंबली से कस्टम सीएमडीलेट का उपयोग करेगा।होस्टेड पावरशेल उसी विधानसभा में सीएमडीलेट्स नहीं देख सकता

using System; 
using System.Management.Automation; 

[Cmdlet(VerbsCommon.Get,"Hello")] 
public class GetHelloCommand:Cmdlet 
{ 
    protected override void EndProcessing() 
    { 
     WriteObject("Hello",true); 
    } 
} 

class MainClass 
{ 
    public static void Main(string[] args) 
    { 
     PowerShell powerShell=PowerShell.Create(); 
     powerShell.AddCommand("Get-Hello"); 
     foreach(string str in powerShell.AddCommand("Out-String").Invoke<string>()) 
      Console.WriteLine(str); 
    } 
} 

जब मैं इसे चलाने के लिए प्रयास करते हैं, मैं एक CommandNotFoundException मिल: यहाँ कोड है। क्या मैंने अपना सीएमडीलेट गलत लिखा था? क्या मेरे पास पावरशेल में या रनस्पेस या कुछ में मेरे सीएमडीलेट को पंजीकृत करने के लिए कुछ करने की ज़रूरत है?

उत्तर

9

अपने वर्तमान कोड स्निपेट के साथ ऐसा करने का सबसे आसान तरीका इस तरह है:

using System; 
using System.Management.Automation; 

[Cmdlet(VerbsCommon.Get,"Hello")] 
public class GetHelloCommand:Cmdlet 
{ 
    protected override void EndProcessing() 
    { 
     WriteObject("Hello",true); 
    } 
} 

class MainClass 
{ 
    public static void Main(string[] args) 
    { 
     PowerShell powerShell=PowerShell.Create(); 

     // import commands from the current executing assembly 
     powershell.AddCommand("Import-Module") 
      .AddParameter("Assembly", 
        System.Reflection.Assembly.GetExecutingAssembly()) 
     powershell.Invoke() 
     powershell.Commands.Clear() 

     powershell.AddCommand("Get-Hello"); 
     foreach(string str in powerShell.AddCommand("Out-String").Invoke<string>()) 
      Console.WriteLine(str); 
    } 
} 

यह PowerShell v2.0 मान लिया गया है (आप में जाँच कर सकते हैं $ psversiontable के साथ या कॉपीराइट तिथि के साथ आपका कंसोल 200 9 होना चाहिए।) यदि आप Win7 पर हैं, तो आप v2 पर हैं।

+0

एक आकर्षण की तरह काम करता है! धन्यवाद! –

1

पावरहेल सत्र में इसका उपयोग करने से पहले आपको अपने cmdlet को पंजीकृत करने की आवश्यकता है। आप आमतौर पर पावरहेल स्नैप-इन के माध्यम से ऐसा करेंगे। यहाँ इस प्रक्रिया का एक उच्च स्तरीय अवलोकन है:

  • कस्टम cmdlets बनाएं (आप पहले से ही इस हिस्से किया है)
  • बनाएं Powershell स्नैप में जो होता है और अपने cmdlets का वर्णन करता है एक
  • स्थापित नई स्नैप आपके सिस्टम Installutil
  • का उपयोग कर स्नैप में एक विशिष्ट PowerShell सत्र में जोड़े का उपयोग करने पर -इन Add-PSSnapin

है कि वें समझाने MSDN पर एक जोड़े को उपयोगी लेख हैं ई प्रक्रिया बहुत अच्छी तरह से:

वहाँ भी ByteBlocks चर्चा है कि कस्टम cmdlets लिखने पर एक 2 भागों की श्रृंखला है। यह श्रृंखला आपकी सबसे अच्छी शर्त हो सकती है, क्योंकि आपने पहले ही भाग 1 के बराबर किया है। आप त्वरित संदर्भ के रूप में केवल भाग 2 का उपयोग करने में सक्षम हो सकते हैं और जाने के लिए अच्छा हो सकते हैं।

+1

एक स्नैपइन चीजों को करने का पावरहेल v1 तरीका है और इन दिनों निराश है क्योंकि इसे पंजीकृत करने के लिए व्यवस्थापकीय विशेषाधिकारों की आवश्यकता होती है। वह powerhell v2 मॉड्यूल का उपयोग करना चाहिए। – x0n

+0

वास्तव में सवाल का जवाब नहीं देता कि वह क्या करने की कोशिश कर रहा है। – manojlds

+0

@manojlds यह सवाल का जवाब देता है, लेकिन निश्चित रूप से x0n के उत्तर के रूप में अद्यतित या सुरुचिपूर्ण नहीं है। – ajk

4

फिर भी एक और आसान तरीका एक रनस्पेस कॉन्फ़िगरेशन में cmdlets को पंजीकृत करना है, इस कॉन्फ़िगरेशन के साथ एक रनस्पेस बनाएं, और उस रनस्पेस का उपयोग करें।

using System; 
using System.Management.Automation; 
using System.Management.Automation.Runspaces; 

[Cmdlet(VerbsCommon.Get, "Hello")] 
public class GetHelloCommand : Cmdlet 
{ 
    protected override void EndProcessing() 
    { 
     WriteObject("Hello", true); 
    } 
} 

class MainClass 
{ 
    public static void Main(string[] args) 
    { 
     PowerShell powerShell = PowerShell.Create(); 
     var configuration = RunspaceConfiguration.Create(); 
     configuration.Cmdlets.Append(new CmdletConfigurationEntry[] { new CmdletConfigurationEntry("Get-Hello", typeof(GetHelloCommand), "") }); 
     powerShell.Runspace = RunspaceFactory.CreateRunspace(configuration); 
     powerShell.Runspace.Open(); 

     powerShell.AddCommand("Get-Hello"); 
     foreach (string str in powerShell.AddCommand("Out-String").Invoke<string>()) 
      Console.WriteLine(str); 
    } 
} 

बस इस मामले के साथ, cmdlet कक्षाओं को सार्वजनिक होने की आवश्यकता नहीं है।

+0

धन्यवाद।क्या PowerShell के अंदर से ऐसा करने का कोई तरीका है? यही है, [Reflection.Assembly] :: LoadFrom का उपयोग करके एक डीएलएल लोड करने के लिए, और फिर उस फ़ंक्शन को कॉल करें जो Cmdlets को PowerShell के वर्तमान सत्र में लोड करता है? –

+0

मैंने कोशिश नहीं की (सिर्फ इसलिए नहीं था)। PowerShell में आप डिफॉल्ट की कॉन्फ़िगरेशन तक पहुंच सकते हैं (अधिक या कम * वर्तमान * लेकिन यह निर्भर करता है) रनस्पेस के रूप में: '[System.Management.Automation.Runspaces.Runspace] :: DefaultRunspace.RunspaceConfiguration'। फिर उस पर '.Cmdlets.Append (...) 'कॉल करने का प्रयास करें। यह अच्छा होगा अगर आप इसे आजमाएं और हमें परिणाम बताएं। –

+0

मैं इसे काम नहीं कर सकता। ऐसा लगता है कि रनस्पेस सीएमडलेट्स को तब तक लोड नहीं करेगा जब तक कि यह पहले ओपन स्थिति में न हो। एक अल्रेय ओपन रनस्पेस के लिए सीएमडीलेट लोड करने का कोई तरीका? –

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