अधिकांश लोग अब तक जानते हैं कि System.Reflection.Assembly.LoadWithPartialNameयह पदावनत है, लेकिन यह पता चला है कि Add-Type -AssemblyName Microsoft.VisualBasic इससे बेहतर व्यवहार नहीं हैLoadWithPartialName :
अपने सिस्टम के संदर्भ में आपके अनुरोध को पार्स करने का कोई प्रयास करने के बजाय, [ऐड-टाइप] "आंशिक नाम" को "पूर्ण नाम" में अनुवाद करने के लिए एक स्थिर, आंतरिक तालिका को देखता है।
यदि आपका "आंशिक नाम" उनकी तालिका में प्रकट नहीं होता है, तो आपकी स्क्रिप्ट विफल हो जाएगी।
यदि आपके पास अपने कंप्यूटर पर असेंबली के कई संस्करण स्थापित हैं, तो उनके बीच चयन करने के लिए कोई बुद्धिमान एल्गोरिथ्म नहीं है। आपको उनकी तालिका में जो भी दिखाई देने वाला है, संभवत: पुराना, पुराना है।
यदि आपके द्वारा इंस्टॉल किए गए संस्करण तालिका में अप्रचलित की तुलना में सभी नए हैं, तो आपकी स्क्रिप्ट विफल हो जाएगी।
ऐड-टाइप के पास "आंशिक नामों" की तरह कोई बुद्धिमान पार्सर नहीं है
.LoadWithPartialNames।
Microsoft क्या कहता है कि आप वास्तव में ऐसा करने वाले हैं:
Add-Type -AssemblyName 'Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
या, यदि आप रास्ता जानते हैं, तो कुछ इस तरह से:
Add-Type -Path 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualBasic\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualBasic.dll'
विधानसभा के लिए दिए गए लंबे नाम को मजबूत नाम के रूप में जाना जाता है , जो संस्करण और असेंबली दोनों के लिए अद्वितीय है, और कभी-कभी पूर्ण नाम के रूप में भी जाना जाता है।
लेकिन यह एक अनुत्तरित कुछ सवालों को छोड़ देता है:
मैं एक आंशिक रूप से दिए गए आंशिक नाम के साथ अपने सिस्टम पर वास्तव में लोड होने वाले मजबूत नाम का निर्धारण कैसे करूं?
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).Location;
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).FullName;
ये भी काम करना चाहिए:
Add-Type -AssemblyName $TypeName -PassThru | Select-Object -ExpandProperty Assembly | Select-Object -ExpandProperty FullName -Unique
अगर मैं चाहता हूं कि मेरी स्क्रिप्ट हमेशा एक .dll के एक विशिष्ट संस्करण का उपयोग करें, लेकिन मैं निश्चित नहीं हो सकता कि यह कहाँ स्थापित है, तो मैं कैसे निर्धारित करूं कि .dll से मजबूत नाम क्या है?
[System.Reflection.AssemblyName]::GetAssemblyName($Path).FullName;
या:
Add-Type $Path -PassThru | Select-Object -ExpandProperty Assembly | Select-Object -ExpandProperty FullName -Unique
यदि मैं मजबूत नाम जानता हूं, तो मैं .dll पथ कैसे निर्धारित करूं?
[Reflection.Assembly]::Load('Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a').Location;
और, एक समान नस पर, अगर मुझे पता है कि मैं जो उपयोग कर रहा हूं उसका प्रकार क्या है, मुझे कैसे पता चलेगा कि यह किस विधानसभा से आ रहा है?
[Reflection.Assembly]::GetAssembly([Type]).Location
[Reflection.Assembly]::GetAssembly([Type]).FullName
मैं कैसे देख सकता हूं कि विधानसभाएं उपलब्ध हैं?
मैं GAC पॉवरशेल मॉड्यूल का सुझाव देता हूं । Get-GacAssembly -Name 'Microsoft.SqlServer.Smo*' | Select Name, Version, FullNameबहुत अच्छा काम करता है।
- मैं उस सूची को कैसे देख सकता हूं जो
Add-Typeउपयोग करती है?
यह थोड़ा अधिक जटिल है। मैं यह वर्णन कर सकता हूं कि किसी .Net रिफ्लेक्टर के साथ पावरशेल के किसी भी संस्करण के लिए इसे कैसे एक्सेस किया जा सकता है (PowerShell Core 6.0 के लिए नीचे अपडेट देखें)।
सबसे पहले, यह पता लगाएं कि कौन सी लाइब्रेरी से Add-Typeआता है:
Get-Command -Name Add-Type | Select-Object -Property DLL
अपने परावर्तक के साथ परिणामी DLL खोलें। मैंने इसके लिए ILSpy का उपयोग किया है क्योंकि यह FLOSS है , लेकिन किसी भी C # रिफ्लेक्टर को काम करना चाहिए। उस लाइब्रेरी को खोलें, और अंदर देखें Microsoft.Powershell.Commands.Utility। के तहत Microsoft.Powershell.Commandsहोना चाहिए AddTypeCommand।
उसके लिए कोड सूची में, एक निजी वर्ग है, InitializeStrongNameDictionary() । यह उन शब्दकोश को सूचीबद्ध करता है जो संक्षिप्त नामों को मजबूत नामों में मैप करता है। मैंने जिस लाइब्रेरी को देखा है, उसमें लगभग 750 प्रविष्टियाँ हैं।
अद्यतन: अब जब कि PowerShell Core 6.0 खुला स्रोत है। उस संस्करण के लिए, आप उपरोक्त चरणों को छोड़ सकते हैं और कोड को सीधे उनके GitHub रिपॉजिटरी में ऑनलाइन देख सकते हैं । मैं इस बात की गारंटी नहीं दे सकता कि कोड PowerShell के किसी अन्य संस्करण से मेल खाता है, हालाँकि।