Powerhell में कीवर्ड का उपयोग करके C # के "के बराबर"?


80

जब मैं C # .net-Framework में C # में किसी अन्य ऑब्जेक्ट का उपयोग करता हूं तो मैं निर्देशन का उपयोग करके बहुत सारे टाइपिंग को बचा सकता हूं।

using FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It;

...


  var blurb = new Thingamabob();

...

तो क्या पावर्सहेल में एक तरीका है कुछ अनौपचारिक? मैं बहुत से .net ऑब्जेक्ट्स एक्सेस कर रहा हूं और टाइप करने से खुश नहीं हूं

 $blurb = new-object FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It.Thingamabob;

पुरे समय।


1
मुझे पता है कि यह एक पुराना सवाल है, लेकिन पावरशेल 5 ने usingबयान पेश किया । आप इसका उपयोग .net नामस्थान, या मॉड्यूल (जो कस्टम क्लासेस आयात करने के एकमात्र तरीकों में से एक है) के लिए कर सकते हैं। वाक्य-विन्यास using namespace Name.Space.Hereया है using module C:\Path\to\manifest। केवल आवश्यकता यह है कि यह आपकी स्क्रिप्ट में किसी भी अन्य बयान से पहले आता है (यहां तक ​​कि
पैराम

जवाबों:


43

PowerShell 5.0 (WMF5 या विंडोज 10 और ऊपर शामिल), using namespaceभाषा में निर्माण जोड़ता है । आप इसे अपनी स्क्रिप्ट में उपयोग कर सकते हैं जैसे:

#Require -Version 5.0
using namespace FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It
$blurb = [Thingamabob]::new()

( #Requireपहली पंक्ति का कथन उपयोग करने के लिए आवश्यक नहीं है using namespace, लेकिन यह स्क्रिप्ट को PS 4.0 में चलाने से रोकता है और नीचे using namespaceएक वाक्यविन्यास त्रुटि है।)


1
उस # कथन को जानने के लिए एक उपयोगी बात है, धन्यवाद।
साइमन टेवेसी

यह सामान्य स्क्रिप्ट में काम करता है, लेकिन इनलाइन स्क्रिप्ट के साथ Azure DevOps PowerShell कार्य कहता है कि उपयोग करना पहला कथन नहीं है।
एंड्री

57

वास्तव में नाम स्थान स्तर पर ऐसा कुछ नहीं है। मैं अक्सर चर के लिए आमतौर पर इस्तेमाल किए जाने वाले प्रकारों को असाइन करता हूं और फिर उन्हें त्वरित करता हूं:

$thingtype = [FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It.Thingamabob];
$blurb = New-Object $thingtype.FullName

यदि बार-बार उपयोग नहीं किया जाएगा, तो संभवतः इसके लायक नहीं है, लेकिन मेरा मानना ​​है कि यह सबसे अच्छा है जो आप कर सकते हैं।


मुझे कभी-कभी SecureStrings को सादे पाठ में बदलने की आवश्यकता है। निम्नलिखित उपयोगी है: $ns = [System.Runtime.InteropServices.Marshal]तो आप कर सकते हैं $ns::PtrToStringAuto($ns::SecureStringToBSTR($ss))
पेट्संड

1
शीर्ष रेटेड उत्तर को देखने वालों को ध्यान दें: PowerShell 5.0 इसे ठीक करता है।
डेव मार्केल

@petrsnd या उपयोग([pscredential]::new('+',$ss)).GetNetworkCredential().Password
निकोलस मेले

12

इस ब्लॉग पोस्ट को कुछ साल पहले देखें: http://blogs.msdn.com/richardb/archive/2007/02/21/add-types-ps1-poor-man-s-use-for-powershell.aspx

यहाँ add-types.ps1उस लेख का अंश दिया गया है:

param(
    [string] $assemblyName = $(throw 'assemblyName is required'),
    [object] $object
)

process {
    if ($_) {
        $object = $_
    }

    if (! $object) {
        throw 'must pass an -object parameter or pipe one in'
    }

    # load the required dll
    $assembly = [System.Reflection.Assembly]::LoadWithPartialName($assemblyName)

    # add each type as a member property
    $assembly.GetTypes() | 
    where {$_.ispublic -and !$_.IsSubclassOf( [Exception] ) -and $_.name -notmatch "event"} | 
    foreach { 
        # avoid error messages in case it already exists
        if (! ($object | get-member $_.name)) {
            add-member noteproperty $_.name $_ -inputobject $object
        }
    }
}

और, इसका उपयोग करने के लिए:

RICBERG470> $tfs | add-types "Microsoft.TeamFoundation.VersionControl.Client"
RICBERG470> $itemSpec = new-object $tfs.itemspec("$/foo", $tfs.RecursionType::none)

मूल रूप से मैं जो भी करता हूं वह असेंबली प्रकार के लिए असेंबली क्रॉल करता है, फिर एक "कंस्ट्रक्टर" लिखें जो ऐड-मेंबर का उपयोग करता है उन्हें (एक संरचित तरीके से) उन वस्तुओं पर जो मैं परवाह करता हूं।

इस अनुवर्ती पोस्ट को भी देखें: http://richardberg.net/blog/?p=38


ऐसा लगता है कि किसी को एक प्रकार के नाम (जैसे System.IO.Path) के बजाय विधानसभा नाम (जैसे mscorlib) का उपयोग करने की आवश्यकता है।
मीका विडेनमैन

यदि आपके पास फ़ंक्शन को पास करने के लिए कोई ऑब्जेक्ट नहीं है, तो आप एक का उपयोग करके बना सकते हैं New-Object PSObject
मीका विडेनमैन

7

यह सिर्फ एक मजाक है, मजाक है ...

$fullnames = New-Object ( [System.Collections.Generic.List``1].MakeGenericType( [String]) );

function using ( $name ) { 
foreach ( $type in [Reflection.Assembly]::LoadWithPartialName($name).GetTypes() )
    {
        $fullnames.Add($type.fullname);
    }
}

function new ( $name ) {
    $fullname = $fullnames -like "*.$name";
    return , (New-Object $fullname[0]);
}

using System.Windows.Forms
using FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It
$a = new button
$b = new Thingamabob

क्या कोई कृपया इस प्रकार में डबल `` 1 की व्याख्या कर सकता है, मुझे खोज करने में मुश्किल हो रही है।
पीट

यह कथन का उपयोग करते हुए C # के बराबर होगा, न कि निर्देश का उपयोग करते हुए।
पाउलो मोरागडो 10

मुझे यह जिस तरह दिखता है वह मुझे पसंद है। यदि आप इसके लिए प्रतिबद्ध थे, तो यह मेरे लिए एक बहुत ही सुंदर समाधान की तरह लगता है। एक नए वाक्यविन्यास को तैयार करने में पावरशेल का लचीलापन मुझे बहुत खुश करता है।
प्रोग्रामर पॉल

@ProgrammerPaul यदि आप पाते हैं कि मनोरंजक है, तो एक कार्यात्मक भाषा आज़माएं - उनमें से कुछ लाइब्रेरी केtry..catch रूप में लागू होती हैं , जिसमें हास्केल और IIRC क्लोजर शामिल हैं।
jpaugh

@ProgrammerPaul (wrt। फंक्शनल लैंग्वेजेज) lol, बस इसे पढ़ते समय F # lib (FParsec के माध्यम से DSL पार्सर) लपेटते हुए। मुझे पता है / हास्केल, क्लोजर, स्काला की तरह, और फिर भी टिप्पणी नहीं कर सकता। यहाँ यह आता है: शायद कुछ सही मायने में ऑब्जेक्ट ओरिएंटेड लैंग्वेज की कोशिश करें, जैसे कि स्मॉलटाक - यह इम्प्लीमेंट इफ / एल्स ए लाइब्रेरी (;-)))
मिलोसलव रोस

5

यहाँ कुछ कोड हैं जो टाइप उपनाम जोड़ने के लिए PowerShell 2.0 में काम करता है। लेकिन समस्या यह है कि यह स्कूप नहीं है। कुछ अतिरिक्त काम के साथ आप नामस्थानों को "अन-इम्पोर्ट" कर सकते हैं, लेकिन इससे आपको एक अच्छी शुरुआत मिलनी चाहिए।

##############################################################################
#.SYNOPSIS
# Add a type accelerator to the current session.
#
#.DESCRIPTION
# The Add-TypeAccelerator function allows you to add a simple type accelerator
# (like [regex]) for a longer type (like [System.Text.RegularExpressions.Regex]).
#
#.PARAMETER Name
# The short form accelerator should be just the name you want to use (without
# square brackets).
#
#.PARAMETER Type
# The type you want the accelerator to accelerate.
#
#.PARAMETER Force
# Overwrites any existing type alias.
#
#.EXAMPLE
# Add-TypeAccelerator List "System.Collections.Generic.List``1"
# $MyList = New-Object List[String]
##############################################################################
function Add-TypeAccelerator {

    [CmdletBinding()]
    param(

        [Parameter(Position=1,Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
        [String[]]$Name,

        [Parameter(Position=2,Mandatory=$true,ValueFromPipeline=$true)]
        [Type]$Type,

        [Parameter()]
        [Switch]$Force

    )

    process {

        $TypeAccelerators = [Type]::GetType('System.Management.Automation.TypeAccelerators')

        foreach ($a in $Name) {
            if ( $TypeAccelerators::Get.ContainsKey($a) ) {
                if ( $Force ) {
                    $TypeAccelerators::Remove($a) | Out-Null
                    $TypeAccelerators::Add($a,$Type)
                }
                elseif ( $Type -ne $TypeAccelerators::Get[$a] ) {
                    Write-Error "$a is already mapped to $($TypeAccelerators::Get[$a])"
                }
            }
            else {
                $TypeAccelerators::Add($a, $Type)
            }
        }

    }

}

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

यह आसान है लेकिन सावधानी के साथ इसका उपयोग करें। स्क्रिप्ट लिखने से बुरा कुछ नहीं जो किसी और की मशीन पर काम न करे। इस कारण से मैंने कभी भी अपने प्रोफाइल में इन एक्सीलेटर को नहीं रखा। यदि कुछ भी हो, तो मैं उन्हें एक स्क्रिप्ट के शीर्ष पर रखूँगा, जिस तरह से वह Add-TypeAccelerator पर तुरंत विफल हो जाएगा।
जोश

5

यदि आपको अपने प्रकार का उदाहरण बनाने की आवश्यकता है, तो आप लंबे नाम स्थान का नाम स्ट्रिंग में संग्रहीत कर सकते हैं:

$st = "System.Text"
$sb = New-Object "$st.StringBuilder"

यह usingसी # में निर्देश जितना शक्तिशाली नहीं है, लेकिन कम से कम इसका उपयोग करना बहुत आसान है।


2

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

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

मुझे लगता है कि एक प्रकार के लिए विधानसभाओं के पूर्वनिर्धारित मार्ग के माध्यम से खोज करने के लिए इसे भी बाहर करने का कोई कारण नहीं है।

अस्वीकरण: मैंने अभी तक इसका निर्माण नहीं किया है ...

यहां बताया गया है कि कोई इसका उपयोग कैसे कर सकता है:

$path = (System.Collections.Generic, FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It)

$type = get-type -Path $path List Thingamabob
$obj = new-object $type
$obj.GetType()

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



-2

मुझे लगता है कि यह एक पुरानी पोस्ट है, लेकिन मैं एक ही चीज की तलाश में था और इस पर आया: http://weblogs.asp.net/adweigert/powershell-adding-the-use-statement

संपादित करें: मुझे लगता है कि मुझे यह निर्दिष्ट करना चाहिए कि यह आपको परिचित वाक्यविन्यास का उपयोग करने की अनुमति देता है ...

using ($x = $y) { ... }

1
यह कथन का उपयोग करते हुए C # के बराबर होगा, न कि निर्देश का उपयोग करते हुए।
पाउलो मोरागडो 10
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.